fix(core): task-orchestrator properly handles arguments (#3560)
The task-orchestrator was converting command line flags to "yargs-compatible" string using a custom logic. This commit makes sure that this happens through `yargs-unparser` to avoid issues with more complex options like arrays and objects. ISSUES CLOSED: #3450
This commit is contained in:
parent
08e4ee29fa
commit
2d1da6b4a7
@ -138,6 +138,7 @@
|
||||
"express": "4.17.1",
|
||||
"file-loader": "4.2.0",
|
||||
"find-cache-dir": "3.0.0",
|
||||
"flat": "^5.0.2",
|
||||
"fork-ts-checker-webpack-plugin": "^3.1.1",
|
||||
"fs-extra": "7.0.1",
|
||||
"glob": "7.1.4",
|
||||
|
||||
@ -68,6 +68,7 @@
|
||||
"yargs": "^11.0.0",
|
||||
"chalk": "2.4.2",
|
||||
"@nrwl/cli": "*",
|
||||
"axios": "0.19.2"
|
||||
"axios": "0.19.2",
|
||||
"flat": "^5.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import { Cache, TaskWithCachedResult } from './cache';
|
||||
import { cliCommand } from '../core/file-utils';
|
||||
import { ProjectGraph } from '../core/project-graph';
|
||||
import { AffectedEventType, Task } from './tasks-runner';
|
||||
import { getOutputs } from './utils';
|
||||
import { getOutputs, unparse } from './utils';
|
||||
import { fork } from 'child_process';
|
||||
import { DefaultTasksRunnerOptions } from './default-tasks-runner';
|
||||
import { output } from '../utils/output';
|
||||
@ -318,13 +318,7 @@ export class TaskOrchestrator {
|
||||
}
|
||||
|
||||
private getCommandArgs(task: Task) {
|
||||
const args = Object.entries(task.overrides || {}).map(([prop, value]) =>
|
||||
typeof value === 'boolean'
|
||||
? value
|
||||
? `--${prop}`
|
||||
: `--no-${prop}`
|
||||
: `--${prop}=${value}`
|
||||
);
|
||||
const args: string[] = unparse(task.overrides || {});
|
||||
|
||||
const config = task.target.configuration
|
||||
? `:${task.target.configuration}`
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
import { getOutputsForTargetAndConfiguration } from '@nrwl/workspace/src/tasks-runner/utils';
|
||||
import {
|
||||
getOutputsForTargetAndConfiguration,
|
||||
unparse,
|
||||
} from '@nrwl/workspace/src/tasks-runner/utils';
|
||||
|
||||
describe('utils', () => {
|
||||
describe('getOutputsForTargetAndConfiguration', () => {
|
||||
@ -181,4 +184,59 @@ describe('utils', () => {
|
||||
).toEqual(['dist/root-myapp']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('unparse', () => {
|
||||
it('should unparse options whose values are primitives', () => {
|
||||
const options = {
|
||||
boolean1: false,
|
||||
boolean2: true,
|
||||
number: 4,
|
||||
string: 'foo',
|
||||
'empty-string': '',
|
||||
ignore: null,
|
||||
};
|
||||
|
||||
expect(unparse(options)).toEqual([
|
||||
'--no-boolean1',
|
||||
'--boolean2',
|
||||
'--number=4',
|
||||
'--string=foo',
|
||||
'--empty-string=',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should unparse options whose values are arrays', () => {
|
||||
const options = {
|
||||
array1: [1, 2],
|
||||
array2: [3, 4],
|
||||
};
|
||||
|
||||
expect(unparse(options)).toEqual([
|
||||
'--array1=1',
|
||||
'--array1=2',
|
||||
'--array2=3',
|
||||
'--array2=4',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should unparse options whose values are objects', () => {
|
||||
const options = {
|
||||
foo: {
|
||||
x: 'x',
|
||||
y: 'y',
|
||||
w: [1, 2],
|
||||
z: [3, 4],
|
||||
},
|
||||
};
|
||||
|
||||
expect(unparse(options)).toEqual([
|
||||
'--foo.x=x',
|
||||
'--foo.y=y',
|
||||
'--foo.w=1',
|
||||
'--foo.w=2',
|
||||
'--foo.z=3',
|
||||
'--foo.z=4',
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Task } from './tasks-runner';
|
||||
import { ProjectGraphNode } from '../core/project-graph';
|
||||
import * as flatten from 'flat';
|
||||
|
||||
const commonCommands = ['build', 'test', 'lint', 'e2e', 'deploy'];
|
||||
|
||||
@ -75,3 +76,34 @@ export function getOutputsForTargetAndConfiguration(
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export function unparse(options: Object): string[] {
|
||||
const unparsed = [];
|
||||
for (const key of Object.keys(options)) {
|
||||
const value = options[key];
|
||||
unparseOption(key, value, unparsed);
|
||||
}
|
||||
|
||||
return unparsed;
|
||||
}
|
||||
|
||||
function unparseOption(key: string, value: any, unparsed: string[]) {
|
||||
if (value === true) {
|
||||
unparsed.push(`--${key}`);
|
||||
} else if (value === false) {
|
||||
unparsed.push(`--no-${key}`);
|
||||
} else if (Array.isArray(value)) {
|
||||
value.forEach((item) => unparseOption(key, item, unparsed));
|
||||
} else if (Object.prototype.toString.call(value) === '[object Object]') {
|
||||
const flattened = flatten(value, { safe: true });
|
||||
for (const flattenedKey in flattened) {
|
||||
unparseOption(
|
||||
`${key}.${flattenedKey}`,
|
||||
flattened[flattenedKey],
|
||||
unparsed
|
||||
);
|
||||
}
|
||||
} else if (typeof value === 'string' || value != null) {
|
||||
unparsed.push(`--${key}=${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10094,6 +10094,11 @@ flat-cache@^2.0.1:
|
||||
rimraf "2.6.3"
|
||||
write "1.0.3"
|
||||
|
||||
flat@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
|
||||
integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
|
||||
|
||||
flatted@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user