Skip to content

Commit

Permalink
feat(@angular-devkit/architect): add analytics to builder context
Browse files Browse the repository at this point in the history
It should be NoopAnalytics if no analytics are supported.
  • Loading branch information
hansl authored and alexeagle committed Mar 28, 2019
1 parent ecd25a7 commit d25fb89
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 3 deletions.
8 changes: 7 additions & 1 deletion packages/angular_devkit/architect/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { experimental, json, logging } from '@angular-devkit/core';
import { analytics, experimental, json, logging } from '@angular-devkit/core';
import { Observable, from } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { Schema as RealBuilderInput, Target as RealTarget } from './input-schema';
Expand Down Expand Up @@ -234,6 +234,12 @@ export interface BuilderContext {
*/
reportProgress(current: number, total?: number, status?: string): void;

/**
* API to report analytics. This might be undefined if the feature is unsupported. This might
* not be undefined, but the backend could also not report anything.
*/
readonly analytics: analytics.Analytics;

/**
* Add teardown logic to this Context, so that when it's being stopped it will execute teardown.
*/
Expand Down
5 changes: 4 additions & 1 deletion packages/angular_devkit/architect/src/architect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { experimental, json, logging } from '@angular-devkit/core';
import { analytics, experimental, json, logging } from '@angular-devkit/core';
import { Observable, from, of } from 'rxjs';
import { concatMap, first, map, shareReplay, switchMap } from 'rxjs/operators';
import {
Expand Down Expand Up @@ -102,6 +102,7 @@ function _createJobHandlerFromBuilderInfo(

export interface ScheduleOptions {
logger?: logging.Logger;
analytics?: analytics.Analytics;
}


Expand Down Expand Up @@ -347,6 +348,7 @@ export class Architect {
logger: scheduleOptions.logger || new logging.NullLogger(),
currentDirectory: this._host.getCurrentDirectory(),
workspaceRoot: this._host.getWorkspaceRoot(),
analytics: scheduleOptions.analytics,
});
}
scheduleTarget(
Expand All @@ -359,6 +361,7 @@ export class Architect {
logger: scheduleOptions.logger || new logging.NullLogger(),
currentDirectory: this._host.getCurrentDirectory(),
workspaceRoot: this._host.getWorkspaceRoot(),
analytics: scheduleOptions.analytics,
});
}
}
4 changes: 3 additions & 1 deletion packages/angular_devkit/architect/src/create-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { experimental, isPromise, json, logging } from '@angular-devkit/core';
import { analytics, experimental, isPromise, json, logging } from '@angular-devkit/core';
import { Observable, Subscription, from, isObservable, of, throwError } from 'rxjs';
import { tap } from 'rxjs/operators';
import {
Expand Down Expand Up @@ -36,6 +36,7 @@ export function createBuilder<
const scheduler = context.scheduler;
const progressChannel = context.createChannel('progress');
const logChannel = context.createChannel('log');
const analyticsChannel = context.createChannel('analytics');
let currentState: BuilderProgressState = BuilderProgressState.Stopped;
const teardownLogics: Array<() => (PromiseLike<void> | void)> = [];
let tearingDown = false;
Expand Down Expand Up @@ -181,6 +182,7 @@ export function createBuilder<
progress({ state: currentState, current, total, status }, context);
}
},
analytics: new analytics.ForwardingAnalytics(report => analyticsChannel.next(report)),
addTeardown(teardown: () => (Promise<void> | void)): void {
teardownLogics.push(teardown);
},
Expand Down
9 changes: 9 additions & 0 deletions packages/angular_devkit/architect/src/schedule-by-name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { experimental, json, logging } from '@angular-devkit/core';
import { EMPTY, Subscription } from 'rxjs';
import { catchError, first, ignoreElements, map, share, shareReplay, tap } from 'rxjs/operators';
import { Analytics, AnalyticsReport, AnalyticsReporter } from '../../core/src/analytics';
import {
BuilderInfo,
BuilderInput,
Expand All @@ -31,6 +32,7 @@ export async function scheduleByName(
logger: logging.LoggerApi,
workspaceRoot: string | Promise<string>,
currentDirectory: string | Promise<string>,
analytics?: Analytics,
},
): Promise<BuilderRun> {
const childLoggerName = options.target ? `{${targetStringFromTarget(options.target)}}` : name;
Expand Down Expand Up @@ -88,6 +90,12 @@ export async function scheduleByName(
shareReplay(),
);

// If there's an analytics object, take the job channel and report it to the analytics.
if (options.analytics) {
const reporter = new AnalyticsReporter(options.analytics);
job.getChannel<AnalyticsReport>('analytics')
.subscribe(report => reporter.report(report));
}
// Start the builder.
output.pipe(first()).subscribe({
error() {},
Expand Down Expand Up @@ -121,6 +129,7 @@ export async function scheduleByTarget(
logger: logging.LoggerApi,
workspaceRoot: string | Promise<string>,
currentDirectory: string | Promise<string>,
analytics?: Analytics,
},
): Promise<BuilderRun> {
return scheduleByName(`{${targetStringFromTarget(target)}}`, overrides, {
Expand Down

0 comments on commit d25fb89

Please sign in to comment.