Skip to content

Commit 5571d09

Browse files
mnahkiesalexeagle
authored andcommitted
fix(@angular/cli): pass arguments to all targets
When running a command with args against multiple targets, all targets should be given the args. As parseArguments was mutating the passed args array this wasn't the case. Fix by not mutating the array. This was especially noticeable when using the `ng lint --fix` command on a newly generated project, as files in the app target would be fixed, but e2e target would be only be linted (with no fix) Possibly closes #10657, #10656, #11005
1 parent f979f0d commit 5571d09

File tree

2 files changed

+27
-13
lines changed

2 files changed

+27
-13
lines changed

packages/angular/cli/models/parser.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ function _removeLeadingDashes(key: string): string {
118118

119119
function _assignOption(
120120
arg: string,
121-
args: string[],
121+
nextArg: string | undefined,
122122
{ options, parsedOptions, leftovers, ignored, errors, deprecations }: {
123123
options: Option[],
124124
parsedOptions: Arguments,
@@ -130,9 +130,10 @@ function _assignOption(
130130
},
131131
) {
132132
const from = arg.startsWith('--') ? 2 : 1;
133+
let consumedNextArg = false;
133134
let key = arg.substr(from);
134135
let option: Option | null = null;
135-
let value = '';
136+
let value: string | undefined = '';
136137
const i = arg.indexOf('=');
137138

138139
// If flag is --no-abc AND there's no equal sign.
@@ -151,7 +152,7 @@ function _assignOption(
151152
// Set it to true if it's a boolean and the next argument doesn't match true/false.
152153
const maybeOption = _getOptionFromName(key, options);
153154
if (maybeOption) {
154-
value = args[0];
155+
value = nextArg;
155156
let shouldShift = true;
156157

157158
if (value && value.startsWith('-')) {
@@ -163,7 +164,7 @@ function _assignOption(
163164

164165
// Only absorb it if it leads to a better value.
165166
if (shouldShift && _coerce(value, maybeOption) !== undefined) {
166-
args.shift();
167+
consumedNextArg = true;
167168
} else {
168169
value = '';
169170
}
@@ -179,9 +180,9 @@ function _assignOption(
179180
}
180181

181182
if (option === null) {
182-
if (args[0] && !args[0].startsWith('-')) {
183-
leftovers.push(arg, args[0]);
184-
args.shift();
183+
if (nextArg && !nextArg.startsWith('-')) {
184+
leftovers.push(arg, nextArg);
185+
consumedNextArg = true;
185186
} else {
186187
leftovers.push(arg);
187188
}
@@ -206,6 +207,8 @@ function _assignOption(
206207
ignored.push(arg);
207208
}
208209
}
210+
211+
return consumedNextArg;
209212
}
210213

211214

@@ -289,30 +292,33 @@ export function parseArguments(
289292

290293
const state = { options, parsedOptions, positionals, leftovers, ignored, errors, deprecations };
291294

292-
for (let arg = args.shift(); arg !== undefined; arg = args.shift()) {
295+
for (let argIndex = 0; argIndex < args.length; argIndex++) {
296+
const arg = args[argIndex];
297+
let consumedNextArg = false;
298+
293299
if (arg == '--') {
294300
// If we find a --, we're done.
295-
leftovers.push(...args);
301+
leftovers.push(...args.slice(argIndex + 1));
296302
break;
297303
}
298304

299305
if (arg.startsWith('--')) {
300-
_assignOption(arg, args, state);
306+
consumedNextArg = _assignOption(arg, args[argIndex + 1], state);
301307
} else if (arg.startsWith('-')) {
302308
// Argument is of form -abcdef. Starts at 1 because we skip the `-`.
303309
for (let i = 1; i < arg.length; i++) {
304310
const flag = arg[i];
305311
// If the next character is an '=', treat it as a long flag.
306312
if (arg[i + 1] == '=') {
307313
const f = '-' + flag + arg.slice(i + 1);
308-
_assignOption(f, args, state);
314+
consumedNextArg = _assignOption(f, args[argIndex + 1], state);
309315
break;
310316
}
311317
// Treat the last flag as `--a` (as if full flag but just one letter). We do this in
312318
// the loop because it saves us a check to see if the arg is just `-`.
313319
if (i == arg.length - 1) {
314320
const arg = '-' + flag;
315-
_assignOption(arg, args, state);
321+
consumedNextArg = _assignOption(arg, args[argIndex + 1], state);
316322
} else {
317323
const maybeOption = _getOptionFromName(flag, options);
318324
if (maybeOption) {
@@ -326,6 +332,10 @@ export function parseArguments(
326332
} else {
327333
positionals.push(arg);
328334
}
335+
336+
if (consumedNextArg) {
337+
argIndex++;
338+
}
329339
}
330340

331341
// Deal with positionals.

packages/angular/cli/models/parser_spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,14 @@ describe('parseArguments', () => {
144144
Object.entries(tests).forEach(([str, expected]) => {
145145
it(`works for ${str}`, () => {
146146
try {
147-
const actual = parseArguments(str.split(' '), options);
147+
const originalArgs = str.split(' ');
148+
const args = originalArgs.slice();
149+
150+
const actual = parseArguments(args, options);
148151

149152
expect(Array.isArray(expected)).toBe(false);
150153
expect(actual).toEqual(expected as Arguments);
154+
expect(args).toEqual(originalArgs);
151155
} catch (e) {
152156
if (!(e instanceof ParseArgumentException)) {
153157
throw e;

0 commit comments

Comments
 (0)