1 | #!/usr/bin/env node
|
2 | "use strict";
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
11 | if (k2 === undefined) k2 = k;
|
12 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
13 | }) : (function(o, m, k, k2) {
|
14 | if (k2 === undefined) k2 = k;
|
15 | o[k2] = m[k];
|
16 | }));
|
17 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
18 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
19 | }) : function(o, v) {
|
20 | o["default"] = v;
|
21 | });
|
22 | var __importStar = (this && this.__importStar) || function (mod) {
|
23 | if (mod && mod.__esModule) return mod;
|
24 | var result = {};
|
25 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
26 | __setModuleDefault(result, mod);
|
27 | return result;
|
28 | };
|
29 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
30 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
31 | };
|
32 | Object.defineProperty(exports, "__esModule", { value: true });
|
33 | exports.main = void 0;
|
34 |
|
35 | require("symbol-observable");
|
36 | const core_1 = require("@angular-devkit/core");
|
37 | const node_1 = require("@angular-devkit/core/node");
|
38 | const schematics_1 = require("@angular-devkit/schematics");
|
39 | const tools_1 = require("@angular-devkit/schematics/tools");
|
40 | const ansiColors = __importStar(require("ansi-colors"));
|
41 | const inquirer = __importStar(require("inquirer"));
|
42 | const minimist_1 = __importDefault(require("minimist"));
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 | function parseSchematicName(str) {
|
58 | let collection = '@angular-devkit/schematics-cli';
|
59 | let schematic = str;
|
60 | if (schematic && schematic.indexOf(':') != -1) {
|
61 | [collection, schematic] = [
|
62 | schematic.slice(0, schematic.lastIndexOf(':')),
|
63 | schematic.substring(schematic.lastIndexOf(':') + 1),
|
64 | ];
|
65 | }
|
66 | return { collection, schematic };
|
67 | }
|
68 | function _listSchematics(workflow, collectionName, logger) {
|
69 | try {
|
70 | const collection = workflow.engine.createCollection(collectionName);
|
71 | logger.info(collection.listSchematicNames().join('\n'));
|
72 | }
|
73 | catch (error) {
|
74 | logger.fatal(error.message);
|
75 | return 1;
|
76 | }
|
77 | return 0;
|
78 | }
|
79 | function _createPromptProvider() {
|
80 | return (definitions) => {
|
81 | const questions = definitions.map((definition) => {
|
82 | const question = {
|
83 | name: definition.id,
|
84 | message: definition.message,
|
85 | default: definition.default,
|
86 | };
|
87 | const validator = definition.validator;
|
88 | if (validator) {
|
89 | question.validate = (input) => validator(input);
|
90 | }
|
91 | switch (definition.type) {
|
92 | case 'confirmation':
|
93 | return { ...question, type: 'confirm' };
|
94 | case 'list':
|
95 | return {
|
96 | ...question,
|
97 | type: definition.multiselect ? 'checkbox' : 'list',
|
98 | choices: definition.items &&
|
99 | definition.items.map((item) => {
|
100 | if (typeof item == 'string') {
|
101 | return item;
|
102 | }
|
103 | else {
|
104 | return {
|
105 | name: item.label,
|
106 | value: item.value,
|
107 | };
|
108 | }
|
109 | }),
|
110 | };
|
111 | default:
|
112 | return { ...question, type: definition.type };
|
113 | }
|
114 | });
|
115 | return inquirer.prompt(questions);
|
116 | };
|
117 | }
|
118 |
|
119 | async function main({ args, stdout = process.stdout, stderr = process.stderr, }) {
|
120 | const argv = parseArgs(args);
|
121 |
|
122 |
|
123 | const colors = ansiColors.create();
|
124 |
|
125 | const logger = (0, node_1.createConsoleLogger)(argv['verbose'], stdout, stderr, {
|
126 | info: (s) => s,
|
127 | debug: (s) => s,
|
128 | warn: (s) => colors.bold.yellow(s),
|
129 | error: (s) => colors.bold.red(s),
|
130 | fatal: (s) => colors.bold.red(s),
|
131 | });
|
132 | if (argv.help) {
|
133 | logger.info(getUsage());
|
134 | return 0;
|
135 | }
|
136 |
|
137 | const { collection: collectionName, schematic: schematicName } = parseSchematicName(argv._.shift() || null);
|
138 | const isLocalCollection = collectionName.startsWith('.') || collectionName.startsWith('/');
|
139 |
|
140 | const debugPresent = argv['debug'] !== null;
|
141 | const debug = debugPresent ? !!argv['debug'] : isLocalCollection;
|
142 | const dryRunPresent = argv['dry-run'] !== null;
|
143 | const dryRun = dryRunPresent ? !!argv['dry-run'] : debug;
|
144 | const force = argv['force'];
|
145 | const allowPrivate = argv['allow-private'];
|
146 |
|
147 | const workflow = new tools_1.NodeWorkflow(process.cwd(), {
|
148 | force,
|
149 | dryRun,
|
150 | resolvePaths: [process.cwd(), __dirname],
|
151 | schemaValidation: true,
|
152 | });
|
153 |
|
154 | if (argv['list-schematics']) {
|
155 | return _listSchematics(workflow, collectionName, logger);
|
156 | }
|
157 | if (!schematicName) {
|
158 | logger.info(getUsage());
|
159 | return 1;
|
160 | }
|
161 | if (debug) {
|
162 | logger.info(`Debug mode enabled${isLocalCollection ? ' by default for local collections' : ''}.`);
|
163 | }
|
164 |
|
165 |
|
166 | let nothingDone = true;
|
167 |
|
168 |
|
169 | let loggingQueue = [];
|
170 | let error = false;
|
171 | |
172 |
|
173 |
|
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 | workflow.reporter.subscribe((event) => {
|
182 | nothingDone = false;
|
183 |
|
184 | const eventPath = event.path.startsWith('/') ? event.path.substr(1) : event.path;
|
185 | switch (event.kind) {
|
186 | case 'error':
|
187 | error = true;
|
188 | const desc = event.description == 'alreadyExist' ? 'already exists' : 'does not exist';
|
189 | logger.error(`ERROR! ${eventPath} ${desc}.`);
|
190 | break;
|
191 | case 'update':
|
192 | loggingQueue.push(`${colors.cyan('UPDATE')} ${eventPath} (${event.content.length} bytes)`);
|
193 | break;
|
194 | case 'create':
|
195 | loggingQueue.push(`${colors.green('CREATE')} ${eventPath} (${event.content.length} bytes)`);
|
196 | break;
|
197 | case 'delete':
|
198 | loggingQueue.push(`${colors.yellow('DELETE')} ${eventPath}`);
|
199 | break;
|
200 | case 'rename':
|
201 | const eventToPath = event.to.startsWith('/') ? event.to.substr(1) : event.to;
|
202 | loggingQueue.push(`${colors.blue('RENAME')} ${eventPath} => ${eventToPath}`);
|
203 | break;
|
204 | }
|
205 | });
|
206 | |
207 |
|
208 |
|
209 | workflow.lifeCycle.subscribe((event) => {
|
210 | if (event.kind == 'workflow-end' || event.kind == 'post-tasks-start') {
|
211 | if (!error) {
|
212 |
|
213 | loggingQueue.forEach((log) => logger.info(log));
|
214 | }
|
215 | loggingQueue = [];
|
216 | error = false;
|
217 | }
|
218 | });
|
219 | |
220 |
|
221 |
|
222 | const parsedArgs = Object.assign({}, argv);
|
223 | delete parsedArgs['--'];
|
224 | for (const key of booleanArgs) {
|
225 | delete parsedArgs[key];
|
226 | }
|
227 | |
228 |
|
229 |
|
230 | const argv2 = (0, minimist_1.default)(argv['--']);
|
231 | for (const key of Object.keys(argv2)) {
|
232 | parsedArgs[key] = argv2[key];
|
233 | }
|
234 |
|
235 | workflow.registry.useXDeprecatedProvider((msg) => logger.warn(msg));
|
236 |
|
237 | workflow.registry.addSmartDefaultProvider('argv', (schema) => {
|
238 | if ('index' in schema) {
|
239 | return argv._[Number(schema['index'])];
|
240 | }
|
241 | else {
|
242 | return argv._;
|
243 | }
|
244 | });
|
245 | delete parsedArgs._;
|
246 |
|
247 | if (argv['interactive'] && isTTY()) {
|
248 | workflow.registry.usePromptProvider(_createPromptProvider());
|
249 | }
|
250 | |
251 |
|
252 |
|
253 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 | try {
|
259 | await workflow
|
260 | .execute({
|
261 | collection: collectionName,
|
262 | schematic: schematicName,
|
263 | options: parsedArgs,
|
264 | allowPrivate: allowPrivate,
|
265 | debug: debug,
|
266 | logger: logger,
|
267 | })
|
268 | .toPromise();
|
269 | if (nothingDone) {
|
270 | logger.info('Nothing to be done.');
|
271 | }
|
272 | else if (dryRun) {
|
273 | logger.info(`Dry run enabled${dryRunPresent ? '' : ' by default in debug mode'}. No files written to disk.`);
|
274 | }
|
275 | return 0;
|
276 | }
|
277 | catch (err) {
|
278 | if (err instanceof schematics_1.UnsuccessfulWorkflowExecution) {
|
279 |
|
280 | logger.fatal('The Schematic workflow failed. See above.');
|
281 | }
|
282 | else if (debug) {
|
283 | logger.fatal('An error occured:\n' + err.stack);
|
284 | }
|
285 | else {
|
286 | logger.fatal(err.stack || err.message);
|
287 | }
|
288 | return 1;
|
289 | }
|
290 | }
|
291 | exports.main = main;
|
292 |
|
293 |
|
294 |
|
295 | function getUsage() {
|
296 | return core_1.tags.stripIndent `
|
297 | schematics [CollectionName:]SchematicName [options, ...]
|
298 |
|
299 | By default, if the collection name is not specified, use the internal collection provided
|
300 | by the Schematics CLI.
|
301 |
|
302 | Options:
|
303 | --debug Debug mode. This is true by default if the collection is a relative
|
304 | path (in that case, turn off with --debug=false).
|
305 |
|
306 | --allow-private Allow private schematics to be run from the command line. Default to
|
307 | false.
|
308 |
|
309 | --dry-run Do not output anything, but instead just show what actions would be
|
310 | performed. Default to true if debug is also true.
|
311 |
|
312 | --force Force overwriting files that would otherwise be an error.
|
313 |
|
314 | --list-schematics List all schematics from the collection, by name. A collection name
|
315 | should be suffixed by a colon. Example: '@angular-devkit/schematics-cli:'.
|
316 |
|
317 | --no-interactive Disables interactive input prompts.
|
318 |
|
319 | --verbose Show more information.
|
320 |
|
321 | --help Show this message.
|
322 |
|
323 | Any additional option is passed to the Schematics depending on its schema.
|
324 | `;
|
325 | }
|
326 |
|
327 | const booleanArgs = [
|
328 | 'allowPrivate',
|
329 | 'allow-private',
|
330 | 'debug',
|
331 | 'dry-run',
|
332 | 'dryRun',
|
333 | 'force',
|
334 | 'help',
|
335 | 'list-schematics',
|
336 | 'listSchematics',
|
337 | 'verbose',
|
338 | 'interactive',
|
339 | ];
|
340 | function parseArgs(args) {
|
341 | return (0, minimist_1.default)(args, {
|
342 | boolean: booleanArgs,
|
343 | alias: {
|
344 | 'dryRun': 'dry-run',
|
345 | 'listSchematics': 'list-schematics',
|
346 | 'allowPrivate': 'allow-private',
|
347 | },
|
348 | default: {
|
349 | 'interactive': true,
|
350 | 'debug': null,
|
351 | 'dryRun': null,
|
352 | },
|
353 | '--': true,
|
354 | });
|
355 | }
|
356 | function isTTY() {
|
357 | const isTruthy = (value) => {
|
358 |
|
359 | return value !== undefined && value !== '0' && value.toUpperCase() !== 'FALSE';
|
360 | };
|
361 |
|
362 | const force = process.env['NG_FORCE_TTY'];
|
363 | if (force !== undefined) {
|
364 | return isTruthy(force);
|
365 | }
|
366 | return !!process.stdout.isTTY && !isTruthy(process.env['CI']);
|
367 | }
|
368 | if (require.main === module) {
|
369 | const args = process.argv.slice(2);
|
370 | main({ args })
|
371 | .then((exitCode) => (process.exitCode = exitCode))
|
372 | .catch((e) => {
|
373 | throw e;
|
374 | });
|
375 | }
|