Skip to content

Commit b9fd911

Browse files
committed
refactor: add build and rebuild related statistics and analytics
The new build and rebuild statistics are used by the CLI to submit build related information to GA.
1 parent 2075480 commit b9fd911

File tree

6 files changed

+333
-193
lines changed

6 files changed

+333
-193
lines changed

packages/angular/cli/src/command-builder/architect-base-command-module.ts

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import {
1111
NodeModulesBuilderInfo,
1212
WorkspaceNodeModulesArchitectHost,
1313
} from '@angular-devkit/architect/node';
14-
import { json } from '@angular-devkit/core';
14+
import { json, JsonValue } from '@angular-devkit/core';
1515
import { spawnSync } from 'child_process';
1616
import { existsSync } from 'fs';
1717
import { resolve } from 'path';
1818
import { isPackageNameSafeForAnalytics } from '../analytics/analytics';
19-
import { EventCustomDimension } from '../analytics/analytics-collector';
19+
import { EventCustomDimension, EventCustomMetric } from '../analytics/analytics-parameters';
2020
import { assertIsError } from '../utilities/error';
2121
import { askConfirmation, askQuestion } from '../utilities/prompt';
2222
import { isTTY } from '../utilities/tty';
@@ -62,18 +62,73 @@ export abstract class ArchitectBaseCommandModule<T extends object>
6262
? await this.getAnalytics()
6363
: undefined;
6464

65-
analytics?.reportArchitectRunEvent({
66-
[EventCustomDimension.BuilderTarget]: builderName,
67-
});
65+
let outputSubscription;
66+
if (analytics) {
67+
analytics.reportArchitectRunEvent({
68+
[EventCustomDimension.BuilderTarget]: builderName,
69+
});
70+
71+
let firstRun = true;
72+
outputSubscription = run.output.subscribe(({ stats }) => {
73+
const parameters = this.builderStatsToAnalyticsParameters(stats, builderName);
74+
if (!parameters) {
75+
return;
76+
}
6877

69-
const { error, success } = await run.output.toPromise();
70-
await run.stop();
78+
if (firstRun) {
79+
firstRun = false;
80+
analytics.reportBuildRunEvent(parameters);
81+
} else {
82+
analytics.reportRebuildRunEvent(parameters);
83+
}
84+
});
85+
}
86+
87+
try {
88+
const { error, success } = await run.output.toPromise();
7189

72-
if (error) {
73-
logger.error(error);
90+
if (error) {
91+
logger.error(error);
92+
}
93+
94+
return success ? 0 : 1;
95+
} finally {
96+
await run.stop();
97+
outputSubscription?.unsubscribe();
98+
}
99+
}
100+
101+
private builderStatsToAnalyticsParameters(
102+
stats: JsonValue,
103+
builderName: string,
104+
): Partial<
105+
| Record<EventCustomDimension & EventCustomMetric, string | number | undefined | boolean>
106+
| undefined
107+
> {
108+
if (!stats || typeof stats !== 'object' || !('durationInMs' in stats)) {
109+
return undefined;
74110
}
75111

76-
return success ? 0 : 1;
112+
const {
113+
optimization,
114+
allChunksCount,
115+
aot,
116+
lazyChunksCount,
117+
initialChunksCount,
118+
durationInMs,
119+
changedChunksCount,
120+
} = stats;
121+
122+
return {
123+
[EventCustomDimension.BuilderTarget]: builderName,
124+
[EventCustomDimension.Aot]: aot,
125+
[EventCustomDimension.Optimization]: optimization,
126+
[EventCustomMetric.AllChunksCount]: allChunksCount,
127+
[EventCustomMetric.LazyChunksCount]: lazyChunksCount,
128+
[EventCustomMetric.InitialChunksCount]: initialChunksCount,
129+
[EventCustomMetric.ChangedChunksCount]: changedChunksCount,
130+
[EventCustomMetric.DurationInMs]: durationInMs,
131+
};
77132
}
78133

79134
private _architectHost: WorkspaceNodeModulesArchitectHost | undefined;

0 commit comments

Comments
 (0)