UNPKG

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