Skip to content

Commit 88fc93f

Browse files
hanslBrocco
authored andcommitted
feat(@angular/cli): allow commands to reparse options if needed
1 parent 71772fd commit 88fc93f

File tree

2 files changed

+29
-28
lines changed

2 files changed

+29
-28
lines changed

packages/@angular/cli/models/command-runner.ts

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
CommandScope
77
} from '../models/command';
88
import { oneLine } from 'common-tags';
9-
import { Logger } from '@angular-devkit/core/src/logger';
9+
import { logging } from '@angular-devkit/core';
1010
import { camelize } from '@angular-devkit/core/src/utils/strings';
1111

1212
const yargsParser = require('yargs-parser');
@@ -19,12 +19,13 @@ export interface CommandMap {
1919
* Run a command.
2020
* @param commandMap Map of available commands.
2121
* @param args Raw unparsed arguments.
22+
* @param logger The logger to use.
2223
* @param context Execution context.
2324
*/
2425
export async function runCommand(commandMap: CommandMap,
25-
args: string[],
26-
logger: Logger,
27-
context: CommandContext): Promise<any> {
26+
args: string[],
27+
logger: logging.Logger,
28+
context: CommandContext): Promise<any> {
2829

2930
const rawOptions = yargsParser(args, { alias: { help: ['h'] }, boolean: [ 'help' ] });
3031
let commandName = rawOptions._[0];
@@ -55,11 +56,10 @@ export async function runCommand(commandMap: CommandMap,
5556

5657
const command = new Cmd(context, logger);
5758

58-
let options = parseOptions(yargsParser, args, command.options);
59-
options = mapArguments(options, command.arguments);
59+
args = await command.initializeRaw(args);
60+
let options = parseOptions(args, command.options, command.arguments);
6061
await command.initialize(options);
61-
options = parseOptions(yargsParser, args, command.options);
62-
options = mapArguments(options, command.arguments);
62+
options = parseOptions(args, command.options, command.arguments);
6363
if (commandName === 'help') {
6464
options.commandMap = commandMap;
6565
}
@@ -74,9 +74,13 @@ export async function runCommand(commandMap: CommandMap,
7474
}
7575
}
7676

77-
function parseOptions(parser: Function,
78-
args: string[],
79-
cmdOpts: Option[]): any {
77+
export function parseOptions<T = any>(
78+
args: string[],
79+
cmdOpts: Option[],
80+
commandArguments: string[],
81+
): T {
82+
const parser = yargsParser;
83+
8084
const aliases = cmdOpts.concat()
8185
.filter(o => o.aliases && o.aliases.length > 0)
8286
.reduce((aliases: any, opt: Option) => {
@@ -131,23 +135,17 @@ function parseOptions(parser: Function,
131135
.filter(key => key.indexOf('-') !== -1)
132136
.forEach(key => delete parsedOptions[key]);
133137

134-
return parsedOptions;
135-
}
136-
137-
// Map arguments to options.
138-
function mapArguments(options: any, args: string[]): any {
139-
const optsWithMappedArgs = {...options};
140-
optsWithMappedArgs._.forEach((value: string, index: number) => {
138+
parsedOptions._.forEach((value: string, index: number) => {
141139
// Remove the starting "<" and trailing ">".
142-
const arg = args[index];
140+
const arg = commandArguments[index];
143141
if (arg) {
144-
optsWithMappedArgs[arg] = value;
142+
parsedOptions[arg] = value;
145143
}
146144
});
147145

148-
delete optsWithMappedArgs._;
146+
delete parsedOptions._;
149147

150-
return optsWithMappedArgs;
148+
return parsedOptions;
151149
}
152150

153151
// Find a command.

packages/@angular/cli/models/command.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { Logger } from '@angular-devkit/core/src/logger';
1+
import { logging } from '@angular-devkit/core';
22
const { cyan } = require('chalk');
33

44
export interface CommandConstructor {
5-
new(context: CommandContext, logger: Logger): Command;
5+
new(context: CommandContext, logger: logging.Logger): Command;
66
aliases: string[];
77
scope: CommandScope.everywhere;
88
}
@@ -14,16 +14,19 @@ export enum CommandScope {
1414
}
1515

1616
export abstract class Command {
17-
constructor(context: CommandContext, logger: Logger) {
17+
constructor(context: CommandContext, logger: logging.Logger) {
1818
this.logger = logger;
1919
if (context) {
2020
this.project = context.project;
2121
this.ui = context.ui;
2222
}
2323
}
2424

25-
initialize(_options: any): Promise<void> {
26-
return Promise.resolve();
25+
async initializeRaw(args: any): Promise<any> {
26+
return args;
27+
}
28+
async initialize(_options: any): Promise<void> {
29+
return;
2730
}
2831

2932
validate(_options: any): boolean | Promise<boolean> {
@@ -68,7 +71,7 @@ export abstract class Command {
6871
public hidden = false;
6972
public unknown = false;
7073
public scope = CommandScope.everywhere;
71-
protected readonly logger: Logger;
74+
protected readonly logger: logging.Logger;
7275
protected readonly project: any;
7376
protected readonly ui: Ui;
7477
}

0 commit comments

Comments
 (0)