Skip to content

Commit 3a7d0d2

Browse files
committed
fix(@angular/cli): clean up architect options
Fix angular#10699
1 parent 89242be commit 3a7d0d2

File tree

9 files changed

+183
-241
lines changed

9 files changed

+183
-241
lines changed

package-lock.json

+95-89
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+4-25
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
import { ArchitectCommand } from '../models/architect-command';
21
import { Option, CommandScope } from '../models/command';
32
import { Version } from '../upgrade/version';
4-
5-
export interface Options {
6-
project?: string;
7-
configuration?: string;
8-
prod: boolean;
9-
}
3+
import { ArchitectCommand, ArchitectCommandOptions } from '../models/architect-command';
104

115
export default class BuildCommand extends ArchitectCommand {
126
public readonly name = 'build';
@@ -20,29 +14,14 @@ export default class BuildCommand extends ArchitectCommand {
2014
this.configurationOption
2115
];
2216

23-
public validate(options: Options) {
17+
public validate(options: ArchitectCommandOptions) {
2418
// Check Angular and TypeScript versions.
2519
Version.assertCompatibleAngularVersion(this.project.root);
2620
Version.assertTypescriptVersion(this.project.root);
2721
return super.validate(options);
2822
}
2923

30-
public async run(options: Options) {
31-
let configuration = options.configuration;
32-
if (!configuration && options.prod) {
33-
configuration = 'production';
34-
}
35-
36-
const overrides = { ...options };
37-
delete overrides.project;
38-
delete overrides.configuration;
39-
delete overrides.prod;
40-
41-
return this.runArchitectTarget({
42-
project: options.project,
43-
target: this.target,
44-
configuration,
45-
overrides
46-
}, options);
24+
public async run(options: ArchitectCommandOptions) {
25+
return this.runArchitectTarget(options);
4726
}
4827
}

packages/@angular/cli/commands/e2e.ts

+3-22
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import { CommandScope, Option } from '../models/command';
2-
import { ArchitectCommand } from '../models/architect-command';
2+
import { ArchitectCommand, ArchitectCommandOptions } from '../models/architect-command';
33

4-
export interface Options {
5-
project?: string;
6-
configuration?: string;
7-
prod: boolean;
8-
}
94

105
export default class E2eCommand extends ArchitectCommand {
116
public readonly name = 'e2e';
@@ -19,21 +14,7 @@ export default class E2eCommand extends ArchitectCommand {
1914
this.configurationOption
2015
];
2116

22-
public run(options: Options) {
23-
let configuration = options.configuration;
24-
if (!configuration && options.prod) {
25-
configuration = 'production';
26-
}
27-
28-
const overrides = { ...options };
29-
delete overrides.project;
30-
delete overrides.prod;
31-
32-
return this.runArchitectTarget({
33-
project: options.project,
34-
target: this.target,
35-
configuration,
36-
overrides
37-
}, options);
17+
public run(options: ArchitectCommandOptions) {
18+
return this.runArchitectTarget(options);
3819
}
3920
}
+3-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import { CommandScope, Option } from '../models/command';
2-
import { ArchitectCommand } from '../models/architect-command';
2+
import { ArchitectCommand, ArchitectCommandOptions } from '../models/architect-command';
33

4-
export interface Options {
5-
project?: string;
6-
configuration?: string;
7-
}
84

95
export default class LintCommand extends ArchitectCommand {
106
public readonly name = 'lint';
@@ -17,14 +13,7 @@ export default class LintCommand extends ArchitectCommand {
1713
this.configurationOption
1814
];
1915

20-
public async run(options: Options) {
21-
const overrides = { ...options };
22-
delete overrides.project;
23-
return this.runArchitectTarget({
24-
project: options.project,
25-
target: this.target,
26-
configuration: options.configuration,
27-
overrides
28-
}, options);
16+
public async run(options: ArchitectCommandOptions) {
17+
return this.runArchitectTarget(options);
2918
}
3019
}

packages/@angular/cli/commands/run.ts

+3-14
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import { CommandScope, Option } from '../models/command';
2-
import { ArchitectCommand } from '../models/architect-command';
2+
import { ArchitectCommand, ArchitectCommandOptions } from '../models/architect-command';
33

4-
export interface RunOptions {
5-
target: string;
6-
}
74

85
export default class RunCommand extends ArchitectCommand {
96
public readonly name = 'run';
@@ -14,17 +11,9 @@ export default class RunCommand extends ArchitectCommand {
1411
this.configurationOption
1512
];
1613

17-
public async run(options: RunOptions) {
14+
public async run(options: ArchitectCommandOptions) {
1815
if (options.target) {
19-
const [project, target, configuration] = options.target.split(':');
20-
const overrides = { ...options };
21-
delete overrides.target;
22-
return this.runArchitectTarget({
23-
project,
24-
target,
25-
configuration,
26-
overrides
27-
}, options);
16+
return this.runArchitectTarget(options);
2817
} else {
2918
throw new Error('Invalid architect target.');
3019
}
+4-24
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
import { CommandScope, Option } from '../models/command';
22
import { Version } from '../upgrade/version';
3-
import { ArchitectCommand } from '../models/architect-command';
3+
import { ArchitectCommand, ArchitectCommandOptions } from '../models/architect-command';
44

5-
export interface Options {
6-
project?: string;
7-
configuration?: string;
8-
prod: boolean;
9-
}
105

116
export default class ServeCommand extends ArchitectCommand {
127
public readonly name = 'serve';
@@ -19,29 +14,14 @@ export default class ServeCommand extends ArchitectCommand {
1914
this.configurationOption
2015
];
2116

22-
public validate(_options: Options) {
17+
public validate(_options: ArchitectCommandOptions) {
2318
// Check Angular and TypeScript versions.
2419
Version.assertCompatibleAngularVersion(this.project.root);
2520
Version.assertTypescriptVersion(this.project.root);
2621
return true;
2722
}
2823

29-
public async run(options: Options) {
30-
let configuration = options.configuration;
31-
if (!configuration && options.prod) {
32-
configuration = 'production';
33-
}
34-
35-
const overrides = { ...options };
36-
delete overrides.project;
37-
delete overrides.configuration;
38-
delete overrides.prod;
39-
40-
return this.runArchitectTarget({
41-
project: options.project,
42-
target: this.target,
43-
configuration,
44-
overrides
45-
}, options);
24+
public async run(options: ArchitectCommandOptions) {
25+
return this.runArchitectTarget(options);
4626
}
4727
}
+3-23
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import { CommandScope, Option } from '../models/command';
2-
import { ArchitectCommand } from '../models/architect-command';
2+
import { ArchitectCommand, ArchitectCommandOptions } from '../models/architect-command';
33

4-
export interface Options {
5-
project?: string;
6-
configuration?: string;
7-
prod: boolean;
8-
}
94

105
export default class TestCommand extends ArchitectCommand {
116
public readonly name = 'test';
@@ -19,22 +14,7 @@ export default class TestCommand extends ArchitectCommand {
1914
this.configurationOption
2015
];
2116

22-
public async run(options: Options) {
23-
let configuration = options.configuration;
24-
if (!configuration && options.prod) {
25-
configuration = 'production';
26-
}
27-
28-
const overrides = { ...options };
29-
delete overrides.project;
30-
delete overrides.configuration;
31-
delete overrides.prod;
32-
33-
return this.runArchitectTarget({
34-
project: options.project,
35-
target: this.target,
36-
configuration,
37-
overrides
38-
}, options);
17+
public async run(options: ArchitectCommandOptions) {
18+
return this.runArchitectTarget(options);
3919
}
4020
}
+3-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import { CommandScope, Option } from '../models/command';
2-
import { ArchitectCommand } from '../models/architect-command';
2+
import { ArchitectCommand, ArchitectCommandOptions } from '../models/architect-command';
33

4-
export interface Options {
5-
project?: string;
6-
configuration?: string;
7-
}
84

95
export default class Xi18nCommand extends ArchitectCommand {
106
public readonly name = 'xi18n';
@@ -16,14 +12,7 @@ export default class Xi18nCommand extends ArchitectCommand {
1612
this.configurationOption
1713
];
1814

19-
public async run(options: Options) {
20-
const overrides = { ...options };
21-
delete overrides.project;
22-
return this.runArchitectTarget({
23-
project: options.project,
24-
target: this.target,
25-
configuration: options.configuration,
26-
overrides
27-
}, options);
15+
public async run(options: ArchitectCommandOptions) {
16+
return this.runArchitectTarget(options);
2817
}
2918
}

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

+65-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { experimental, schema, strings } from '@angular-devkit/core';
1+
import { JsonObject, experimental, schema, strings } from '@angular-devkit/core';
22
import { NodeJsSyncHost, createConsoleLogger } from '@angular-devkit/core/node';
33
import {
44
Architect, BuilderDescription, BuildEvent,
@@ -11,7 +11,20 @@ import { concatMap, map, tap, toArray } from 'rxjs/operators';
1111
import { WorkspaceLoader } from '../models/workspace-loader';
1212

1313

14-
export abstract class ArchitectCommand<T = any> extends Command<T> {
14+
export interface ProjectAndConfigurationOptions {
15+
project?: string;
16+
configuration?: string;
17+
prod: boolean;
18+
}
19+
20+
export interface TargetOptions {
21+
target?: string;
22+
}
23+
24+
export type ArchitectCommandOptions = ProjectAndConfigurationOptions & TargetOptions & JsonObject;
25+
26+
export abstract class ArchitectCommand extends Command<ArchitectCommandOptions> {
27+
1528
private _host = new NodeJsSyncHost();
1629
private _architect: Architect;
1730
private _workspace: experimental.workspace.Workspace;
@@ -30,18 +43,19 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
3043

3144
target: string | undefined;
3245

33-
public async initialize(options: any): Promise<void> {
46+
public async initialize(options: ArchitectCommandOptions): Promise<void> {
3447
return this._loadWorkspaceAndArchitect().pipe(
3548
concatMap(() => {
3649
let targetSpec: TargetSpecifier;
50+
const { project } = this._splitOptionsObject(options);
51+
3752
if (options.project) {
3853
targetSpec = {
39-
project: options.project,
54+
project: project,
4055
target: this.target
4156
};
4257
} else if (options.target) {
43-
const [project, target] = options.target.split(':');
44-
targetSpec = { project, target };
58+
targetSpec = { project, target: options.target };
4559
} else if (this.target) {
4660
const projects = this.getProjectNamesByTarget(this.target);
4761

@@ -70,13 +84,10 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
7084
.then(() => { });
7185
}
7286

73-
public validate(options: any) {
87+
public validate(options: ArchitectCommandOptions) {
7488
if (!options.project && this.target) {
7589
const projectNames = this.getProjectNamesByTarget(this.target);
76-
const overrides = { ...options };
77-
delete overrides.project;
78-
delete overrides.configuration;
79-
delete overrides.prod;
90+
const { overrides } = this._splitOptionsObject(options);
8091
if (projectNames.length > 1 && Object.keys(overrides).length > 0) {
8192
throw new Error('Architect commands with multiple targets cannot specify overrides.'
8293
+ `'${this.target}' would be run on the following projects: ${projectNames.join()}`);
@@ -146,10 +157,15 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
146157
aliases: ['c']
147158
};
148159

149-
protected async runArchitectTarget(
150-
targetSpec: TargetSpecifier,
151-
commandOptions: T,
152-
): Promise<number> {
160+
protected async runArchitectTarget(options: ArchitectCommandOptions): Promise<number> {
161+
const { project, configuration, overrides } = this._splitOptionsObject(options);
162+
const targetSpec = {
163+
project,
164+
target: options.target || this.target,
165+
configuration,
166+
overrides,
167+
};
168+
153169
const runSingleTarget = (targetSpec: TargetSpecifier) => this._architect.run(
154170
this._architect.getBuilderConfiguration(targetSpec),
155171
{ logger: this._logger }
@@ -174,7 +190,7 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
174190
e.errors.forEach(schemaError => {
175191
if (schemaError.keyword === 'additionalProperties') {
176192
const unknownProperty = schemaError.params.additionalProperty;
177-
if (unknownProperty in commandOptions) {
193+
if (unknownProperty in options) {
178194
const dashes = unknownProperty.length === 1 ? '-' : '--';
179195
this.logger.fatal(`Unknown option: '${dashes}${unknownProperty}'`);
180196

@@ -229,4 +245,37 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
229245
tap((architect: Architect) => this._architect = architect),
230246
);
231247
}
248+
249+
private _splitOptionsObject(options: ArchitectCommandOptions): {
250+
project?: string,
251+
configuration?: string,
252+
overrides: JsonObject,
253+
} {
254+
let project, target, configuration, overrides;
255+
256+
if (options.target) {
257+
[project, target, configuration] = options.target.split(':');
258+
259+
overrides = { ...options };
260+
delete overrides.target;
261+
} else {
262+
project = options.project;
263+
configuration = options.configuration;
264+
if (!configuration && options.prod) {
265+
configuration = 'production';
266+
}
267+
268+
overrides = { ...options };
269+
270+
delete overrides.configuration;
271+
delete overrides.prod;
272+
delete overrides.project;
273+
}
274+
275+
return {
276+
project,
277+
configuration,
278+
overrides
279+
};
280+
}
232281
}

0 commit comments

Comments
 (0)