Skip to content

Commit 685d4d0

Browse files
hanslKeen Yee Liau
authored and
Keen Yee Liau
committed
feat(@angular-devkit/architect): add generic architect builders
Four builders were added; - true, always succeed - false, always fails - concat, runs all targets or builders in succession - allOf, runs all targets or builders in parallel
1 parent 79a6988 commit 685d4d0

File tree

8 files changed

+217
-2
lines changed

8 files changed

+217
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import { json } from '@angular-devkit/core';
9+
import { EMPTY, from, of } from 'rxjs';
10+
import { map, mergeMap } from 'rxjs/operators';
11+
import { BuilderOutput, BuilderRun, createBuilder } from '../src/index2';
12+
import { Schema as OperatorSchema } from './operator-schema';
13+
14+
export default createBuilder<json.JsonObject & OperatorSchema>((options, context) => {
15+
const allRuns: Promise<[number, BuilderRun]>[] = [];
16+
17+
context.reportProgress(0,
18+
(options.targets ? options.targets.length : 0)
19+
+ (options.builders ? options.builders.length : 0),
20+
);
21+
22+
if (options.targets) {
23+
allRuns.push(...options.targets.map(({ target: targetStr, overrides }, i) => {
24+
const [project, target, configuration] = targetStr.split(/:/g, 3);
25+
26+
return context.scheduleTarget({ project, target, configuration }, overrides || {})
27+
.then(run => [i, run] as [number, BuilderRun]);
28+
}));
29+
}
30+
31+
if (options.builders) {
32+
allRuns.push(...options.builders.map(({ builder, options }, i) => {
33+
return context.scheduleBuilder(builder, options || {})
34+
.then(run => [i, run] as [number, BuilderRun]);
35+
}));
36+
}
37+
38+
const allResults: (BuilderOutput | null)[] = allRuns.map(() => null);
39+
let n = 0;
40+
context.reportProgress(n++, allRuns.length);
41+
42+
return from(allRuns).pipe(
43+
mergeMap(runPromise => from(runPromise)),
44+
mergeMap(([i, run]: [number, BuilderRun]) => run.output.pipe(map(output => [i, output]))),
45+
mergeMap<[number, BuilderOutput], BuilderOutput>(([i, output]) => {
46+
allResults[i] = output;
47+
context.reportProgress(n++, allRuns.length);
48+
49+
if (allResults.some(x => x === null)) {
50+
// Some builders aren't done running yet.
51+
return EMPTY;
52+
} else {
53+
return of({
54+
success: allResults.every(x => x ? x.success : false),
55+
});
56+
}
57+
}),
58+
);
59+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"$schema": "../src/builders-schema.json",
3+
"builders": {
4+
"true": {
5+
"implementation": "./true",
6+
"schema": "./noop-schema.json",
7+
"description": "Always succeed."
8+
},
9+
"false": {
10+
"implementation": "./false",
11+
"schema": "./noop-schema.json",
12+
"description": "Always fails."
13+
},
14+
"allOf": {
15+
"implementation": "./all-of",
16+
"schema": "./operator-schema.json",
17+
"description": "A builder that executes many builders in parallel, and succeed if both succeeds."
18+
},
19+
"concat": {
20+
"implementation": "./concat",
21+
"schema": "./operator-schema.json",
22+
"description": "A builder that executes many builders one after the other, and stops when one fail. It will succeed if all builders succeeds (and return the last output)"
23+
}
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import { json } from '@angular-devkit/core';
9+
import { from, of } from 'rxjs';
10+
import { concatMap, first, last, map, switchMap } from 'rxjs/operators';
11+
import { BuilderOutput, BuilderRun, createBuilder } from '../src/index2';
12+
import { Schema as OperatorSchema } from './operator-schema';
13+
14+
export default createBuilder<json.JsonObject & OperatorSchema>((options, context) => {
15+
const allRuns: (() => Promise<BuilderRun>)[] = [];
16+
17+
context.reportProgress(0,
18+
(options.targets ? options.targets.length : 0)
19+
+ (options.builders ? options.builders.length : 0),
20+
);
21+
22+
if (options.targets) {
23+
allRuns.push(...options.targets.map(({ target: targetStr, overrides }) => {
24+
const [project, target, configuration] = targetStr.split(/:/g, 3);
25+
26+
return () => context.scheduleTarget({ project, target, configuration }, overrides || {});
27+
}));
28+
}
29+
30+
if (options.builders) {
31+
allRuns.push(...options.builders.map(({ builder, options }) => {
32+
return () => context.scheduleBuilder(builder, options || {});
33+
}));
34+
}
35+
36+
let stop: BuilderOutput | null = null;
37+
let i = 0;
38+
context.reportProgress(i++, allRuns.length);
39+
40+
return from(allRuns).pipe(
41+
concatMap(fn => stop ? of(null) : from(fn()).pipe(
42+
switchMap(run => run === null ? of(null) : run.output.pipe(first())),
43+
)),
44+
map(output => {
45+
context.reportProgress(i++, allRuns.length);
46+
if (output === null || stop !== null) {
47+
return stop || { success: false };
48+
} else if (output.success === false) {
49+
return stop = output;
50+
} else {
51+
return output;
52+
}
53+
}),
54+
last(),
55+
);
56+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import { of } from 'rxjs';
9+
import { createBuilder } from '../src/index2';
10+
11+
export default createBuilder(() => of({
12+
success: false,
13+
error: 'False builder always errors.',
14+
}));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"$schema": "http://json-schema.org/schema",
3+
"type": "object"
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"$schema": "http://json-schema.org/schema",
3+
"description": "All input types of builders that perform operations on one or multiple sub-builders.",
4+
"type": "object",
5+
"properties": {
6+
"builders": {
7+
"type": "array",
8+
"items": {
9+
"type": "object",
10+
"properties": {
11+
"builder": {
12+
"type": "string",
13+
"pattern": ".*:.*"
14+
},
15+
"options": {
16+
"type": "object"
17+
}
18+
},
19+
"required": [
20+
"builder"
21+
]
22+
},
23+
"minItems": 1
24+
},
25+
"targets": {
26+
"type": "array",
27+
"items": {
28+
"type": "object",
29+
"properties": {
30+
"target": {
31+
"type": "string",
32+
"pattern": ".*:.*"
33+
},
34+
"overrides": {
35+
"type": "object"
36+
}
37+
},
38+
"required": [
39+
"target"
40+
]
41+
},
42+
"minItems": 1
43+
}
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import { of } from 'rxjs';
9+
import { createBuilder } from '../src/index2';
10+
11+
export default createBuilder(() => of({ success: true }));

packages/angular_devkit/architect/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
"dependencies": {
88
"@angular-devkit/core": "0.0.0",
99
"rxjs": "6.3.3"
10-
}
11-
}
10+
},
11+
"builders": "./builders/builders.json"
12+
}

0 commit comments

Comments
 (0)