|
6 | 6 | * found in the LICENSE file at https://angular.io/license
|
7 | 7 | */
|
8 | 8 |
|
9 |
| -import { analytics, logging, tags } from '@angular-devkit/core'; |
10 |
| -import { spawnSync } from 'child_process'; |
| 9 | +import { analytics, logging, schema, strings, tags } from '@angular-devkit/core'; |
11 | 10 | import * as fs from 'fs';
|
12 |
| -import * as os from 'os'; |
| 11 | +import { glob as globCb } from 'glob'; |
13 | 12 | import * as path from 'path';
|
14 |
| -import { CommandDescriptionMap, Option } from '../packages/angular/cli/models/interface'; |
15 |
| -import create from './create'; |
| 13 | +import { promisify } from 'util'; |
| 14 | +import { packages } from '../lib/packages'; |
16 | 15 |
|
17 | 16 | const userAnalyticsTable = require('./templates/user-analytics-table').default;
|
18 | 17 |
|
19 | 18 | const dimensionsTableRe = /<!--DIMENSIONS_TABLE_BEGIN-->([\s\S]*)<!--DIMENSIONS_TABLE_END-->/m;
|
20 | 19 | const metricsTableRe = /<!--METRICS_TABLE_BEGIN-->([\s\S]*)<!--METRICS_TABLE_END-->/m;
|
21 | 20 |
|
22 |
| -/** |
23 |
| - * Execute a command. |
24 |
| - * @private |
25 |
| - */ |
26 |
| -function _exec(command: string, args: string[], opts: { cwd?: string }, logger: logging.Logger) { |
27 |
| - const { status, error, stdout } = spawnSync(command, args, { |
28 |
| - stdio: ['ignore', 'pipe', 'inherit'], |
29 |
| - ...opts, |
30 |
| - }); |
31 |
| - |
32 |
| - if (status != 0) { |
33 |
| - logger.error(`Command failed: ${command} ${args.map((x) => JSON.stringify(x)).join(', ')}`); |
34 |
| - throw error; |
35 |
| - } |
36 |
| - |
37 |
| - return stdout.toString('utf-8'); |
38 |
| -} |
39 |
| - |
40 | 21 | async function _checkDimensions(dimensionsTable: string, logger: logging.Logger) {
|
41 | 22 | const data: { userAnalytics: number; type: string; name: string }[] = new Array(200);
|
42 | 23 |
|
43 |
| - function _updateData(userAnalytics: number, name: string, type: string) { |
| 24 | + function updateData(userAnalytics: number, name: string, type: string) { |
44 | 25 | if (data[userAnalytics]) {
|
45 | 26 | if (data[userAnalytics].name !== name) {
|
46 | 27 | logger.error(tags.stripIndents`
|
@@ -77,47 +58,37 @@ async function _checkDimensions(dimensionsTable: string, logger: logging.Logger)
|
77 | 58 | `Invalid value found in enum AnalyticsDimensions: ${JSON.stringify(userAnalytics)}`,
|
78 | 59 | );
|
79 | 60 | }
|
80 |
| - _updateData(userAnalytics, flagName, type); |
| 61 | + updateData(userAnalytics, flagName, type); |
81 | 62 | }
|
82 | 63 |
|
83 |
| - // Creating a new project and reading the help. |
84 |
| - logger.info('Creating temporary project for gathering help...'); |
85 |
| - |
86 |
| - const newProjectTempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'angular-cli-create-')); |
87 |
| - const newProjectName = 'help-project'; |
88 |
| - const newProjectRoot = path.join(newProjectTempRoot, newProjectName); |
89 |
| - await create({ _: [newProjectName] }, logger.createChild('create'), newProjectTempRoot); |
| 64 | + logger.info('Gathering options for user-analytics...'); |
90 | 65 |
|
91 |
| - const commandDescription: CommandDescriptionMap = {}; |
| 66 | + const userAnalyticsGatherer = (obj: Object) => { |
| 67 | + for (const [key, value] of Object.entries(obj)) { |
| 68 | + if (value && typeof value === 'object') { |
| 69 | + if ('x-user-analytics' in value) { |
| 70 | + const type = |
| 71 | + [...schema.getTypesOfSchema(value)].find((type) => type !== 'object') ?? 'string'; |
92 | 72 |
|
93 |
| - logger.info('Gathering options...'); |
94 |
| - |
95 |
| - const commands = require('../packages/angular/cli/commands.json'); |
96 |
| - const ngPath = path.join(newProjectRoot, 'node_modules/.bin/ng'); |
97 |
| - for (const commandName of Object.keys(commands)) { |
98 |
| - const options = { cwd: newProjectRoot }; |
99 |
| - const childLogger = logger.createChild(commandName); |
100 |
| - const stdout = _exec(ngPath, [commandName, '--help=json'], options, childLogger); |
101 |
| - commandDescription[commandName] = JSON.parse(stdout.trim()); |
102 |
| - } |
103 |
| - |
104 |
| - function _checkOptionsForAnalytics(options: Option[]) { |
105 |
| - for (const option of options) { |
106 |
| - if (option.subcommands) { |
107 |
| - for (const subcommand of Object.values(option.subcommands)) { |
108 |
| - _checkOptionsForAnalytics(subcommand.options); |
| 73 | + updateData(value['x-user-analytics'], 'Flag: --' + strings.dasherize(key), type); |
| 74 | + } else { |
| 75 | + userAnalyticsGatherer(value); |
109 | 76 | }
|
110 | 77 | }
|
111 |
| - |
112 |
| - if (option.userAnalytics === undefined) { |
113 |
| - continue; |
114 |
| - } |
115 |
| - _updateData(option.userAnalytics, 'Flag: --' + option.name, option.type); |
116 | 78 | }
|
117 |
| - } |
| 79 | + }; |
| 80 | + |
| 81 | + const glob = promisify(globCb); |
118 | 82 |
|
119 |
| - for (const commandName of Object.keys(commandDescription)) { |
120 |
| - _checkOptionsForAnalytics(commandDescription[commandName].options); |
| 83 | + // Find all the schemas |
| 84 | + const packagesPaths = Object.values(packages).map(({ root }) => root); |
| 85 | + for (const packagePath of packagesPaths) { |
| 86 | + const schemasPaths = await glob('**/schema.json', { cwd: packagePath }); |
| 87 | + |
| 88 | + for (const schemaPath of schemasPaths) { |
| 89 | + const schema = await fs.promises.readFile(path.join(packagePath, schemaPath), 'utf8'); |
| 90 | + userAnalyticsGatherer(JSON.parse(schema)); |
| 91 | + } |
121 | 92 | }
|
122 | 93 |
|
123 | 94 | const generatedTable = userAnalyticsTable({ flags: data }).trim();
|
|
0 commit comments