fix(core): alias conversion should not exclude unknown props for builders

This commit is contained in:
Victor Savkin 2020-07-01 21:47:50 -04:00 committed by Victor Savkin
parent 74c73b5398
commit d9536703f3
4 changed files with 49 additions and 32 deletions

View File

@ -27,7 +27,10 @@ import {
convertToCamelCase, convertToCamelCase,
handleErrors, handleErrors,
Schema, Schema,
validateOptions, Options,
lookupUnmatched,
convertAliases,
coerceTypes,
} from '../shared/params'; } from '../shared/params';
import { commandName, printHelp } from '../shared/print-help'; import { commandName, printHelp } from '../shared/print-help';
// @ts-ignore // @ts-ignore
@ -317,7 +320,7 @@ async function runSchematic(
const record = { loggingQueue: [] as string[], error: false }; const record = { loggingQueue: [] as string[], error: false };
workflow.reporter.subscribe(createRecorder(record, logger)); workflow.reporter.subscribe(createRecorder(record, logger));
const schematicOptions = validateOptions( const schematicOptions = normalizeOptions(
opts.schematicOptions, opts.schematicOptions,
flattenedSchema flattenedSchema
); );
@ -421,6 +424,13 @@ export async function taoNew(
}); });
} }
function normalizeOptions(opts: Options, schema: Schema): Options {
return lookupUnmatched(
convertAliases(coerceTypes(opts, schema), schema, true),
schema
);
}
function isTTY(): boolean { function isTTY(): boolean {
return !!process.stdout.isTTY && process.env['CI'] !== 'true'; return !!process.stdout.isTTY && process.env['CI'] !== 'true';
} }

View File

@ -10,9 +10,11 @@ import {
import { NodeJsSyncHost } from '@angular-devkit/core/node'; import { NodeJsSyncHost } from '@angular-devkit/core/node';
import { getLogger } from '../shared/logger'; import { getLogger } from '../shared/logger';
import { import {
coerceTypesAndNormalizeAliases, coerceTypes,
convertAliases,
convertToCamelCase, convertToCamelCase,
handleErrors, handleErrors,
Options,
Schema, Schema,
} from '../shared/params'; } from '../shared/params';
import { commandName, printHelp } from '../shared/print-help'; import { commandName, printHelp } from '../shared/print-help';
@ -175,7 +177,7 @@ export async function run(root: string, args: string[], isVerbose: boolean) {
return 0; return 0;
} }
const runOptions = coerceTypesAndNormalizeAliases( const runOptions = normalizeOptions(
opts.runOptions, opts.runOptions,
flattenedSchema as any flattenedSchema as any
); );
@ -193,3 +195,7 @@ export async function run(root: string, args: string[], isVerbose: boolean) {
return result.success ? 0 : 1; return result.success ? 0 : 1;
}); });
} }
function normalizeOptions(opts: Options, schema: Schema): Options {
return convertAliases(coerceTypes(opts, schema), schema, false);
}

View File

@ -97,12 +97,13 @@ describe('params', () => {
properties: { directory: { type: 'string', alias: 'd' } }, properties: { directory: { type: 'string', alias: 'd' } },
required: [], required: [],
description: '', description: '',
} },
true
) )
).toEqual({ directory: 'test' }); ).toEqual({ directory: 'test' });
}); });
it('should filter unknown keys into the leftovers field', () => { it('should filter unknown keys into the leftovers field when excludeUnmatched is true', () => {
expect( expect(
convertAliases( convertAliases(
{ d: 'test' }, { d: 'test' },
@ -110,7 +111,8 @@ describe('params', () => {
properties: { directory: { type: 'string' } }, properties: { directory: { type: 'string' } },
required: [], required: [],
description: '', description: '',
} },
true
) )
).toEqual({ ).toEqual({
'--': [ '--': [
@ -121,6 +123,22 @@ describe('params', () => {
], ],
}); });
}); });
it('should not filter unknown keys into the leftovers field when excludeUnmatched is false', () => {
expect(
convertAliases(
{ d: 'test' },
{
properties: { directory: { type: 'string' } },
required: [],
description: '',
},
false
)
).toEqual({
d: 'test',
});
});
}); });
describe('lookupUnmatched', () => { describe('lookupUnmatched', () => {

View File

@ -83,7 +83,11 @@ export function coerceTypes(opts: Options, schema: Schema): Options {
* @param opts The options passed in by the user * @param opts The options passed in by the user
* @param schema The schema definition to check against * @param schema The schema definition to check against
*/ */
export function convertAliases(opts: Options, schema: Schema): Options { export function convertAliases(
opts: Options,
schema: Schema,
excludeUnmatched: boolean
): Options {
return Object.keys(opts).reduce((acc, k) => { return Object.keys(opts).reduce((acc, k) => {
if (schema.properties[k]) { if (schema.properties[k]) {
acc[k] = opts[k]; acc[k] = opts[k];
@ -93,7 +97,7 @@ export function convertAliases(opts: Options, schema: Schema): Options {
); );
if (found) { if (found) {
acc[found[0]] = opts[k]; acc[found[0]] = opts[k];
} else { } else if (excludeUnmatched) {
if (!acc['--']) { if (!acc['--']) {
acc['--'] = []; acc['--'] = [];
} }
@ -101,6 +105,8 @@ export function convertAliases(opts: Options, schema: Schema): Options {
name: k, name: k,
possible: [], possible: [],
}); });
} else {
acc[k] = opts[k];
} }
} }
return acc; return acc;
@ -126,26 +132,3 @@ export function lookupUnmatched(opts: Options, schema: Schema): Options {
} }
return opts; return opts;
} }
export function coerceTypesAndNormalizeAliases(
opts: Options,
schema: Schema
): Options {
return convertAliases(coerceTypes(opts, schema), schema);
}
/**
* Converts aliases and coerces types according to the schema
*
* @param opts The options to check
* @param schema The schema definition to validate against
*
* @remarks
*
* Unmatched options are added to opts['--']
* and listed along with possible schema matches
*
*/
export function validateOptions(opts: Options, schema: Schema): Options {
return lookupUnmatched(coerceTypesAndNormalizeAliases(opts, schema), schema);
}