1
- import { experimental , schema , strings } from '@angular-devkit/core' ;
1
+ import { JsonObject , experimental , schema , strings } from '@angular-devkit/core' ;
2
2
import { NodeJsSyncHost , createConsoleLogger } from '@angular-devkit/core/node' ;
3
3
import {
4
4
Architect , BuilderDescription , BuildEvent ,
@@ -11,7 +11,20 @@ import { concatMap, map, tap, toArray } from 'rxjs/operators';
11
11
import { WorkspaceLoader } from '../models/workspace-loader' ;
12
12
13
13
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
+
15
28
private _host = new NodeJsSyncHost ( ) ;
16
29
private _architect : Architect ;
17
30
private _workspace : experimental . workspace . Workspace ;
@@ -30,18 +43,19 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
30
43
31
44
target : string | undefined ;
32
45
33
- public async initialize ( options : any ) : Promise < void > {
46
+ public async initialize ( options : ArchitectCommandOptions ) : Promise < void > {
34
47
return this . _loadWorkspaceAndArchitect ( ) . pipe (
35
48
concatMap ( ( ) => {
36
49
let targetSpec : TargetSpecifier ;
50
+ const { project } = this . _splitOptionsObject ( options ) ;
51
+
37
52
if ( options . project ) {
38
53
targetSpec = {
39
- project : options . project ,
54
+ project : project ,
40
55
target : this . target
41
56
} ;
42
57
} else if ( options . target ) {
43
- const [ project , target ] = options . target . split ( ':' ) ;
44
- targetSpec = { project, target } ;
58
+ targetSpec = { project, target : options . target } ;
45
59
} else if ( this . target ) {
46
60
const projects = this . getProjectNamesByTarget ( this . target ) ;
47
61
@@ -70,13 +84,10 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
70
84
. then ( ( ) => { } ) ;
71
85
}
72
86
73
- public validate ( options : any ) {
87
+ public validate ( options : ArchitectCommandOptions ) {
74
88
if ( ! options . project && this . target ) {
75
89
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 ) ;
80
91
if ( projectNames . length > 1 && Object . keys ( overrides ) . length > 0 ) {
81
92
throw new Error ( 'Architect commands with multiple targets cannot specify overrides.'
82
93
+ `'${ this . target } ' would be run on the following projects: ${ projectNames . join ( ) } ` ) ;
@@ -146,10 +157,15 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
146
157
aliases : [ 'c' ]
147
158
} ;
148
159
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
+
153
169
const runSingleTarget = ( targetSpec : TargetSpecifier ) => this . _architect . run (
154
170
this . _architect . getBuilderConfiguration ( targetSpec ) ,
155
171
{ logger : this . _logger }
@@ -174,7 +190,7 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
174
190
e . errors . forEach ( schemaError => {
175
191
if ( schemaError . keyword === 'additionalProperties' ) {
176
192
const unknownProperty = schemaError . params . additionalProperty ;
177
- if ( unknownProperty in commandOptions ) {
193
+ if ( unknownProperty in options ) {
178
194
const dashes = unknownProperty . length === 1 ? '-' : '--' ;
179
195
this . logger . fatal ( `Unknown option: '${ dashes } ${ unknownProperty } '` ) ;
180
196
@@ -229,4 +245,37 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
229
245
tap ( ( architect : Architect ) => this . _architect = architect ) ,
230
246
) ;
231
247
}
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
+ }
232
281
}
0 commit comments