Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple --preset-path with --presets #70

Merged
merged 2 commits into from
Sep 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/gasket-cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# `@gasket/cli`

- Support multiple --preset-path with --presets
- Always execute `configure` lifecycle for GasketCommands ([#71])
- Use Loader for presets during create ([#66])
- Presets can export createContext from module
Expand Down
10 changes: 6 additions & 4 deletions packages/gasket-cli/src/commands/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,12 @@ comma-separated values: --npm-link=@gasket/jest-plugin,some-test-preset`,
parse: commasToArray
}),
'preset-path': flags.string({
description: `(INTERNAL) Path the a local preset package. Can be absolute
or relative to the current working directory.`,
multiple: false,
hidden: true
description: `(INTERNAL) Paths the a local preset packages. Can be absolute
or relative to the current working directory.
comma-separated values: --preset-path=path1,path2`,
multiple: true,
hidden: true,
parse: commasToArray
}),
'npmconfig': GasketCommand.flags.npmconfig
};
Expand Down
23 changes: 15 additions & 8 deletions packages/gasket-cli/src/scaffold/actions/load-preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const loader = new Loader();
*/
async function remotePresets(context) {
const { cwd, npmconfig, rawPresets = [] } = context;
if (!rawPresets) { return []; }

return await Promise.all(rawPresets.map(async rawName => {
const packageName = presetIdentifier(rawName).full;
const fetcher = new PackageFetcher({ cwd, npmconfig, packageName });
Expand All @@ -30,12 +32,18 @@ async function remotePresets(context) {
* @private
*/
function localPreset(context) {
const { cwd, presetPath } = context;
const pkgPath = path.resolve(cwd, presetPath);
const presetInfo = loader.loadPreset(pkgPath, { from: 'cli' }, { shallow: true });
presetInfo.rawName = `${presetInfo.package.name}@file:${pkgPath}`;
const { cwd, localPresets = [] } = context;
if (!localPresets) { return []; }

const presetInfos = [];
localPresets.forEach(localPresetPath => {
const pkgPath = path.resolve(cwd, localPresetPath);
const presetInfo = loader.loadPreset(pkgPath, { from: 'cli' }, { shallow: true });
presetInfo.rawName = `${presetInfo.package.name}@file:${pkgPath}`;
presetInfos.push(presetInfo);
});

return [presetInfo];
return presetInfos;
}

/**
Expand All @@ -46,11 +54,10 @@ function localPreset(context) {
* @returns {Promise} promise
*/
async function loadPreset(context) {
const { presetPath } = context;
let presetInfos = await remotePresets(context);
presetInfos = presetInfos.concat(localPreset(context));

const presetInfos = presetPath ? localPreset(context) : await remotePresets(context);
const presets = presetInfos.map(p => presetIdentifier(p.rawName).shortName);

Object.assign(context, { presets, presetInfos });
}

Expand Down
13 changes: 7 additions & 6 deletions packages/gasket-cli/src/scaffold/create-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ function flatten(acc, values) {
* @property {String} dest - Path to the target app (Default: cwd/appName)
* @property {String} relDest - Relative path to the target app
* @property {Boolean} extant - Whether or not target directory already exists
* @property {String} presetPath - path to a local preset package
* @property {PresetDesc[]} rawPresets - Raw preset desc from args. Can include version constraint. Added by load-preset if using presetPath.
* @property {[String]} localPresets - paths to the local presets packages
* @property {PresetDesc[]} rawPresets - Raw preset desc from args. Can include version constraint. Added by load-preset if using localPresets.
* @property {PluginDesc[]} rawPlugins - Raw plugin desc from flags, prompts, etc. Can include constraints.
* @property {PluginName[]} plugins - Short names of plugins
* @property {String[]} pkgLinks - Local packages that should be linked
Expand Down Expand Up @@ -132,17 +132,18 @@ module.exports = function makeCreateContext(argv = [], flags = {}) {
plugins = [],
presets = [],
'npm-link': npmLink = [],
'preset-path': presetPath,
'preset-path': presetPath = [],
'package-manager': packageManager
} = flags;

// Flatten the array of array created by the plugins flag – it
// supports both multiple instances as well as comma-separated lists.
const rawPresets = presets.reduce(flatten, []);
const localPresets = presetPath.reduce(flatten, []);
const rawPlugins = plugins.reduce(flatten, []);
const pkgLinks = npmLink.reduce(flatten, []);

if (!presetPath && rawPresets.length === 0) {
if (localPresets.length === 0 && rawPresets.length === 0) {
throw new Error('No preset specified.');
}

Expand All @@ -165,8 +166,8 @@ module.exports = function makeCreateContext(argv = [], flags = {}) {
extant,
npmconfig,
pkgLinks,
presetPath,
rawPresets: presetPath ? null : rawPresets,
localPresets,
rawPresets,
messages: [],
warnings: [],
errors: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,42 @@ describe('loadPreset', () => {
assume(loadPreset).property('wrapped');
});

describe('remote and local packages', () => {
beforeEach(() => {
mockContext.localPresets = ['../../../fixtures/local-preset'];
});

it('includes one of each other', async () => {
await loadPreset(mockContext);
assume(mockContext.presetInfos).to.lengthOf(2);
assume(mockContext).to.have.deep.property('rawPresets', ['@gasket/bogus-preset@^1.0.0']);
assume(mockContext).to.have.deep.property('localPresets', ['../../../fixtures/local-preset']);
assume(mockContext.presetInfos[0]).property('rawName');
assume(mockContext.presetInfos[0].rawName).equals('@gasket/bogus-preset@^1.0.0');
assume(mockContext.presetInfos[1]).property('rawName');
assume(mockContext.presetInfos[1].rawName).includes('@file:');
});

it('includes multiple of remote and local packages', async () => {
mockContext.rawPresets = ['@gasket/bogus-preset@^1.0.0', '@gasket/all-i-ever-wanted-preset@^2.0.0'];
mockContext.localPresets = ['../../../fixtures/local-preset', '../../../fixtures/local-preset'];

await loadPreset(mockContext);
console.log(mockContext);
assume(mockContext).to.have
.deep.property('rawPresets', ['@gasket/bogus-preset@^1.0.0', '@gasket/all-i-ever-wanted-preset@^2.0.0']);
assume(mockContext).to.have
.deep.property('localPresets', ['../../../fixtures/local-preset', '../../../fixtures/local-preset']);
assume(mockContext).to.have.deep.property('presets', ['bogus', 'all-i-ever-wanted', 'local-preset', 'local-preset']);
assume(mockContext.presetInfos).to.lengthOf(4);
});

});

describe('local package', () => {
beforeEach(() => {
mockContext.rawPresets = null;
mockContext.presetPath = '../../../fixtures/local-preset';
mockContext.localPresets = ['../../../fixtures/local-preset'];
});

it('does not instantiates Fetcher ', async () => {
Expand All @@ -101,6 +133,17 @@ describe('loadPreset', () => {
assume(mockContext.presetInfos[0]).property('rawName');
assume(mockContext.presetInfos[0].rawName).includes('@file:');
});

it('adds multiple local packages', async () => {
mockContext.localPresets = ['../../../fixtures/local-preset', '../../../fixtures/local-preset'];

await loadPreset(mockContext);
assume(mockContext.presetInfos).to.lengthOf(2);
assume(mockContext.presetInfos[0]).property('rawName');
assume(mockContext.presetInfos[0].rawName).includes('@file:');
assume(mockContext.presetInfos[1]).property('rawName');
assume(mockContext.presetInfos[1].rawName).includes('@file:');
});
});

describe('remote package', () => {
Expand Down
29 changes: 22 additions & 7 deletions packages/gasket-cli/test/unit/scaffold/create-context.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,29 @@ describe('makeCreateContext', () => {
assume(results.rawPresets).deep.equals(['@gasket/bogus-preset@^1.2.3']);
});

it('set presetPath from flags', () => {
results = makeCreateContext(argv, { 'preset-path': '../bogus/path' });
assume(results.presetPath).equals('../bogus/path');
it('sets rawPresets from flags with multiple entries', () => {
results = makeCreateContext(argv, { presets: ['@gasket/bogus-preset@^1.2.3', '@gasket/test-preset@^3.1.2'] });
assume(results.rawPresets).deep.equals(['@gasket/bogus-preset@^1.2.3', '@gasket/test-preset@^3.1.2']);
});

it('sets rawPresets to null if presetPath set', () => {
results = makeCreateContext(argv, { 'preset-path': '../bogus/path' });
assume(results.rawPresets).equals(null);
it('sets rawPresets to empty array if not defined', () => {
results = makeCreateContext(argv, { 'preset-path': ['../bogus/path'] });
assume(results.rawPresets).deep.equals([]);
});

it('sets localPresets from flags', () => {
results = makeCreateContext(argv, { 'preset-path': ['../bogus/path'] });
assume(results.localPresets).deep.equals(['../bogus/path']);
});

it('sets localPresets from flags with multiple entries', () => {
results = makeCreateContext(argv, { 'preset-path': ['../bogus/path', '../test/path'] });
assume(results.localPresets).deep.equals(['../bogus/path', '../test/path']);
});

it('sets localPresets to empty array if not defined', () => {
results = makeCreateContext(argv, { presets: ['@gasket/bogus-preset@^1.2.3'] });
assume(results.localPresets).deep.equals([]);
});

it('uses npmconfig from flags', () => {
Expand Down Expand Up @@ -240,7 +255,7 @@ describe('makeCreateContext', () => {
it('doesnt throw if preset path found', () => {
let error;
try {
results = makeCreateContext(argv, { 'preset-path': 'somePath' });
results = makeCreateContext(argv, { 'preset-path': ['somePath'] });
} catch (err) {
error = err;
}
Expand Down