Skip to content

Commit db1653b

Browse files
filipesilvahansl
authored andcommitted
feat(@angular-devkit/architect-cli): add package
1 parent 435648e commit db1653b

3 files changed

Lines changed: 157 additions & 1 deletion

File tree

bin/architect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111

1212
require('../lib/bootstrap-local');
1313
const packages = require('../lib/packages').packages;
14-
require(packages['@angular-devkit/architect'].bin['architect']);
14+
require(packages['@angular-devkit/architect-cli'].bin['architect']);
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#!/usr/bin/env node
2+
/**
3+
* @license
4+
* Copyright Google Inc. All Rights Reserved.
5+
*
6+
* Use of this source code is governed by an MIT-style license that can be
7+
* found in the LICENSE file at https://angular.io/license
8+
*/
9+
10+
import { Architect, Workspace } from '@angular-devkit/architect';
11+
import { dirname, normalize, tags } from '@angular-devkit/core';
12+
import { NodeJsSyncHost, createConsoleLogger } from '@angular-devkit/core/node';
13+
import { existsSync, readFileSync } from 'fs';
14+
import * as minimist from 'minimist';
15+
import * as path from 'path';
16+
import { _throw } from 'rxjs/observable/throw';
17+
import { concatMap } from 'rxjs/operators';
18+
19+
20+
function findUp(names: string | string[], from: string) {
21+
if (!Array.isArray(names)) {
22+
names = [names];
23+
}
24+
const root = path.parse(from).root;
25+
26+
let currentDir = from;
27+
while (currentDir && currentDir !== root) {
28+
for (const name of names) {
29+
const p = path.join(currentDir, name);
30+
if (existsSync(p)) {
31+
return p;
32+
}
33+
}
34+
35+
currentDir = path.dirname(currentDir);
36+
}
37+
38+
return null;
39+
}
40+
41+
/**
42+
* Show usage of the CLI tool, and exit the process.
43+
*/
44+
function usage(exitCode = 0): never {
45+
logger.info(tags.stripIndent`
46+
architect [project][:target][:configuration] [options, ...]
47+
48+
Run a project target.
49+
If project/target/configuration are not specified, the workspace defaults will be used.
50+
51+
Options:
52+
--help Show available options for project target.
53+
Shows this message instead when ran without the run argument.
54+
55+
56+
Any additional option is passed the target, overriding existing options.
57+
`);
58+
59+
process.exit(exitCode);
60+
throw 0; // The node typing sometimes don't have a never type for process.exit().
61+
}
62+
63+
/** Parse the command line. */
64+
const argv = minimist(process.argv.slice(2), { boolean: ['help'] });
65+
66+
/** Create the DevKit Logger used through the CLI. */
67+
const logger = createConsoleLogger(argv['verbose']);
68+
69+
// Check the target.
70+
const targetStr = argv._.shift();
71+
if (!targetStr && argv.help) {
72+
// Show architect usage if there's no target.
73+
usage();
74+
}
75+
76+
// Split a target into its parts.
77+
let project: string, targetName: string, configuration: string;
78+
if (targetStr) {
79+
[project, targetName, configuration] = targetStr.split(':');
80+
}
81+
82+
// Load workspace configuration file.
83+
const currentPath = process.cwd();
84+
const configFileName = '.architect.json';
85+
const configFilePath = findUp([configFileName], currentPath);
86+
87+
if (!configFilePath) {
88+
logger.fatal(`Workspace configuration file (${configFileName}) cannot be found in `
89+
+ `'${currentPath}' or in parent directories.`);
90+
process.exit(3);
91+
throw 3; // TypeScript doesn't know that process.exit() never returns.
92+
}
93+
94+
const workspacePath = dirname(normalize(configFilePath));
95+
const configContent = readFileSync(configFilePath, 'utf-8');
96+
const configJson = JSON.parse(configContent) as Workspace;
97+
98+
const host = new NodeJsSyncHost();
99+
const architect = new Architect(workspacePath, host);
100+
architect.loadWorkspaceFromJson(configJson).pipe(
101+
concatMap(() => {
102+
const overrides = { ...argv };
103+
delete overrides['help'];
104+
delete overrides['_'];
105+
106+
const targetOptions = {
107+
project,
108+
target: targetName,
109+
configuration,
110+
overrides,
111+
};
112+
const target = architect.getTarget(targetOptions);
113+
114+
// TODO: better logging of what's happening.
115+
if (argv.help) {
116+
// TODO: add target help
117+
return _throw('Target help NYI.');
118+
// architect.help(targetOptions, logger);
119+
} else {
120+
return architect.run(target, { logger });
121+
}
122+
}),
123+
).subscribe({
124+
next: (event => logger.info(JSON.stringify(event, null, 2))),
125+
complete: () => process.exit(0),
126+
error: (err: Error) => {
127+
logger.fatal(err.message);
128+
if (err.stack) {
129+
logger.fatal(err.stack);
130+
}
131+
process.exit(1);
132+
},
133+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "@angular-devkit/architect-cli",
3+
"version": "0.0.0",
4+
"description": "Angular Architect CLI",
5+
"bin": {
6+
"architect": "./bin/architect.js"
7+
},
8+
"scripts": {
9+
"preinstall": "echo DO NOT INSTALL THIS PROJECT, ONLY THE ROOT PROJECT. && exit 1"
10+
},
11+
"keywords": [
12+
"build system",
13+
"build facade",
14+
"build",
15+
"tooling"
16+
],
17+
"dependencies": {
18+
"@angular-devkit/core": "0.0.0",
19+
"@angular-devkit/architect": "0.0.0",
20+
"minimist": "^1.2.0",
21+
"rxjs": "^5.5.2"
22+
}
23+
}

0 commit comments

Comments
 (0)