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