Allow .env and .overrides in presets.

This commit is contained in:
Logan Smyth 2017-12-22 13:19:29 -08:00
parent 1ded1d7ff6
commit 193e841d89
2 changed files with 54 additions and 36 deletions

View File

@ -40,7 +40,7 @@ export type PresetInstance = {
dirname: string, dirname: string,
}; };
type ConfigContext = { export type ConfigContext = {
filename: string | null, filename: string | null,
cwd: string, cwd: string,
envName: string, envName: string,
@ -54,16 +54,26 @@ type ConfigContextNamed = {
/** /**
* Build a config chain for a given preset. * Build a config chain for a given preset.
*/ */
export const buildPresetChain = makeWeakCache( export const buildPresetChain: (
({ dirname, options, alias }: PresetInstance): ConfigChain => { arg: PresetInstance,
const result = createUncachedDescriptors(dirname, options, alias); context: *,
const { plugins, presets } = result; ) => * = makeChainWalker({
return { init: arg => arg,
plugins: plugins(), root: preset => loadPresetDescriptors(preset),
presets: presets(), env: (preset, envName) => loadPresetEnvDescriptors(preset)(envName),
options: [normalizeOptions(result.options)], });
}; const loadPresetDescriptors = makeWeakCache((preset: PresetInstance) =>
}, buildRootDescriptors(preset, preset.alias, createUncachedDescriptors),
);
const loadPresetEnvDescriptors = makeWeakCache((preset: PresetInstance) =>
makeStrongCache((envName: string) =>
buildEnvDescriptors(
preset,
preset.alias,
createUncachedDescriptors,
envName,
),
),
); );
/** /**
@ -72,14 +82,8 @@ export const buildPresetChain = makeWeakCache(
export function buildRootChain( export function buildRootChain(
cwd: string, cwd: string,
opts: ValidatedOptions, opts: ValidatedOptions,
envName: string, context: ConfigContext,
): ConfigChain | null { ): ConfigChain | null {
const context = {
filename: opts.filename ? path.resolve(cwd, opts.filename) : null,
cwd,
envName,
};
const programmaticChain = loadProgrammaticChain( const programmaticChain = loadProgrammaticChain(
{ {
options: opts, options: opts,

View File

@ -7,6 +7,7 @@ import merge from "lodash/merge";
import { import {
buildRootChain, buildRootChain,
buildPresetChain, buildPresetChain,
type ConfigContext,
type ConfigChain, type ConfigChain,
type PresetInstance, type PresetInstance,
} from "./config-chain"; } from "./config-chain";
@ -36,6 +37,12 @@ export type { Plugin };
export type PluginPassList = Array<Plugin>; export type PluginPassList = Array<Plugin>;
export type PluginPasses = Array<PluginPassList>; export type PluginPasses = Array<PluginPassList>;
// Context not including filename since it is used in places that cannot
// process 'ignore'/'only' and other filename-based logic.
type SimpleContext = {
envName: string,
};
export default function loadConfig(inputOpts: mixed): ResolvedConfig | null { export default function loadConfig(inputOpts: mixed): ResolvedConfig | null {
if ( if (
inputOpts != null && inputOpts != null &&
@ -49,27 +56,32 @@ export default function loadConfig(inputOpts: mixed): ResolvedConfig | null {
const { envName = getEnv(), cwd = "." } = args; const { envName = getEnv(), cwd = "." } = args;
const absoluteCwd = path.resolve(cwd); const absoluteCwd = path.resolve(cwd);
const configChain = buildRootChain(absoluteCwd, args, envName); const context: ConfigContext = {
filename: args.filename ? path.resolve(cwd, args.filename) : null,
cwd: absoluteCwd,
envName,
};
const configChain = buildRootChain(absoluteCwd, args, context);
if (!configChain) return null; if (!configChain) return null;
const optionDefaults = {}; const optionDefaults = {};
const options = {}; const options = {};
const passes = [[]]; const passes = [[]];
try { try {
(function recurseDescriptors( const ignored = (function recurseDescriptors(
config: { config: {
plugins: Array<UnloadedDescriptor>, plugins: Array<UnloadedDescriptor>,
presets: Array<UnloadedDescriptor>, presets: Array<UnloadedDescriptor>,
}, },
pass: Array<Plugin>, pass: Array<Plugin>,
envName: string,
) { ) {
const plugins = config.plugins.map(descriptor => const plugins = config.plugins.map(descriptor =>
loadPluginDescriptor(descriptor, envName), loadPluginDescriptor(descriptor, context),
); );
const presets = config.presets.map(descriptor => { const presets = config.presets.map(descriptor => {
return { return {
preset: loadPresetDescriptor(descriptor, envName), preset: loadPresetDescriptor(descriptor, context),
pass: descriptor.ownPass ? [] : pass, pass: descriptor.ownPass ? [] : pass,
}; };
}); });
@ -85,14 +97,16 @@ export default function loadConfig(inputOpts: mixed): ResolvedConfig | null {
); );
for (const { preset, pass } of presets) { for (const { preset, pass } of presets) {
recurseDescriptors( if (!preset) return true;
const ignored = recurseDescriptors(
{ {
plugins: preset.plugins, plugins: preset.plugins,
presets: preset.presets, presets: preset.presets,
}, },
pass, pass,
envName,
); );
if (ignored) return true;
preset.options.forEach(opts => { preset.options.forEach(opts => {
merge(optionDefaults, opts); merge(optionDefaults, opts);
@ -110,9 +124,10 @@ export default function loadConfig(inputOpts: mixed): ResolvedConfig | null {
presets: configChain.presets, presets: configChain.presets,
}, },
passes[0], passes[0],
envName,
); );
if (ignored) return null;
configChain.options.forEach(opts => { configChain.options.forEach(opts => {
merge(options, opts); merge(options, opts);
}); });
@ -152,7 +167,7 @@ export default function loadConfig(inputOpts: mixed): ResolvedConfig | null {
const loadDescriptor = makeWeakCache( const loadDescriptor = makeWeakCache(
( (
{ value, options, dirname, alias }: UnloadedDescriptor, { value, options, dirname, alias }: UnloadedDescriptor,
cache: CacheConfigurator<{ envName: string }>, cache: CacheConfigurator<SimpleContext>,
): LoadedDescriptor => { ): LoadedDescriptor => {
// Disabled presets should already have been filtered out // Disabled presets should already have been filtered out
if (options === false) throw new Error("Assertion failure"); if (options === false) throw new Error("Assertion failure");
@ -199,7 +214,7 @@ const loadDescriptor = makeWeakCache(
*/ */
function loadPluginDescriptor( function loadPluginDescriptor(
descriptor: UnloadedDescriptor, descriptor: UnloadedDescriptor,
envName: string, context: SimpleContext,
): Plugin { ): Plugin {
if (descriptor.value instanceof Plugin) { if (descriptor.value instanceof Plugin) {
if (descriptor.options) { if (descriptor.options) {
@ -211,15 +226,13 @@ function loadPluginDescriptor(
return descriptor.value; return descriptor.value;
} }
return instantiatePlugin(loadDescriptor(descriptor, { envName }), { return instantiatePlugin(loadDescriptor(descriptor, context), context);
envName,
});
} }
const instantiatePlugin = makeWeakCache( const instantiatePlugin = makeWeakCache(
( (
{ value, options, dirname, alias }: LoadedDescriptor, { value, options, dirname, alias }: LoadedDescriptor,
cache: CacheConfigurator<{ envName: string }>, cache: CacheConfigurator<SimpleContext>,
): Plugin => { ): Plugin => {
const pluginObj = validatePluginObject(value); const pluginObj = validatePluginObject(value);
@ -239,7 +252,7 @@ const instantiatePlugin = makeWeakCache(
// If the inherited plugin changes, reinstantiate this plugin. // If the inherited plugin changes, reinstantiate this plugin.
const inherits = cache.invalidate(data => const inherits = cache.invalidate(data =>
loadPluginDescriptor(inheritsDescriptor, data.envName), loadPluginDescriptor(inheritsDescriptor, data),
); );
plugin.pre = chain(inherits.pre, plugin.pre); plugin.pre = chain(inherits.pre, plugin.pre);
@ -263,10 +276,11 @@ const instantiatePlugin = makeWeakCache(
*/ */
const loadPresetDescriptor = ( const loadPresetDescriptor = (
descriptor: UnloadedDescriptor, descriptor: UnloadedDescriptor,
envName: string, context: ConfigContext,
): ConfigChain => { ): ConfigChain | null => {
return buildPresetChain( return buildPresetChain(
instantiatePreset(loadDescriptor(descriptor, { envName })), instantiatePreset(loadDescriptor(descriptor, context)),
context,
); );
}; };