Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(@angular/cli): check/prompt for workspace level analytics configuration #14264

Merged
merged 1 commit into from
Sep 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions packages/angular/cli/models/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,67 @@ export async function getGlobalAnalytics(): Promise<UniversalAnalytics | undefin
}
}

export async function hasWorkspaceAnalyticsConfiguration(): Promise<boolean> {
try {
const globalWorkspace = await getWorkspace('local');
const analyticsConfig: string | undefined | null | { uid?: string } = globalWorkspace
&& globalWorkspace.getCli()
&& globalWorkspace.getCli()['analytics'];

if (analyticsConfig !== undefined) {
return true;
}
} catch {}

return false;
}

/**
* Get the workspace analytics object for the user. This returns an instance of UniversalAnalytics,
* or undefined if analytics are disabled.
*
* If any problem happens, it is considered the user has been opting out of analytics.
*/
export async function getWorkspaceAnalytics(): Promise<UniversalAnalytics | undefined> {
analyticsDebug('getWorkspaceAnalytics');
try {
const globalWorkspace = await getWorkspace('local');
const analyticsConfig: string | undefined | null | { uid?: string } = globalWorkspace
&& globalWorkspace.getCli()
&& globalWorkspace.getCli()['analytics'];
analyticsDebug('Workspace Analytics config found: %j', analyticsConfig);

if (analyticsConfig === false) {
analyticsDebug('Analytics disabled. Ignoring all analytics.');

return undefined;
} else if (analyticsConfig === undefined || analyticsConfig === null) {
analyticsDebug('Analytics settings not found. Ignoring all analytics.');

return undefined;
} else {
let uid: string | undefined = undefined;
if (typeof analyticsConfig == 'string') {
uid = analyticsConfig;
} else if (typeof analyticsConfig == 'object' && typeof analyticsConfig['uid'] == 'string') {
uid = analyticsConfig['uid'];
}

analyticsDebug('client id: %j', uid);
if (uid == undefined) {
return undefined;
}

return new UniversalAnalytics(AnalyticsProperties.AngularCliDefault, uid);
}
} catch (err) {
analyticsDebug('Error happened during reading of analytics config: %s', err.message);

return undefined;
}

}

/**
* Return the usage analytics sharing setting, which is either a property string (GA-XXXXXXX-XX),
* or undefined if no sharing.
Expand Down
25 changes: 21 additions & 4 deletions packages/angular/cli/models/command-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ import * as debug from 'debug';
import { readFileSync } from 'fs';
import { join, resolve } from 'path';
import { parseJsonSchemaToCommandDescription } from '../utilities/json-schema';
import { UniversalAnalytics, getGlobalAnalytics, getSharedAnalytics } from './analytics';
import {
getGlobalAnalytics,
getSharedAnalytics,
getWorkspaceAnalytics,
hasWorkspaceAnalyticsConfiguration,
promptProjectAnalytics,
} from './analytics';
import { Command } from './command';
import { CommandDescription, CommandWorkspace } from './interface';
import * as parser from './parser';
Expand Down Expand Up @@ -58,8 +64,19 @@ export interface CommandMapOptions {
* Create the analytics instance.
* @private
*/
async function _createAnalytics(): Promise<analytics.Analytics> {
const config = await getGlobalAnalytics();
async function _createAnalytics(workspace: boolean): Promise<analytics.Analytics> {
let config = await getGlobalAnalytics();
// If in workspace and global analytics is enabled, defer to workspace level
if (workspace && config) {
// TODO: This should honor the `no-interactive` option.
// It is currently not an `ng` option but rather only an option for specific commands.
// The concept of `ng`-wide options are needed to cleanly handle this.
if (!(await hasWorkspaceAnalyticsConfiguration())) {
await promptProjectAnalytics();
}
config = await getWorkspaceAnalytics();
}

const maybeSharedAnalytics = await getSharedAnalytics();

if (config && maybeSharedAnalytics) {
Expand Down Expand Up @@ -214,7 +231,7 @@ export async function runCommand(
return map;
});

const analytics = options.analytics || await _createAnalytics();
const analytics = options.analytics || await _createAnalytics(!!workspace.configFile);
const context = { workspace, analytics };
const command = new description.impl(context, description, logger);

Expand Down