Return a list of files that were read from loadPartialConfig (#11907)

This commit is contained in:
Devon Govett 2020-10-09 07:32:00 -07:00 committed by Nicolò Ribaudo
parent a5bed04f55
commit ce7b170ab7
6 changed files with 141 additions and 16 deletions

View File

@ -40,6 +40,7 @@ export type ConfigChain = {
plugins: Array<UnloadedDescriptor>, plugins: Array<UnloadedDescriptor>,
presets: Array<UnloadedDescriptor>, presets: Array<UnloadedDescriptor>,
options: Array<ValidatedOptions>, options: Array<ValidatedOptions>,
files: Set<string>,
}; };
export type PresetInstance = { export type PresetInstance = {
@ -71,6 +72,7 @@ export function* buildPresetChain(
plugins: dedupDescriptors(chain.plugins), plugins: dedupDescriptors(chain.plugins),
presets: dedupDescriptors(chain.presets), presets: dedupDescriptors(chain.presets),
options: chain.options.map(o => normalizeOptions(o)), options: chain.options.map(o => normalizeOptions(o)),
files: new Set(),
}; };
} }
@ -124,10 +126,13 @@ const loadPresetOverridesEnvDescriptors = makeWeakCacheSync(
), ),
); );
export type FileHandling = "transpile" | "ignored" | "unsupported";
export type RootConfigChain = ConfigChain & { export type RootConfigChain = ConfigChain & {
babelrc: ConfigFile | void, babelrc: ConfigFile | void,
config: ConfigFile | void, config: ConfigFile | void,
ignore: IgnoreFile | void, ignore: IgnoreFile | void,
fileHandling: FileHandling,
files: Set<string>,
}; };
/** /**
@ -202,6 +207,7 @@ export function* buildRootChain(
: null; : null;
let ignoreFile, babelrcFile; let ignoreFile, babelrcFile;
let isIgnored = false;
const fileChain = emptyChain(); const fileChain = emptyChain();
// resolve all .babelrc files // resolve all .babelrc files
if ( if (
@ -215,14 +221,18 @@ export function* buildRootChain(
context.caller, context.caller,
)); ));
if (ignoreFile) {
fileChain.files.add(ignoreFile.filepath);
}
if ( if (
ignoreFile && ignoreFile &&
shouldIgnore(context, ignoreFile.ignore, null, ignoreFile.dirname) shouldIgnore(context, ignoreFile.ignore, null, ignoreFile.dirname)
) { ) {
return null; isIgnored = true;
} }
if (babelrcFile) { if (babelrcFile && !isIgnored) {
const validatedFile = validateBabelrcFile(babelrcFile); const validatedFile = validateBabelrcFile(babelrcFile);
const babelrcLogger = new ConfigPrinter(); const babelrcLogger = new ConfigPrinter();
const result = yield* loadFileChain( const result = yield* loadFileChain(
@ -231,13 +241,19 @@ export function* buildRootChain(
undefined, undefined,
babelrcLogger, babelrcLogger,
); );
if (!result) return null; if (!result) {
isIgnored = true;
} else {
babelRcReport = babelrcLogger.output(); babelRcReport = babelrcLogger.output();
mergeChain(fileChain, result); mergeChain(fileChain, result);
} }
} }
if (babelrcFile && isIgnored) {
fileChain.files.add(babelrcFile.filepath);
}
}
if (context.showConfig) { if (context.showConfig) {
console.log( console.log(
// $FlowIgnore: context.showConfig implies context.filename is not null // $FlowIgnore: context.showConfig implies context.filename is not null
@ -257,12 +273,14 @@ export function* buildRootChain(
); );
return { return {
plugins: dedupDescriptors(chain.plugins), plugins: isIgnored ? [] : dedupDescriptors(chain.plugins),
presets: dedupDescriptors(chain.presets), presets: isIgnored ? [] : dedupDescriptors(chain.presets),
options: chain.options.map(o => normalizeOptions(o)), options: isIgnored ? [] : chain.options.map(o => normalizeOptions(o)),
fileHandling: isIgnored ? "ignored" : "transpile",
ignore: ignoreFile || undefined, ignore: ignoreFile || undefined,
babelrc: babelrcFile || undefined, babelrc: babelrcFile || undefined,
config: configFile || undefined, config: configFile || undefined,
files: chain.files,
}; };
} }
@ -355,7 +373,7 @@ const loadProgrammaticChain = makeChainWalker({
/** /**
* Build a config chain for a given file. * Build a config chain for a given file.
*/ */
const loadFileChain = makeChainWalker({ const loadFileChainWalker = makeChainWalker({
root: file => loadFileDescriptors(file), root: file => loadFileDescriptors(file),
env: (file, envName) => loadFileEnvDescriptors(file)(envName), env: (file, envName) => loadFileEnvDescriptors(file)(envName),
overrides: (file, index) => loadFileOverridesDescriptors(file)(index), overrides: (file, index) => loadFileOverridesDescriptors(file)(index),
@ -364,6 +382,16 @@ const loadFileChain = makeChainWalker({
createLogger: (file, context, baseLogger) => createLogger: (file, context, baseLogger) =>
buildFileLogger(file.filepath, context, baseLogger), buildFileLogger(file.filepath, context, baseLogger),
}); });
function* loadFileChain(input, context, files, baseLogger) {
const chain = yield* loadFileChainWalker(input, context, files, baseLogger);
if (chain) {
chain.files.add(input.filepath);
}
return chain;
}
const loadFileDescriptors = makeWeakCacheSync((file: ValidatedFile) => const loadFileDescriptors = makeWeakCacheSync((file: ValidatedFile) =>
buildRootDescriptors(file, file.filepath, createUncachedDescriptors), buildRootDescriptors(file, file.filepath, createUncachedDescriptors),
); );
@ -622,6 +650,9 @@ function mergeChain(target: ConfigChain, source: ConfigChain): ConfigChain {
target.options.push(...source.options); target.options.push(...source.options);
target.plugins.push(...source.plugins); target.plugins.push(...source.plugins);
target.presets.push(...source.presets); target.presets.push(...source.presets);
for (const file of source.files) {
target.files.add(file);
}
return target; return target;
} }
@ -642,6 +673,7 @@ function emptyChain(): ConfigChain {
options: [], options: [],
presets: [], presets: [],
plugins: [], plugins: [],
files: new Set(),
}; };
} }

