Skip to content

Commit 2ffbdfa

Browse files
hanslalexeagle
authored andcommitted
build: add a validation script for the analytics.md tables
Also added enums to update when changing dimensions.
1 parent 5547177 commit 2ffbdfa

File tree

9 files changed

+328
-56
lines changed

9 files changed

+328
-56
lines changed

docs/design/analytics.md

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,19 @@ Each command creates a pageview with the path `/command/${commandName}/${subcomm
88
`ng generate component my-component --dryRun` would create a page view with the path
99
`/command/generate/@schematics_angular/component`.
1010

11-
Additionally, only the Architect configuration of `default`, `production` and `staging` will be
12-
logged. The project name will be removed, and if the configuration is different than the three
13-
basic ones, it will be replaced with `_`.
11+
We use page views to keep track of sessions more effectively, and to tag events to a page.
12+
13+
Project names and target names will be removed.
1414
The command `ng run some-project:lint:some-configuration` will create a page view with the path
15-
`/command/run/_:lint:_`. Configurations are only used when actually mentioned on the command
16-
line, thus the command `ng build some-project --prod` will create a page view of
17-
`/command/build/_:default` (with the `prod` flag), while `ng build some-project:some-conf` will log
18-
`/command/build/_:_`.
15+
`/command/run`.
1916

2017
# Dimensions
21-
Google Analytics Custom Dimensions are used to track flag values. These dimensions are aggregated
22-
automatically on the backend.
18+
Google Analytics Custom Dimensions are used to track system values and flag values. These
19+
dimensions are aggregated automatically on the backend.
2320

2421
One dimension per flag, and although technically there can be an overlap between 2 commands, for
25-
simplicity it should remain unique across all CLI commands. These are numbers added to our own
26-
`schema.json` files. Dimensions are not to be used for anything else.
22+
simplicity it should remain unique across all CLI commands. The dimension is the value of the
23+
`x-user-analytics` field in the `schema.json` files.
2724

2825
To create a new dimension (tracking a new flag):
2926

@@ -41,43 +38,60 @@ PROJECT NAME TO BUILD OR A MODULE NAME.**
4138
Note: There's a limit of 20 custom dimensions.
4239

4340
### List Of All Dimensions
44-
| Id | Category | Flag | Type | File / Description |
45-
|:---:|:---|:---|:---|---:|
46-
| 1 | `generate`, `new` | `--dryRun` | `Boolean` | |
47-
| 2 | `generate`, `new` | `--force` | `Boolean` | |
48-
| 3 | `generate`, `new` | `--interactive` | `Boolean` | |
49-
| 4 | `generate` | `--skipInstall` | `Boolean` | |
50-
| 5 | `generate` | `--style` | `String` | |
51-
| 6 | `add` | `--collection` | `String` | Only for packages that we control (see safelist in `add-impl.ts`). |
52-
| 7 | `build`, `serve` | `--buildEventLog` | `Boolean` | If the flag was used (does not report its value). See `build-impl.ts`. |
53-
| 8 | `generate`, `new` | `--enableIvy` | `Boolean` | |
54-
| 9 | `generate` | `--inlineStyle` | `Boolean` | |
55-
| 10 | `generate` | `--inlineTemplate` | `Boolean` | |
56-
| 11 | `generate` | `--viewEncapsulation` | `String` | |
57-
| 12 | `generate` | `--skipTests` | `Boolean` | |
58-
| 13 | `build` | `--aot` | `Boolean` | |
59-
| 14 | `generate` | `--minimal` | `Boolean` | |
60-
| 15 | `generate` | `--lintFix` | `Boolean` | |
61-
| 16 | `build` | `--optimization` | `Boolean` | |
62-
| 17 | `generate` | `--routing` | `Boolean` | |
63-
| 18 | `generate` | `--skipImport` | `Boolean` | |
64-
| 19 | `generate` | `--export` | `Boolean` | |
65-
| 20 | `generate` | `--entryComponent` | `Boolean` | |
41+
<!--DIMENSIONS_TABLE_BEGIN-->
42+
| Id | Flag | Type |
43+
|:---:|:---|:---|
44+
| 1 | `CPU Count` | `number` |
45+
| 2 | `CPU Speed` | `number` |
46+
| 3 | `RAM (In MB)` | `number` |
47+
| 4 | `Node Version` | `number` |
48+
| 5 | `Flag: --style` | `string` |
49+
| 6 | `--collection` | `string` |
50+
| 7 | `--buildEventLog` | `boolean` |
51+
| 8 | `Flag: --enableIvy` | `boolean` |
52+
| 9 | `Flag: --inlineStyle` | `boolean` |
53+
| 10 | `Flag: --inlineTemplate` | `boolean` |
54+
| 11 | `Flag: --viewEncapsulation` | `string` |
55+
| 12 | `Flag: --skipTests` | `boolean` |
56+
| 13 | `Flag: --aot` | `boolean` |
57+
| 14 | `Flag: --minimal` | `boolean` |
58+
| 15 | `Flag: --lintFix` | `boolean` |
59+
| 16 | `Flag: --optimization` | `boolean` |
60+
| 17 | `Flag: --routing` | `boolean` |
61+
| 18 | `Flag: --skipImport` | `boolean` |
62+
| 19 | `Flag: --export` | `boolean` |
63+
| 20 | `Build Errors (comma separated)` | `string` |
64+
<!--DIMENSIONS_TABLE_END-->
6665

6766
# Metrics
6867

6968
### List of All Metrics
70-
| Id | Type | Description |
71-
|:---:|:-----|-------------|
72-
| 1 | `Number` | CPU count |
73-
| 2 | `Number` | Average CPU speed |
74-
| 3 | `Number` | RAM Count |
75-
| 4 | `Number` | Node Version (Major.Minor) |
69+
<!--METRICS_TABLE_BEGIN-->
70+
| Id | Flag | Type |
71+
|:---:|:---|:---|
72+
| 1 | `UNUSED_1` | `none` |
73+
| 2 | `UNUSED_2` | `none` |
74+
| 3 | `UNUSED_3` | `none` |
75+
| 4 | `UNUSED_4` | `none` |
76+
| 5 | `Build Time` | `number` |
77+
| 6 | `NgOnInit Count` | `number` |
78+
| 7 | `Initial Chunk Size` | `number` |
79+
| 8 | `Total Chunk Count` | `number` |
80+
| 9 | `Total Chunk Size` | `number` |
81+
| 10 | `Lazy Chunk Count` | `number` |
82+
| 11 | `Lazy Chunk Size` | `number` |
83+
| 12 | `Asset Count` | `number` |
84+
| 13 | `Asset Size` | `number` |
85+
| 14 | ` Polyfill Size` | `number` |
86+
| 15 | ` Css Size` | `number` |
87+
<!--METRICS_TABLE_END-->
7688

7789
# Operating System and Node Version
7890
A User Agent string is built to "fool" Google Analytics into reading the Operating System and
7991
version fields from it. The base dimensions are used for those.
8092

93+
Node version is our App ID, but a dimension is also used to get the numeric MAJOR.MINOR of node.
94+
8195
# Debugging
8296
Using `DEBUG=universal-analytics` will report all calls to the universal-analytics library,
8397
including queuing events and sending them to the server.

packages/angular/cli/commands/add-impl.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ModuleNotFoundException, resolve } from '@angular-devkit/core/node';
1010
import { NodePackageDoesNotSupportSchematics } from '@angular-devkit/schematics/tools';
1111
import { dirname } from 'path';
1212
import { intersects, prerelease, rcompare, satisfies, valid, validRange } from 'semver';
13-
import { AnalyticsDimensions, isPackageNameSafeForAnalytics } from '../models/analytics';
13+
import { isPackageNameSafeForAnalytics } from '../models/analytics';
1414
import { Arguments } from '../models/interface';
1515
import { SchematicCommand } from '../models/schematic-command';
1616
import npmInstall from '../tasks/npm-install';
@@ -152,7 +152,7 @@ export class AddCommand extends SchematicCommand<AddCommandSchema> {
152152
if (collection && isPackageNameSafeForAnalytics(collection)) {
153153
dimensions[analytics.NgCliAnalyticsDimensions.NgAddCollection] = collection;
154154
} else {
155-
delete dimensions[AnalyticsDimensions.NgAddCollection];
155+
delete dimensions[analytics.NgCliAnalyticsDimensions.NgAddCollection];
156156
}
157157

158158
return super.reportAnalytics(paths, options, dimensions, metrics);

packages/angular/cli/models/analytics.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,6 @@ export function isPackageNameSafeForAnalytics(name: string) {
4242
});
4343
}
4444

45-
/**
46-
* MAKE SURE TO KEEP THIS IN SYNC WITH THE TABLE AND CONTENT IN `/docs/design/analytics.md`.
47-
* WE LIST THOSE DIMENSIONS (AND MORE).
48-
*/
49-
export enum AnalyticsDimensions {
50-
NgAddCollection = 6,
51-
NgBuildBuildEventLog = 7,
52-
}
53-
5445

5546
/**
5647
* Attempt to get the Windows Language Code string.

packages/angular_devkit/core/src/analytics/index.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ export * from './noop';
1515
/**
1616
* MAKE SURE TO KEEP THIS IN SYNC WITH THE TABLE AND CONTENT IN `/docs/design/analytics.md`.
1717
* WE LIST THOSE DIMENSIONS (AND MORE).
18+
*
19+
* These cannot be in their respective schema.json file because we either change the type
20+
* (e.g. --buildEventLog is string, but we want to know the usage of it, not its value), or
21+
* some validation needs to be done (we cannot record ng add --collection if it's not whitelisted).
1822
*/
1923
export enum NgCliAnalyticsDimensions {
2024
CpuCount = 1,
@@ -40,6 +44,38 @@ export enum NgCliAnalyticsMetrics {
4044
LazyChunkSize = 11,
4145
AssetCount = 12,
4246
AssetSize = 13,
43-
PolyfillSize = 12,
44-
CssSize = 13,
47+
PolyfillSize = 14,
48+
CssSize = 15,
4549
}
50+
51+
// This table is used when generating the analytics.md file. It should match the enum above
52+
// or the validate-user-analytics script will fail.
53+
export const NgCliAnalyticsDimensionsFlagInfo: { [name: string]: [string, string] } = {
54+
CpuCount: ['CPU Count', 'number'],
55+
CpuSpeed: ['CPU Speed', 'number'],
56+
RamInMegabytes: ['RAM (In MB)', 'number'],
57+
NodeVersion: ['Node Version', 'number'],
58+
NgAddCollection: ['--collection', 'string'],
59+
NgBuildBuildEventLog: ['--buildEventLog', 'boolean'],
60+
BuildErrors: ['Build Errors (comma separated)', 'string'],
61+
};
62+
63+
// This table is used when generating the analytics.md file. It should match the enum above
64+
// or the validate-user-analytics script will fail.
65+
export const NgCliAnalyticsMetricsFlagInfo: { [name: string]: [string, string] } = {
66+
UNUSED_1: ['UNUSED_1', 'none'],
67+
UNUSED_2: ['UNUSED_2', 'none'],
68+
UNUSED_3: ['UNUSED_3', 'none'],
69+
UNUSED_4: ['UNUSED_4', 'none'],
70+
BuildTime: ['Build Time', 'number'],
71+
NgOnInitCount: ['NgOnInit Count', 'number'],
72+
InitialChunkSize: ['Initial Chunk Size', 'number'],
73+
TotalChunkCount: ['Total Chunk Count', 'number'],
74+
TotalChunkSize: ['Total Chunk Size', 'number'],
75+
LazyChunkCount: ['Lazy Chunk Count', 'number'],
76+
LazyChunkSize: ['Lazy Chunk Size', 'number'],
77+
AssetCount: ['Asset Count', 'number'],
78+
AssetSize: ['Asset Size', 'number'],
79+
PolyfillSize: [' Polyfill Size', 'number'],
80+
CssSize: [' Css Size', 'number'],
81+
};

packages/schematics/angular/application/schema.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@
8080
"skipPackageJson": {
8181
"type": "boolean",
8282
"default": false,
83-
"description": "When true, does not add dependencies to the \"package.json\" file.",
84-
"x-user-analytics": 13
83+
"description": "When true, does not add dependencies to the \"package.json\" file."
8584
},
8685
"minimal": {
8786
"description": "When true, creates a bare-bones project without any testing frameworks. (Use for learning purposes only.)",

packages/schematics/angular/library/schema.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@
3131
"skipPackageJson": {
3232
"type": "boolean",
3333
"default": false,
34-
"description": "When true, does not add dependencies to the \"package.json\" file. ",
35-
"x-user-analytics": 13
34+
"description": "When true, does not add dependencies to the \"package.json\" file. "
3635
},
3736
"skipInstall": {
3837
"description": "When true, does not install dependency packages.",
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<%
2+
%>| Id | Flag | Type |
3+
|:---:|:---|:---|
4+
<% for (const flag of flags) {
5+
if (flag === undefined) {
6+
continue;
7+
}
8+
%>| <%= flag.userAnalytics %> | `<%= flag.name %>` | `<%= flag.type %>` |
9+
<%}%>

0 commit comments

Comments
 (0)