99
1010import { Architect , BuilderInfo , BuilderProgressState , Target } from '@angular-devkit/architect' ;
1111import { WorkspaceNodeModulesArchitectHost } from '@angular-devkit/architect/node' ;
12- import { logging , schema , tags , workspaces } from '@angular-devkit/core' ;
12+ import { json , logging , schema , tags , workspaces } from '@angular-devkit/core' ;
1313import { NodeJsSyncHost , createConsoleLogger } from '@angular-devkit/core/node' ;
1414import * as ansiColors from 'ansi-colors' ;
1515import { existsSync } from 'fs' ;
16- import minimist from 'minimist' ;
1716import * as path from 'path' ;
1817import { tap } from 'rxjs/operators' ;
18+ import yargsParser from 'yargs-parser' ;
1919import { MultiProgressBar } from '../src/progress' ;
2020
2121function findUp ( names : string | string [ ] , from : string ) {
@@ -78,24 +78,43 @@ async function _executeTarget(
7878 parentLogger: logging.Logger,
7979 workspace: workspaces.WorkspaceDefinition,
8080 root: string,
81- argv: minimist.ParsedArgs ,
81+ argv: yargsParser.Arguments ,
8282 registry: schema.SchemaRegistry,
8383) {
8484 const architectHost = new WorkspaceNodeModulesArchitectHost(workspace, root);
8585 const architect = new Architect(architectHost, registry);
8686
8787 // Split a target into its parts.
88- const targetStr = argv._.shift() || '';
88+ const {
89+ _: [targetStr = ''],
90+ help,
91+ ...options
92+ } = argv;
8993 const [project, target, configuration] = targetStr.split(':');
9094 const targetSpec = { project, target, configuration };
9195
92- delete argv['help'];
9396 const logger = new logging.Logger('jobs');
9497 const logs: logging.LogEntry[] = [];
9598 logger.subscribe((entry) => logs.push({ ...entry, message: ` $ { entry . name } : ` + entry.message }));
9699
97- const { _, ...options } = argv;
98- const run = await architect.scheduleTarget(targetSpec, options, { logger });
100+ // Camelize options as yargs will return the object in kebab-case when camel casing is disabled.
101+
102+ // Casting temporary until https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59065 is merged and released.
103+ const { camelCase, decamelize } = yargsParser as yargsParser.Parser & {
104+ camelCase(str: string): string;
105+ decamelize(str: string, joinString?: string): string;
106+ };
107+
108+ const camelCasedOptions: json.JsonObject = {};
109+ for (const [key, value] of Object.entries(options)) {
110+ if (/[A-Z]/.test(key)) {
111+ throw new Error(` Unknown argument ${key } . Did you mean ${decamelize ( key ) } ?`);
112+ }
113+
114+ camelCasedOptions[camelCase(key)] = value;
115+ }
116+
117+ const run = await architect.scheduleTarget(targetSpec, camelCasedOptions, { logger });
99118 const bars = new MultiProgressBar<number, BarInfo>(':name :bar (:current/:total) :status');
100119
101120 run.progress.subscribe((update) => {
@@ -107,7 +126,7 @@ async function _executeTarget(
107126 name: (
108127 (update.target ? _targetStringFromTarget(update.target) : update.builder.name) +
109128 ' '.repeat(80)
110- ).substr (0, 40),
129+ ).substring (0, 40),
111130 };
112131
113132 if (update.status !== undefined) {
@@ -175,7 +194,15 @@ async function _executeTarget(
175194
176195async function main(args: string[]): Promise<number> {
177196 /** Parse the command line. */
178- const argv = minimist(args, { boolean: ['help'] });
197+ const argv = yargsParser(args, {
198+ boolean: ['help'],
199+ configuration: {
200+ 'dot-notation': false,
201+ 'boolean-negation': true,
202+ 'strip-aliased': true,
203+ 'camel-case-expansion': false,
204+ },
205+ });
179206
180207 /** Create the DevKit Logger used through the CLI. */
181208 const logger = createConsoleLogger(argv['verbose'], process.stdout, process.stderr, {
0 commit comments