feat(core): forward options for run command (#22064)

This commit is contained in:
Emily Xiong 2024-03-06 12:08:45 -05:00 committed by GitHub
parent 876bc94aab
commit da5a19dfee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 78 additions and 18 deletions

View File

@ -153,6 +153,21 @@ describe('Extra Nx Misc Tests', () => {
expect(result).toContain('--var1=a');
}, 120000);
it('should pass unknown options', async () => {
updateJson(join('libs', mylib, 'project.json'), (config) => {
config.targets.echo = {
command: 'echo',
options: {
var1: 'a',
},
};
return config;
});
const result = runCLI(`run ${mylib}:echo`, { silent: true });
expect(result).toContain('--var1 a');
}, 120000);
it('should interpolate provided arguments', async () => {
const echoTarget = uniq('echo');
updateJson(join('libs', mylib, 'project.json'), (config) => {

View File

@ -190,6 +190,16 @@ describe('Run Commands', () => {
).toEqual('echo --additional-arg');
});
it('should add forward unknown options when forwardAllArgs is true', () => {
expect(
interpolateArgsIntoCommand(
'echo',
{ unknownOptions: { hello: 123 }, parsedArgs: { hello: 123 } } as any,
true
)
).toEqual('echo --hello 123');
});
it('should add all args and unparsed args when forwardAllArgs is true', () => {
expect(
interpolateArgsIntoCommand(

View File

@ -62,6 +62,10 @@ const propKeys = [
'cwd',
'args',
'envFile',
'__unparsed__',
'env',
'mode',
'verbose',
];
export interface NormalizedRunCommandsOptions extends RunCommandsOptions {
@ -69,6 +73,9 @@ export interface NormalizedRunCommandsOptions extends RunCommandsOptions {
command: string;
forwardAllArgs?: boolean;
}[];
unknownOptions?: {
[k: string]: any;
};
parsedArgs: {
[k: string]: any;
};
@ -173,7 +180,25 @@ function normalizeOptions(
if (options.args && Array.isArray(options.args)) {
options.args = options.args.join(' ');
}
options.parsedArgs = parseArgs(options, options.args as string);
const unparsedCommandArgs = yargsParser(options.__unparsed__, {
configuration: {
'parse-numbers': false,
'parse-positional-numbers': false,
'dot-notation': false,
},
});
options.unknownOptions = Object.keys(options)
.filter(
(p) => propKeys.indexOf(p) === -1 && unparsedCommandArgs[p] === undefined
)
.reduce((m, c) => ((m[c] = options[c]), m), {});
options.parsedArgs = parseArgs(
unparsedCommandArgs,
options.unknownOptions,
options.args as string
);
(options as NormalizedRunCommandsOptions).commands.forEach((c) => {
c.command = interpolateArgsIntoCommand(
@ -361,7 +386,7 @@ export function interpolateArgsIntoCommand(
command: string,
opts: Pick<
NormalizedRunCommandsOptions,
'args' | 'parsedArgs' | '__unparsed__'
'args' | 'parsedArgs' | '__unparsed__' | 'unknownOptions'
>,
forwardAllArgs: boolean
) {
@ -371,28 +396,38 @@ export function interpolateArgsIntoCommand(
opts.parsedArgs[group] !== undefined ? opts.parsedArgs[group] : ''
);
} else if (forwardAllArgs) {
return `${command}${opts.args ? ' ' + opts.args : ''}${
opts.__unparsed__.length > 0 ? ' ' + opts.__unparsed__.join(' ') : ''
}`;
let args = '';
if (Object.keys(opts.unknownOptions ?? {}).length > 0) {
args +=
' ' +
Object.keys(opts.unknownOptions)
.filter(
(k) =>
typeof opts.unknownOptions[k] !== 'object' &&
opts.parsedArgs[k] === opts.unknownOptions[k]
)
.map((k) => `--${k} ${opts.unknownOptions[k]}`)
.join(' ');
}
if (opts.args) {
args += ` ${opts.args}`;
}
if (opts.__unparsed__?.length > 0) {
args += ` ${opts.__unparsed__.join(' ')}`;
}
return `${command}${args}`;
} else {
return command;
}
}
function parseArgs(options: RunCommandsOptions, args?: string) {
function parseArgs(
unparsedCommandArgs: { [k: string]: string },
unknownOptions: { [k: string]: string },
args?: string
) {
if (!args) {
const unknownOptionsTreatedAsArgs = Object.keys(options)
.filter((p) => propKeys.indexOf(p) === -1)
.reduce((m, c) => ((m[c] = options[c]), m), {});
const unparsedCommandArgs = yargsParser(options.__unparsed__, {
configuration: {
'parse-numbers': false,
'parse-positional-numbers': false,
'dot-notation': false,
},
});
return { ...unknownOptionsTreatedAsArgs, ...unparsedCommandArgs };
return { ...unknownOptions, ...unparsedCommandArgs };
}
return yargsParser(args.replace(/(^"|"$)/g, ''), {
configuration: { 'camel-case-expansion': false },