-
Notifications
You must be signed in to change notification settings - Fork 12k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(@angular/cli): handle duplicate arguments
With this change we add a Yargs middleware that normalizes non Array options when the argument has been provided multiple times. By default, when an option is non array and it is provided multiple times in the command line, yargs will not override it's value but instead it will be changed to an array unless `duplicate-arguments-array` is disabled. But this option also have an effect on real array options which isn't desired. See: yargs/yargs-parser#163 (comment) Closes #22956
- Loading branch information
1 parent
d87b858
commit ff4eba3
Showing
3 changed files
with
58 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
packages/angular/cli/src/command-builder/utilities/normalize-options-middleware.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import * as yargs from 'yargs'; | ||
|
||
/** | ||
* A Yargs middleware that normalizes non Array options when the argument has been provided multiple times. | ||
* | ||
* By default, when an option is non array and it is provided multiple times in the command line, yargs | ||
* will not override it's value but instead it will be changed to an array unless `duplicate-arguments-array` is disabled. | ||
* But this option also have an effect on real array options which isn't desired. | ||
* | ||
* See: https://github.com/yargs/yargs-parser/pull/163#issuecomment-516566614 | ||
*/ | ||
export function normalizeOptionsMiddleware(args: yargs.Arguments): void { | ||
// `getOptions` is not included in the types even though it's public API. | ||
// https://github.com/yargs/yargs/issues/2098 | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const { array } = (yargs as any).getOptions(); | ||
const arrayOptions = new Set(array); | ||
|
||
for (const [key, value] of Object.entries(args)) { | ||
if (key !== '_' && Array.isArray(value) && !arrayOptions.has(key)) { | ||
const newValue = value.pop(); | ||
// eslint-disable-next-line no-console | ||
console.warn( | ||
`Option '${key}' has been specified multiple times. The value '${newValue}' will be used.`, | ||
); | ||
args[key] = newValue; | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
tests/legacy-cli/e2e/tests/misc/duplicate-command-line-option.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { ng } from '../../utils/process'; | ||
import { expectFileToExist } from '../../utils/fs'; | ||
|
||
export default async function () { | ||
const { stderr } = await ng( | ||
'generate', | ||
'component', | ||
'test-component', | ||
'--style=scss', | ||
'--style=sass', | ||
); | ||
|
||
const warningMatch = `Option 'style' has been specified multiple times. The value 'sass' will be used`; | ||
if (!stderr.includes(warningMatch)) { | ||
throw new Error(`Expected stderr to contain: "${warningMatch}".`); | ||
} | ||
|
||
await expectFileToExist('src/app/test-component/test-component.component.sass'); | ||
} |