diff --git a/README.md b/README.md
index 0ce6aab3d..95ee2d43c 100644
--- a/README.md
+++ b/README.md
@@ -14,3 +14,22 @@ npm install git+https://github.com/angular/angular-devkit-architect-cli-builds.g
```
----
+# Architect CLI
+
+This package contains the executable for running an [Architect Builder](/packages/angular_devkit/architect/README.md).
+
+# Usage
+
+```
+architect [project][:target][:configuration] [options, ...]
+
+Run a project target.
+If project/target/configuration are not specified, the workspace defaults will be used.
+
+Options:
+ --help Show available options for project target.
+ Shows this message instead when ran without the run argument.
+
+
+Any additional option is passed the target, overriding existing options.
+```
diff --git a/bin/architect.d.ts b/bin/architect.d.ts
index 980409b99..2b1611b75 100644
--- a/bin/architect.d.ts
+++ b/bin/architect.d.ts
@@ -1,2 +1,9 @@
#!/usr/bin/env node
-import 'symbol-observable';
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+export {};
diff --git a/bin/architect.js b/bin/architect.js
index 5d4d6b704..83bb26ecf 100644
--- a/bin/architect.js
+++ b/bin/architect.js
@@ -1,17 +1,45 @@
#!/usr/bin/env node
"use strict";
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
Object.defineProperty(exports, "__esModule", { value: true });
-require("symbol-observable");
-// symbol polyfill must go first
-// tslint:disable-next-line:ordered-imports import-groups
const architect_1 = require("@angular-devkit/architect");
+const node_1 = require("@angular-devkit/architect/node");
const core_1 = require("@angular-devkit/core");
-const node_1 = require("@angular-devkit/core/node");
+const node_2 = require("@angular-devkit/core/node");
+const ansiColors = __importStar(require("ansi-colors"));
const fs_1 = require("fs");
-const minimist = require("minimist");
-const path = require("path");
-const rxjs_1 = require("rxjs");
+const minimist_1 = __importDefault(require("minimist"));
+const path = __importStar(require("path"));
const operators_1 = require("rxjs/operators");
+const progress_1 = require("../src/progress");
function findUp(names, from) {
if (!Array.isArray(names)) {
names = [names];
@@ -32,7 +60,7 @@ function findUp(names, from) {
/**
* Show usage of the CLI tool, and exit the process.
*/
-function usage(exitCode = 0) {
+function usage(logger, exitCode = 0) {
logger.info(core_1.tags.stripIndent `
architect [project][:target][:configuration] [options, ...]
@@ -46,74 +74,128 @@ function usage(exitCode = 0) {
Any additional option is passed the target, overriding existing options.
`);
- process.exit(exitCode);
- throw 0; // The node typing sometimes don't have a never type for process.exit().
+ return process.exit(exitCode);
}
-/** Parse the command line. */
-const argv = minimist(process.argv.slice(2), { boolean: ['help'] });
-/** Create the DevKit Logger used through the CLI. */
-const logger = node_1.createConsoleLogger(argv['verbose']);
-// Check the target.
-const targetStr = argv._.shift();
-if (!targetStr && argv.help) {
- // Show architect usage if there's no target.
- usage();
+function _targetStringFromTarget({ project, target, configuration }) {
+ return `${project}:${target}${configuration !== undefined ? ':' + configuration : ''}`;
}
-// Split a target into its parts.
-let project, targetName, configuration;
-if (targetStr) {
- [project, targetName, configuration] = targetStr.split(':');
-}
-// Load workspace configuration file.
-const currentPath = process.cwd();
-const configFileNames = [
- 'angular.json',
- '.angular.json',
- 'workspace.json',
- '.workspace.json',
-];
-const configFilePath = findUp(configFileNames, currentPath);
-if (!configFilePath) {
- logger.fatal(`Workspace configuration file (${configFileNames.join(', ')}) cannot be found in `
- + `'${currentPath}' or in parent directories.`);
- process.exit(3);
- throw 3; // TypeScript doesn't know that process.exit() never returns.
+// Create a separate instance to prevent unintended global changes to the color configuration
+// Create function is not defined in the typings. See: https://github.com/doowb/ansi-colors/pull/44
+const colors = ansiColors.create();
+async function _executeTarget(parentLogger, workspace, root, argv, registry) {
+ const architectHost = new node_1.WorkspaceNodeModulesArchitectHost(workspace, root);
+ const architect = new architect_1.Architect(architectHost, registry);
+ // Split a target into its parts.
+ const targetStr = argv._.shift() || '';
+ const [project, target, configuration] = targetStr.split(':');
+ const targetSpec = { project, target, configuration };
+ delete argv['help'];
+ const logger = new core_1.logging.Logger('jobs');
+ const logs = [];
+ logger.subscribe((entry) => logs.push({ ...entry, message: `${entry.name}: ` + entry.message }));
+ const { _, ...options } = argv;
+ const run = await architect.scheduleTarget(targetSpec, options, { logger });
+ const bars = new progress_1.MultiProgressBar(':name :bar (:current/:total) :status');
+ run.progress.subscribe((update) => {
+ const data = bars.get(update.id) || {
+ id: update.id,
+ builder: update.builder,
+ target: update.target,
+ status: update.status || '',
+ name: ((update.target ? _targetStringFromTarget(update.target) : update.builder.name) +
+ ' '.repeat(80)).substr(0, 40),
+ };
+ if (update.status !== undefined) {
+ data.status = update.status;
+ }
+ switch (update.state) {
+ case architect_1.BuilderProgressState.Error:
+ data.status = 'Error: ' + update.error;
+ bars.update(update.id, data);
+ break;
+ case architect_1.BuilderProgressState.Stopped:
+ data.status = 'Done.';
+ bars.complete(update.id);
+ bars.update(update.id, data, update.total, update.total);
+ break;
+ case architect_1.BuilderProgressState.Waiting:
+ bars.update(update.id, data);
+ break;
+ case architect_1.BuilderProgressState.Running:
+ bars.update(update.id, data, update.current, update.total);
+ break;
+ }
+ bars.render();
+ });
+ // Wait for full completion of the builder.
+ try {
+ const { success } = await run.output
+ .pipe(operators_1.tap((result) => {
+ if (result.success) {
+ parentLogger.info(colors.green('SUCCESS'));
+ }
+ else {
+ parentLogger.info(colors.red('FAILURE'));
+ }
+ parentLogger.info('Result: ' + JSON.stringify({ ...result, info: undefined }, null, 4));
+ parentLogger.info('\nLogs:');
+ logs.forEach((l) => parentLogger.next(l));
+ logs.splice(0);
+ }))
+ .toPromise();
+ await run.stop();
+ bars.terminate();
+ return success ? 0 : 1;
+ }
+ catch (err) {
+ parentLogger.info(colors.red('ERROR'));
+ parentLogger.info('\nLogs:');
+ logs.forEach((l) => parentLogger.next(l));
+ parentLogger.fatal('Exception:');
+ parentLogger.fatal(err.stack);
+ return 2;
+ }
}
-const root = core_1.dirname(core_1.normalize(configFilePath));
-const configContent = fs_1.readFileSync(configFilePath, 'utf-8');
-const workspaceJson = JSON.parse(configContent);
-const host = new node_1.NodeJsSyncHost();
-const workspace = new core_1.experimental.workspace.Workspace(root, host);
-let lastBuildEvent = { success: true };
-workspace.loadWorkspaceFromJson(workspaceJson).pipe(operators_1.concatMap(ws => new architect_1.Architect(ws).loadArchitect()), operators_1.concatMap(architect => {
- const overrides = Object.assign({}, argv);
- delete overrides['help'];
- delete overrides['_'];
- const targetSpec = {
- project,
- target: targetName,
- configuration,
- overrides,
- };
- // TODO: better logging of what's happening.
- if (argv.help) {
- // TODO: add target help
- return rxjs_1.throwError('Target help NYI.');
- // architect.help(targetOptions, logger);
+async function main(args) {
+ /** Parse the command line. */
+ const argv = minimist_1.default(args, { boolean: ['help'] });
+ /** Create the DevKit Logger used through the CLI. */
+ const logger = node_2.createConsoleLogger(argv['verbose'], process.stdout, process.stderr, {
+ info: (s) => s,
+ debug: (s) => s,
+ warn: (s) => colors.bold.yellow(s),
+ error: (s) => colors.bold.red(s),
+ fatal: (s) => colors.bold.red(s),
+ });
+ // Check the target.
+ const targetStr = argv._[0] || '';
+ if (!targetStr || argv.help) {
+ // Show architect usage if there's no target.
+ usage(logger);
}
- else {
- const builderConfig = architect.getBuilderConfiguration(targetSpec);
- return architect.run(builderConfig, { logger });
+ // Load workspace configuration file.
+ const currentPath = process.cwd();
+ const configFileNames = ['angular.json', '.angular.json', 'workspace.json', '.workspace.json'];
+ const configFilePath = findUp(configFileNames, currentPath);
+ if (!configFilePath) {
+ logger.fatal(`Workspace configuration file (${configFileNames.join(', ')}) cannot be found in ` +
+ `'${currentPath}' or in parent directories.`);
+ return 3;
}
-})).subscribe({
- next: (buildEvent => lastBuildEvent = buildEvent),
- complete: () => process.exit(lastBuildEvent.success ? 0 : 1),
- error: (err) => {
- logger.fatal(err.message);
- if (err.stack) {
- logger.fatal(err.stack);
- }
- process.exit(1);
- },
+ const root = path.dirname(configFilePath);
+ const registry = new core_1.schema.CoreSchemaRegistry();
+ registry.addPostTransform(core_1.schema.transforms.addUndefinedDefaults);
+ // Show usage of deprecated options
+ registry.useXDeprecatedProvider((msg) => logger.warn(msg));
+ const { workspace } = await core_1.workspaces.readWorkspace(configFilePath, core_1.workspaces.createWorkspaceHost(new node_2.NodeJsSyncHost()));
+ // Clear the console.
+ process.stdout.write('\u001Bc');
+ return await _executeTarget(logger, workspace, root, argv, registry);
+}
+main(process.argv.slice(2)).then((code) => {
+ process.exit(code);
+}, (err) => {
+ // eslint-disable-next-line no-console
+ console.error('Error: ' + err.stack || err.message || err);
+ process.exit(-1);
});
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJjaGl0ZWN0LmpzIiwic291cmNlUm9vdCI6Ii4vIiwic291cmNlcyI6WyJwYWNrYWdlcy9hbmd1bGFyX2RldmtpdC9hcmNoaXRlY3RfY2xpL2Jpbi9hcmNoaXRlY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBU0EsNkJBQTJCO0FBQzNCLGdDQUFnQztBQUNoQyx5REFBeUQ7QUFDekQseURBQXNEO0FBQ3RELCtDQUE4RTtBQUM5RSxvREFBZ0Y7QUFDaEYsMkJBQThDO0FBQzlDLHFDQUFxQztBQUNyQyw2QkFBNkI7QUFDN0IsK0JBQWtDO0FBQ2xDLDhDQUEyQztBQUczQyxTQUFTLE1BQU0sQ0FBQyxLQUF3QixFQUFFLElBQVk7SUFDcEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDekIsS0FBSyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDakI7SUFDRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQztJQUVuQyxJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDdEIsT0FBTyxVQUFVLElBQUksVUFBVSxLQUFLLElBQUksRUFBRTtRQUN4QyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRTtZQUN4QixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN0QyxJQUFJLGVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDakIsT0FBTyxDQUFDLENBQUM7YUFDVjtTQUNGO1FBRUQsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7S0FDdkM7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsS0FBSyxDQUFDLFFBQVEsR0FBRyxDQUFDO0lBQ3pCLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBSSxDQUFDLFdBQVcs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UUFDeEIsT0FBTyxpQkFBVSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDdEMseUNBQXlDO0tBQzFDO1NBQU07UUFDTCxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsdUJBQXVCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFcEUsT0FBTyxTQUFTLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7S0FDakQ7QUFDSCxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsQ0FBQztJQUNWLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsY0FBYyxHQUFHLFVBQVUsQ0FBQztJQUNqRCxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM1RCxLQUFLLEVBQUUsQ0FBQyxHQUFVLEVBQUUsRUFBRTtRQUNwQixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxQixJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUU7WUFDYixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN6QjtRQUNELE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEIsQ0FBQztDQUNGLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcbi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0ICdzeW1ib2wtb2JzZXJ2YWJsZSc7XG4vLyBzeW1ib2wgcG9seWZpbGwgbXVzdCBnbyBmaXJzdFxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm9yZGVyZWQtaW1wb3J0cyBpbXBvcnQtZ3JvdXBzXG5pbXBvcnQgeyBBcmNoaXRlY3QgfSBmcm9tICdAYW5ndWxhci1kZXZraXQvYXJjaGl0ZWN0JztcbmltcG9ydCB7IGRpcm5hbWUsIGV4cGVyaW1lbnRhbCwgbm9ybWFsaXplLCB0YWdzIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L2NvcmUnO1xuaW1wb3J0IHsgTm9kZUpzU3luY0hvc3QsIGNyZWF0ZUNvbnNvbGVMb2dnZXIgfSBmcm9tICdAYW5ndWxhci1kZXZraXQvY29yZS9ub2RlJztcbmltcG9ydCB7IGV4aXN0c1N5bmMsIHJlYWRGaWxlU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIG1pbmltaXN0IGZyb20gJ21pbmltaXN0JztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjb25jYXRNYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cblxuZnVuY3Rpb24gZmluZFVwKG5hbWVzOiBzdHJpbmcgfCBzdHJpbmdbXSwgZnJvbTogc3RyaW5nKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShuYW1lcykpIHtcbiAgICBuYW1lcyA9IFtuYW1lc107XG4gIH1cbiAgY29uc3Qgcm9vdCA9IHBhdGgucGFyc2UoZnJvbSkucm9vdDtcblxuICBsZXQgY3VycmVudERpciA9IGZyb207XG4gIHdoaWxlIChjdXJyZW50RGlyICYmIGN1cnJlbnREaXIgIT09IHJvb3QpIHtcbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgbmFtZXMpIHtcbiAgICAgIGNvbnN0IHAgPSBwYXRoLmpvaW4oY3VycmVudERpciwgbmFtZSk7XG4gICAgICBpZiAoZXhpc3RzU3luYyhwKSkge1xuICAgICAgICByZXR1cm4gcDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjdXJyZW50RGlyID0gcGF0aC5kaXJuYW1lKGN1cnJlbnREaXIpO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogU2hvdyB1c2FnZSBvZiB0aGUgQ0xJIHRvb2wsIGFuZCBleGl0IHRoZSBwcm9jZXNzLlxuICovXG5mdW5jdGlvbiB1c2FnZShleGl0Q29kZSA9IDApOiBuZXZlciB7XG4gIGxvZ2dlci5pbmZvKHRhZ3Muc3RyaXBJbmRlbnRgXG4gICAgYXJjaGl0ZWN0IFtwcm9qZWN0XVs6dGFyZ2V0XVs6Y29uZmlndXJhdGlvbl0gW29wdGlvbnMsIC4uLl1cblxuICAgIFJ1biBhIHByb2plY3QgdGFyZ2V0LlxuICAgIElmIHByb2plY3QvdGFyZ2V0L2NvbmZpZ3VyYXRpb24gYXJlIG5vdCBzcGVjaWZpZWQsIHRoZSB3b3Jrc3BhY2UgZGVmYXVsdHMgd2lsbCBiZSB1c2VkLlxuXG4gICAgT3B0aW9uczpcbiAgICAgICAgLS1oZWxwICAgICAgICAgICAgICBTaG93IGF2YWlsYWJsZSBvcHRpb25zIGZvciBwcm9qZWN0IHRhcmdldC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaG93cyB0aGlzIG1lc3NhZ2UgaW5zdGVhZCB3aGVuIHJhbiB3aXRob3V0IHRoZSBydW4gYXJndW1lbnQuXG5cblxuICAgIEFueSBhZGRpdGlvbmFsIG9wdGlvbiBpcyBwYXNzZWQgdGhlIHRhcmdldCwgb3ZlcnJpZGluZyBleGlzdGluZyBvcHRpb25zLlxuICBgKTtcblxuICBwcm9jZXNzLmV4aXQoZXhpdENvZGUpO1xuICB0aHJvdyAwOyAgLy8gVGhlIG5vZGUgdHlwaW5nIHNvbWV0aW1lcyBkb24ndCBoYXZlIGEgbmV2ZXIgdHlwZSBmb3IgcHJvY2Vzcy5leGl0KCkuXG59XG5cbi8qKiBQYXJzZSB0aGUgY29tbWFuZCBsaW5lLiAqL1xuY29uc3QgYXJndiA9IG1pbmltaXN0KHByb2Nlc3MuYXJndi5zbGljZSgyKSwgeyBib29sZWFuOiBbJ2hlbHAnXSB9KTtcblxuLyoqIENyZWF0ZSB0aGUgRGV2S2l0IExvZ2dlciB1c2VkIHRocm91Z2ggdGhlIENMSS4gKi9cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUNvbnNvbGVMb2dnZXIoYXJndlsndmVyYm9zZSddKTtcblxuLy8gQ2hlY2sgdGhlIHRhcmdldC5cbmNvbnN0IHRhcmdldFN0ciA9IGFyZ3YuXy5zaGlmdCgpO1xuaWYgKCF0YXJnZXRTdHIgJiYgYXJndi5oZWxwKSB7XG4gIC8vIFNob3cgYXJjaGl0ZWN0IHVzYWdlIGlmIHRoZXJlJ3Mgbm8gdGFyZ2V0LlxuICB1c2FnZSgpO1xufVxuXG4vLyBTcGxpdCBhIHRhcmdldCBpbnRvIGl0cyBwYXJ0cy5cbmxldCBwcm9qZWN0OiBzdHJpbmcsIHRhcmdldE5hbWU6IHN0cmluZywgY29uZmlndXJhdGlvbjogc3RyaW5nO1xuaWYgKHRhcmdldFN0cikge1xuICBbcHJvamVjdCwgdGFyZ2V0TmFtZSwgY29uZmlndXJhdGlvbl0gPSB0YXJnZXRTdHIuc3BsaXQoJzonKTtcbn1cblxuLy8gTG9hZCB3b3Jrc3BhY2UgY29uZmlndXJhdGlvbiBmaWxlLlxuY29uc3QgY3VycmVudFBhdGggPSBwcm9jZXNzLmN3ZCgpO1xuY29uc3QgY29uZmlnRmlsZU5hbWVzID0gW1xuICAnYW5ndWxhci5qc29uJyxcbiAgJy5hbmd1bGFyLmpzb24nLFxuICAnd29ya3NwYWNlLmpzb24nLFxuICAnLndvcmtzcGFjZS5qc29uJyxcbl07XG5cbmNvbnN0IGNvbmZpZ0ZpbGVQYXRoID0gZmluZFVwKGNvbmZpZ0ZpbGVOYW1lcywgY3VycmVudFBhdGgpO1xuXG5pZiAoIWNvbmZpZ0ZpbGVQYXRoKSB7XG4gIGxvZ2dlci5mYXRhbChgV29ya3NwYWNlIGNvbmZpZ3VyYXRpb24gZmlsZSAoJHtjb25maWdGaWxlTmFtZXMuam9pbignLCAnKX0pIGNhbm5vdCBiZSBmb3VuZCBpbiBgXG4gICAgKyBgJyR7Y3VycmVudFBhdGh9JyBvciBpbiBwYXJlbnQgZGlyZWN0b3JpZXMuYCk7XG4gIHByb2Nlc3MuZXhpdCgzKTtcbiAgdGhyb3cgMzsgIC8vIFR5cGVTY3JpcHQgZG9lc24ndCBrbm93IHRoYXQgcHJvY2Vzcy5leGl0KCkgbmV2ZXIgcmV0dXJucy5cbn1cblxuY29uc3Qgcm9vdCA9IGRpcm5hbWUobm9ybWFsaXplKGNvbmZpZ0ZpbGVQYXRoKSk7XG5jb25zdCBjb25maWdDb250ZW50ID0gcmVhZEZpbGVTeW5jKGNvbmZpZ0ZpbGVQYXRoLCAndXRmLTgnKTtcbmNvbnN0IHdvcmtzcGFjZUpzb24gPSBKU09OLnBhcnNlKGNvbmZpZ0NvbnRlbnQpO1xuXG5jb25zdCBob3N0ID0gbmV3IE5vZGVKc1N5bmNIb3N0KCk7XG5jb25zdCB3b3Jrc3BhY2UgPSBuZXcgZXhwZXJpbWVudGFsLndvcmtzcGFjZS5Xb3Jrc3BhY2Uocm9vdCwgaG9zdCk7XG5cbmxldCBsYXN0QnVpbGRFdmVudCA9IHsgc3VjY2VzczogdHJ1ZSB9O1xuXG53b3Jrc3BhY2UubG9hZFdvcmtzcGFjZUZyb21Kc29uKHdvcmtzcGFjZUpzb24pLnBpcGUoXG4gIGNvbmNhdE1hcCh3cyA9PiBuZXcgQXJjaGl0ZWN0KHdzKS5sb2FkQXJjaGl0ZWN0KCkpLFxuICBjb25jYXRNYXAoYXJjaGl0ZWN0ID0+IHtcblxuICAgIGNvbnN0IG92ZXJyaWRlcyA9IHsgLi4uYXJndiB9O1xuICAgIGRlbGV0ZSBvdmVycmlkZXNbJ2hlbHAnXTtcbiAgICBkZWxldGUgb3ZlcnJpZGVzWydfJ107XG5cbiAgICBjb25zdCB0YXJnZXRTcGVjID0ge1xuICAgICAgcHJvamVjdCxcbiAgICAgIHRhcmdldDogdGFyZ2V0TmFtZSxcbiAgICAgIGNvbmZpZ3VyYXRpb24sXG4gICAgICBvdmVycmlkZXMsXG4gICAgfTtcblxuICAgIC8vIFRPRE86IGJldHRlciBsb2dnaW5nIG9mIHdoYXQncyBoYXBwZW5pbmcuXG4gICAgaWYgKGFyZ3YuaGVscCkge1xuICAgICAgLy8gVE9ETzogYWRkIHRhcmdldCBoZWxwXG4gICAgICByZXR1cm4gdGhyb3dFcnJvcignVGFyZ2V0IGhlbHAgTllJLicpO1xuICAgICAgLy8gYXJjaGl0ZWN0LmhlbHAodGFyZ2V0T3B0aW9ucywgbG9nZ2VyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYnVpbGRlckNvbmZpZyA9IGFyY2hpdGVjdC5nZXRCdWlsZGVyQ29uZmlndXJhdGlvbih0YXJnZXRTcGVjKTtcblxuICAgICAgcmV0dXJuIGFyY2hpdGVjdC5ydW4oYnVpbGRlckNvbmZpZywgeyBsb2dnZXIgfSk7XG4gICAgfVxuICB9KSxcbikuc3Vic2NyaWJlKHtcbiAgbmV4dDogKGJ1aWxkRXZlbnQgPT4gbGFzdEJ1aWxkRXZlbnQgPSBidWlsZEV2ZW50KSxcbiAgY29tcGxldGU6ICgpID0+IHByb2Nlc3MuZXhpdChsYXN0QnVpbGRFdmVudC5zdWNjZXNzID8gMCA6IDEpLFxuICBlcnJvcjogKGVycjogRXJyb3IpID0+IHtcbiAgICBsb2dnZXIuZmF0YWwoZXJyLm1lc3NhZ2UpO1xuICAgIGlmIChlcnIuc3RhY2spIHtcbiAgICAgIGxvZ2dlci5mYXRhbChlcnIuc3RhY2spO1xuICAgIH1cbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH0sXG59KTtcbiJdfQ==
\ No newline at end of file
diff --git a/package.json b/package.json
index 7de032ab5..8af4a610d 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,9 @@
{
"name": "@angular-devkit/architect-cli",
- "version": "0.12.0-rc.0",
+ "version": "0.1300.0-next.0",
"description": "Angular Architect CLI",
+ "homepage": "https://github.com/angular/angular-cli",
+ "experimental": true,
"bin": {
"architect": "./bin/architect.js"
},
@@ -17,24 +19,26 @@
"tooling"
],
"dependencies": {
- "@angular-devkit/core": "github:angular/angular-devkit-core-builds#0b7dd0e",
- "@angular-devkit/architect": "github:angular/angular-devkit-architect-builds#0b7dd0e",
- "minimist": "1.2.0",
- "symbol-observable": "1.2.0",
- "rxjs": "6.3.3"
+ "@angular-devkit/architect": "github:angular/angular-devkit-architect-builds#9eb599da2",
+ "@angular-devkit/core": "github:angular/angular-devkit-core-builds#9eb599da2",
+ "ansi-colors": "4.1.1",
+ "minimist": "1.2.5",
+ "progress": "2.0.3",
+ "rxjs": "6.6.7",
+ "symbol-observable": "4.0.0"
},
"repository": {
"type": "git",
"url": "https://github.com/angular/angular-cli.git"
},
"engines": {
- "node": ">= 8.9.0",
- "npm": ">= 5.5.1"
+ "node": "^12.20.0 || >=14.0.0",
+ "npm": "^6.11.0 || ^7.5.6",
+ "yarn": ">= 1.13.0"
},
"author": "Angular Authors",
"license": "MIT",
"bugs": {
"url": "https://github.com/angular/angular-cli/issues"
- },
- "homepage": "https://github.com/angular/angular-cli"
+ }
}
diff --git a/src/progress.d.ts b/src/progress.d.ts
new file mode 100644
index 000000000..d8550e868
--- /dev/null
+++ b/src/progress.d.ts
@@ -0,0 +1,22 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+///
+export declare class MultiProgressBar {
+ private _status;
+ private _stream;
+ private _bars;
+ constructor(_status: string, _stream?: NodeJS.WriteStream);
+ private _add;
+ complete(id: Key): void;
+ add(id: Key, data: T): void;
+ get(key: Key): T | undefined;
+ has(key: Key): boolean;
+ update(key: Key, data: T, current?: number, total?: number): void;
+ render(max?: number, sort?: (a: T, b: T) => number): void;
+ terminate(): void;
+}
diff --git a/src/progress.js b/src/progress.js
new file mode 100644
index 000000000..e64961cc1
--- /dev/null
+++ b/src/progress.js
@@ -0,0 +1,112 @@
+"use strict";
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MultiProgressBar = void 0;
+const progress_1 = __importDefault(require("progress"));
+const readline = __importStar(require("readline"));
+class MultiProgressBar {
+ constructor(_status, _stream = process.stderr) {
+ this._status = _status;
+ this._stream = _stream;
+ this._bars = new Map();
+ }
+ _add(id, data) {
+ const width = Math.min(80, this._stream.columns || 80);
+ const value = {
+ data,
+ bar: new progress_1.default(this._status, {
+ renderThrottle: 0,
+ clear: true,
+ total: 1,
+ width: width,
+ complete: '#',
+ incomplete: '.',
+ stream: this._stream,
+ }),
+ };
+ this._bars.set(id, value);
+ readline.moveCursor(this._stream, 0, 1);
+ return value;
+ }
+ complete(id) {
+ const maybeBar = this._bars.get(id);
+ if (maybeBar) {
+ maybeBar.bar.complete = true;
+ }
+ }
+ add(id, data) {
+ this._add(id, data);
+ }
+ get(key) {
+ const maybeValue = this._bars.get(key);
+ return maybeValue && maybeValue.data;
+ }
+ has(key) {
+ return this._bars.has(key);
+ }
+ update(key, data, current, total) {
+ let maybeBar = this._bars.get(key);
+ if (!maybeBar) {
+ maybeBar = this._add(key, data);
+ }
+ maybeBar.data = data;
+ if (total !== undefined) {
+ maybeBar.bar.total = total;
+ }
+ if (current !== undefined) {
+ maybeBar.bar.curr = Math.max(0, Math.min(current, maybeBar.bar.total));
+ }
+ }
+ render(max = Infinity, sort) {
+ const stream = this._stream;
+ readline.moveCursor(stream, 0, -this._bars.size);
+ readline.cursorTo(stream, 0);
+ let values = this._bars.values();
+ if (sort) {
+ values = [...values].sort((a, b) => sort(a.data, b.data));
+ }
+ for (const { data, bar } of values) {
+ if (max-- == 0) {
+ return;
+ }
+ bar.render(data);
+ readline.moveCursor(stream, 0, 1);
+ readline.cursorTo(stream, 0);
+ }
+ }
+ terminate() {
+ for (const { bar } of this._bars.values()) {
+ bar.terminate();
+ }
+ this._bars.clear();
+ }
+}
+exports.MultiProgressBar = MultiProgressBar;
diff --git a/uniqueId b/uniqueId
index 16d518091..847d54924 100644
--- a/uniqueId
+++ b/uniqueId
@@ -1 +1 @@
-Fri Dec 21 2018 21:43:48 GMT+0000 (Coordinated Universal Time)
\ No newline at end of file
+Fri Aug 13 2021 20:44:51 GMT+0000 (Coordinated Universal Time)
\ No newline at end of file