feat(nx): support passing args to run-commands builder
This commit is contained in:
parent
857ee73142
commit
7d5fdcd1d3
@ -4,15 +4,11 @@ Run commands
|
||||
|
||||
## Properties
|
||||
|
||||
### commands
|
||||
|
||||
Type: `array` of `object`
|
||||
|
||||
#### command
|
||||
### args
|
||||
|
||||
Type: `string`
|
||||
|
||||
Command to run in child process
|
||||
Extra arguments. You can pass them as follows: ng run project:target --args='--wait=100'. You can them use {args.wait} syntax to interpolate them in angular.json
|
||||
|
||||
### parallel
|
||||
|
||||
|
||||
@ -23,7 +23,6 @@ describe('ng-add', () => {
|
||||
.toPromise();
|
||||
const packageJson = readJsonInTree(result, 'package.json');
|
||||
|
||||
console.log(packageJson);
|
||||
expect(packageJson.dependencies['@nrwl/nest']).toBeUndefined();
|
||||
expect(packageJson.devDependencies['@nrwl/nest']).toBeDefined();
|
||||
expect(packageJson.dependencies['@nestjs/core']).toBeDefined();
|
||||
|
||||
@ -194,4 +194,52 @@ describe('Command Runner Builder', () => {
|
||||
expect(result).toEqual({ success: false });
|
||||
expect(readFile(f)).toEqual('1');
|
||||
});
|
||||
|
||||
it('should throw when invalid args', async () => {
|
||||
const root = normalize('/root');
|
||||
const f = fileSync().name;
|
||||
|
||||
try {
|
||||
await builder
|
||||
.run({
|
||||
root,
|
||||
builder: '@nrwl/run-commands',
|
||||
projectType: 'application',
|
||||
options: {
|
||||
commands: [
|
||||
{
|
||||
command: `echo {args.key} >> ${f}`
|
||||
}
|
||||
],
|
||||
args: 'key=value'
|
||||
}
|
||||
})
|
||||
.toPromise();
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual('Invalid args: key=value');
|
||||
}
|
||||
});
|
||||
|
||||
it('should enable parameter substitution', async () => {
|
||||
const root = normalize('/root');
|
||||
const f = fileSync().name;
|
||||
const result = await builder
|
||||
.run({
|
||||
root,
|
||||
builder: '@nrwl/run-commands',
|
||||
projectType: 'application',
|
||||
options: {
|
||||
commands: [
|
||||
{
|
||||
command: `echo {args.key} >> ${f}`
|
||||
}
|
||||
],
|
||||
args: '--key=value'
|
||||
}
|
||||
})
|
||||
.toPromise();
|
||||
|
||||
expect(result).toEqual({ success: true });
|
||||
expect(readFile(f)).toEqual('value');
|
||||
});
|
||||
});
|
||||
|
||||
@ -15,6 +15,8 @@ export interface RunCommandsBuilderOptions {
|
||||
commands: { command: string }[];
|
||||
parallel?: boolean;
|
||||
readyWhen?: string;
|
||||
args?: string;
|
||||
parsedArgs?: { [k: string]: string };
|
||||
}
|
||||
|
||||
export default class RunCommandsBuilder
|
||||
@ -22,6 +24,10 @@ export default class RunCommandsBuilder
|
||||
run(
|
||||
config: BuilderConfiguration<RunCommandsBuilderOptions>
|
||||
): Observable<BuildEvent> {
|
||||
config.options.parsedArgs = {
|
||||
...(config.options as any),
|
||||
...this.parseArgs(config.options.args)
|
||||
};
|
||||
return Observable.create(async observer => {
|
||||
if (!config || !config.options || !config.options.commands) {
|
||||
observer.error(
|
||||
@ -62,7 +68,10 @@ export default class RunCommandsBuilder
|
||||
config: BuilderConfiguration<RunCommandsBuilderOptions>
|
||||
) {
|
||||
const procs = config.options.commands.map(c =>
|
||||
this.createProcess(c.command, config.options.readyWhen).then(result => ({
|
||||
this.createProcess(
|
||||
this.transformCommand(c.command, config.options.parsedArgs),
|
||||
config.options.readyWhen
|
||||
).then(result => ({
|
||||
result,
|
||||
command: c.command
|
||||
}))
|
||||
@ -106,7 +115,7 @@ export default class RunCommandsBuilder
|
||||
>(async (m, c) => {
|
||||
if ((await m) === null) {
|
||||
const success = await this.createProcess(
|
||||
c.command,
|
||||
this.transformCommand(c.command, config.options.parsedArgs),
|
||||
config.options.readyWhen
|
||||
);
|
||||
return !success ? c.command : null;
|
||||
@ -151,4 +160,29 @@ export default class RunCommandsBuilder
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private transformCommand(command: string, args: any) {
|
||||
const regex = /{args\.([^}]+)}/g;
|
||||
return command.replace(regex, (_, group: string) => args[group]);
|
||||
}
|
||||
|
||||
private parseArgs(args: string) {
|
||||
if (!args) {
|
||||
return {};
|
||||
}
|
||||
return args
|
||||
.split(' ')
|
||||
.map(t => t.trim())
|
||||
.reduce((m, c) => {
|
||||
if (!c.startsWith('--')) {
|
||||
throw new Error(`Invalid args: ${args}`);
|
||||
}
|
||||
const [key, value] = c.substring(2).split('=');
|
||||
if (!key || !value) {
|
||||
throw new Error(`Invalid args: ${args}`);
|
||||
}
|
||||
m[key] = value;
|
||||
return m;
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,10 @@
|
||||
"readyWhen": {
|
||||
"type": "string",
|
||||
"description": "String to appear in stdout or stderr that indicates that the task is done. This option can only be used when parallel is set to true. If not specified, the task is done when all the child processes complete."
|
||||
},
|
||||
"args": {
|
||||
"type": "string",
|
||||
"description": "Extra arguments. You can pass them as follows: ng run project:target --args='--wait=100'. You can them use {args.wait} syntax to interpolate them in angular.json"
|
||||
}
|
||||
},
|
||||
"required": ["commands"]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user