View File

@ -63,7 +63,11 @@ export default gensync<[any], ResolvedConfig | null>(function* loadFullConfig(
if (!result) { if (!result) {
return null; return null;
} }
const { options, context } = result; const { options, context, fileHandling } = result;
if (fileHandling === "ignored") {
return null;
}
const optionDefaults = {}; const optionDefaults = {};
const passes: Array<Array<Plugin>> = [[]]; const passes: Array<Array<Plugin>> = [[]];

View File

@ -5,7 +5,11 @@ import gensync, { type Handler } from "gensync";
import Plugin from "./plugin"; import Plugin from "./plugin";
import { mergeOptions } from "./util"; import { mergeOptions } from "./util";
import { createItemFromDescriptor } from "./item"; import { createItemFromDescriptor } from "./item";
import { buildRootChain, type ConfigContext } from "./config-chain"; import {
buildRootChain,
type ConfigContext,
type FileHandling,
} from "./config-chain";
import { getEnv } from "./helpers/environment"; import { getEnv } from "./helpers/environment";
import { import {
validate, validate,
@ -59,9 +63,11 @@ function* resolveRootMode(
type PrivPartialConfig = { type PrivPartialConfig = {
options: ValidatedOptions, options: ValidatedOptions,
context: ConfigContext, context: ConfigContext,
fileHandling: FileHandling,
ignore: IgnoreFile | void, ignore: IgnoreFile | void,
babelrc: ConfigFile | void, babelrc: ConfigFile | void,
config: ConfigFile | void, config: ConfigFile | void,
files: Set<string>,
}; };
export default function* loadPrivatePartialConfig( export default function* loadPrivatePartialConfig(
@ -137,20 +143,30 @@ export default function* loadPrivatePartialConfig(
return { return {
options, options,
context, context,
fileHandling: configChain.fileHandling,
ignore: configChain.ignore, ignore: configChain.ignore,
babelrc: configChain.babelrc, babelrc: configChain.babelrc,
config: configChain.config, config: configChain.config,
files: configChain.files,
}; };
} }
type LoadPartialConfigOpts = {
showIgnoredFiles?: boolean,
...
};
export const loadPartialConfig = gensync<[any], PartialConfig | null>( export const loadPartialConfig = gensync<[any], PartialConfig | null>(
function* (inputOpts: mixed): Handler<PartialConfig | null> { function* (inputOpts: LoadPartialConfigOpts): Handler<PartialConfig | null> {
const result: ?PrivPartialConfig = yield* loadPrivatePartialConfig( const { showIgnoredFiles, ...opts } = inputOpts;
inputOpts, const result: ?PrivPartialConfig = yield* loadPrivatePartialConfig(opts);
);
if (!result) return null; if (!result) return null;
const { options, babelrc, ignore, config } = result; const { options, babelrc, ignore, config, fileHandling, files } = result;
if (fileHandling === "ignored" && !showIgnoredFiles) {
return null;
}
(options.plugins || []).forEach(item => { (options.plugins || []).forEach(item => {
if (item.value instanceof Plugin) { if (item.value instanceof Plugin) {
@ -166,6 +182,8 @@ export const loadPartialConfig = gensync<[any], PartialConfig | null>(
babelrc ? babelrc.filepath : undefined, babelrc ? babelrc.filepath : undefined,
ignore ? ignore.filepath : undefined, ignore ? ignore.filepath : undefined,
config ? config.filepath : undefined, config ? config.filepath : undefined,
fileHandling,
files,
); );
}, },
); );
@ -181,17 +199,23 @@ class PartialConfig {
babelrc: string | void; babelrc: string | void;
babelignore: string | void; babelignore: string | void;
config: string | void; config: string | void;
fileHandling: FileHandling;
files: Set<string>;
constructor( constructor(
options: ValidatedOptions, options: ValidatedOptions,
babelrc: string | void, babelrc: string | void,
ignore: string | void, ignore: string | void,
config: string | void, config: string | void,
fileHandling: FileHandling,
files: Set<string>,
) { ) {
this.options = options; this.options = options;
this.babelignore = ignore; this.babelignore = ignore;
this.babelrc = babelrc; this.babelrc = babelrc;
this.config = config; this.config = config;
this.fileHandling = fileHandling;
this.files = files;
// Freeze since this is a public API and it should be extremely obvious that // Freeze since this is a public API and it should be extremely obvious that
// reassigning properties on here does nothing. // reassigning properties on here does nothing.

View File

@ -1271,6 +1271,65 @@ describe("buildConfigChain", function () {
loadOptionsAsync({ filename, cwd: path.dirname(filename) }), loadOptionsAsync({ filename, cwd: path.dirname(filename) }),
).rejects.toThrow(error); ).rejects.toThrow(error);
}); });
it("loadPartialConfig should return a list of files that were extended", () => {
const filename = fixture("config-files", "babelrc-extended", "src.js");
expect(
babel.loadPartialConfig({ filename, cwd: path.dirname(filename) }),
).toEqual({
babelignore: fixture("config-files", ".babelignore"),
babelrc: fixture("config-files", "babelrc-extended", ".babelrc"),
config: undefined,
fileHandling: "transpile",
options: {
...getDefaults(),
filename: filename,
cwd: path.dirname(filename),
root: path.dirname(filename),
comments: true,
},
files: new Set([
fixture("config-files", ".babelignore"),
fixture("config-files", "babelrc-extended", ".babelrc-extended"),
fixture("config-files", "babelrc-extended", ".babelrc"),
]),
});
});
it("loadPartialConfig should return null when ignored", () => {
const filename = fixture("config-files", "babelignore", "src.js");
expect(
babel.loadPartialConfig({ filename, cwd: path.dirname(filename) }),
).toBeNull();
});
it("loadPartialConfig should return a list of files when ignored with showIgnoredFiles option", () => {
const filename = fixture("config-files", "babelignore", "src.js");
expect(
babel.loadPartialConfig({
filename,
cwd: path.dirname(filename),
showIgnoredFiles: true,
}),
).toEqual({
babelignore: fixture("config-files", "babelignore", ".babelignore"),
babelrc: undefined,
config: undefined,
fileHandling: "ignored",
options: {
...getDefaults(),
filename: filename,
cwd: path.dirname(filename),
root: path.dirname(filename),
},
files: new Set([
fixture("config-files", "babelignore", ".babelignore"),
]),
});
});
}); });
it("should throw when `test` presents but `filename` is not passed", () => { it("should throw when `test` presents but `filename` is not passed", () => {

View File

@ -0,0 +1,3 @@
{
"extends": "./.babelrc-extended"
}

View File

@ -0,0 +1,3 @@
{
"comments": true
}