UNPKG

5.85 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright Google LLC 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 */
9Object.defineProperty(exports, "__esModule", { value: true });
10exports.Command = void 0;
11const core_1 = require("@angular-devkit/core");
12const color_1 = require("../utilities/color");
13const interface_1 = require("./interface");
14class Command {
15 constructor(context, description, logger) {
16 this.context = context;
17 this.description = description;
18 this.logger = logger;
19 this.allowMissingWorkspace = false;
20 this.useReportAnalytics = true;
21 this.workspace = context.workspace;
22 this.analytics = context.analytics || new core_1.analytics.NoopAnalytics();
23 }
24 static setCommandMap(map) {
25 this.commandMap = map;
26 }
27 async initialize(options) { }
28 async printHelp() {
29 await this.printHelpUsage();
30 await this.printHelpOptions();
31 return 0;
32 }
33 async printJsonHelp() {
34 const replacer = (key, value) => key === 'name' ? core_1.strings.dasherize(value) : value;
35 this.logger.info(JSON.stringify(this.description, replacer, 2));
36 return 0;
37 }
38 async printHelpUsage() {
39 this.logger.info(this.description.description);
40 const name = this.description.name;
41 const args = this.description.options.filter((x) => x.positional !== undefined);
42 const opts = this.description.options.filter((x) => x.positional === undefined);
43 const argDisplay = args && args.length > 0 ? ' ' + args.map((a) => `<${a.name}>`).join(' ') : '';
44 const optionsDisplay = opts && opts.length > 0 ? ` [options]` : ``;
45 this.logger.info(`usage: ng ${name}${argDisplay}${optionsDisplay}`);
46 this.logger.info('');
47 }
48 async printHelpOptions(options = this.description.options) {
49 const args = options.filter((opt) => opt.positional !== undefined);
50 const opts = options.filter((opt) => opt.positional === undefined);
51 const formatDescription = (description) => ` ${description.replace(/\n/g, '\n ')}`;
52 if (args.length > 0) {
53 this.logger.info(`arguments:`);
54 args.forEach((o) => {
55 this.logger.info(` ${color_1.colors.cyan(o.name)}`);
56 if (o.description) {
57 this.logger.info(formatDescription(o.description));
58 }
59 });
60 }
61 if (options.length > 0) {
62 if (args.length > 0) {
63 this.logger.info('');
64 }
65 this.logger.info(`options:`);
66 opts
67 .filter((o) => !o.hidden)
68 .sort((a, b) => a.name.localeCompare(b.name))
69 .forEach((o) => {
70 const aliases = o.aliases && o.aliases.length > 0
71 ? '(' + o.aliases.map((a) => `-${a}`).join(' ') + ')'
72 : '';
73 this.logger.info(` ${color_1.colors.cyan('--' + core_1.strings.dasherize(o.name))} ${aliases}`);
74 if (o.description) {
75 this.logger.info(formatDescription(o.description));
76 }
77 });
78 }
79 }
80 async validateScope(scope) {
81 switch (scope === undefined ? this.description.scope : scope) {
82 case interface_1.CommandScope.OutProject:
83 if (this.workspace) {
84 this.logger.fatal(core_1.tags.oneLine `
85 The ${this.description.name} command requires to be run outside of a project, but a
86 project definition was found at "${this.workspace.filePath}".
87 `);
88 // eslint-disable-next-line no-throw-literal
89 throw 1;
90 }
91 break;
92 case interface_1.CommandScope.InProject:
93 if (!this.workspace) {
94 this.logger.fatal(core_1.tags.oneLine `
95 The ${this.description.name} command requires to be run in an Angular project, but a
96 project definition could not be found.
97 `);
98 // eslint-disable-next-line no-throw-literal
99 throw 1;
100 }
101 break;
102 case interface_1.CommandScope.Everywhere:
103 // Can't miss this.
104 break;
105 }
106 }
107 async reportAnalytics(paths, options, dimensions = [], metrics = []) {
108 for (const option of this.description.options) {
109 const ua = option.userAnalytics;
110 const v = options[option.name];
111 if (v !== undefined && !Array.isArray(v) && ua) {
112 dimensions[ua] = v;
113 }
114 }
115 this.analytics.pageview('/command/' + paths.join('/'), { dimensions, metrics });
116 }
117 async validateAndRun(options) {
118 if (!(options.help === true || options.help === 'json' || options.help === 'JSON')) {
119 await this.validateScope();
120 }
121 let result = await this.initialize(options);
122 if (typeof result === 'number' && result !== 0) {
123 return result;
124 }
125 if (options.help === true) {
126 return this.printHelp();
127 }
128 else if (options.help === 'json' || options.help === 'JSON') {
129 return this.printJsonHelp();
130 }
131 else {
132 const startTime = +new Date();
133 if (this.useReportAnalytics) {
134 await this.reportAnalytics([this.description.name], options);
135 }
136 result = await this.run(options);
137 const endTime = +new Date();
138 this.analytics.timing(this.description.name, 'duration', endTime - startTime);
139 return result;
140 }
141 }
142}
143exports.Command = Command;