diff --git a/packages/angular/cli/models/analytics.ts b/packages/angular/cli/models/analytics.ts index 42674a769ca0..dec1a0567f82 100644 --- a/packages/angular/cli/models/analytics.ts +++ b/packages/angular/cli/models/analytics.ts @@ -14,6 +14,7 @@ import * as os from 'os'; import * as ua from 'universal-analytics'; import { v4 as uuidV4 } from 'uuid'; import { getWorkspace, getWorkspaceRaw } from '../utilities/config'; +import { isTTY } from '../utilities/tty'; const analyticsDebug = debug('ng:analytics'); // Generate analytics, including settings and users. const analyticsLogDebug = debug('ng:analytics:log'); // Actual logs of events. @@ -359,7 +360,7 @@ export function setAnalyticsConfig(level: 'global' | 'local', value: string | bo */ export async function promptGlobalAnalytics(force = false) { analyticsDebug('prompting global analytics.'); - if (force || (process.stdout.isTTY && process.stdin.isTTY)) { + if (force || isTTY()) { const answers = await inquirer.prompt<{ analytics: boolean }>([ { type: 'confirm', @@ -407,7 +408,7 @@ export async function promptProjectAnalytics(force = false): Promise { throw new Error(`Could not find a local workspace. Are you in a project?`); } - if (force || (process.stdout.isTTY && process.stdin.isTTY)) { + if (force || isTTY()) { const answers = await inquirer.prompt<{ analytics: boolean }>([ { type: 'confirm', @@ -448,7 +449,7 @@ export function hasGlobalAnalyticsConfiguration(): boolean { && globalWorkspace.getCli() && globalWorkspace.getCli()['analytics']; - if (analyticsConfig !== undefined) { + if (analyticsConfig !== null && analyticsConfig !== undefined) { return true; } } catch {} diff --git a/packages/angular/cli/models/schematic-command.ts b/packages/angular/cli/models/schematic-command.ts index 7b99766c6b05..7cbc13e807c3 100644 --- a/packages/angular/cli/models/schematic-command.ts +++ b/packages/angular/cli/models/schematic-command.ts @@ -37,6 +37,7 @@ import { } from '../utilities/config'; import { parseJsonSchemaToOptions } from '../utilities/json-schema'; import { getPackageManager } from '../utilities/package-manager'; +import { isTTY } from '../utilities/tty'; import { isPackageNameSafeForAnalytics } from './analytics'; import { BaseCommandOptions, Command } from './command'; import { Arguments, CommandContext, CommandDescription, Option } from './interface'; @@ -299,7 +300,7 @@ export abstract class SchematicCommand< return undefined; }); - if (options.interactive !== false && process.stdout.isTTY) { + if (options.interactive !== false && isTTY()) { workflow.registry.usePromptProvider((definitions: Array) => { const questions: inquirer.Questions = definitions.map(definition => { const question: inquirer.Question = { diff --git a/packages/angular/cli/utilities/tty.ts b/packages/angular/cli/utilities/tty.ts new file mode 100644 index 000000000000..1b168be93dab --- /dev/null +++ b/packages/angular/cli/utilities/tty.ts @@ -0,0 +1,15 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * 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 + */ +export function isTTY(): boolean { + const force = process.env['NG_FORCE_TTY']; + if (force !== undefined) { + return !(force === '0' || force.toUpperCase() === 'FALSE'); + } + + return !!process.stdout.isTTY && !!process.stdin.isTTY; +} diff --git a/tests/legacy-cli/e2e/tests/misc/ask-analytics.ts b/tests/legacy-cli/e2e/tests/misc/ask-analytics.ts new file mode 100644 index 000000000000..1bd61b7b1138 --- /dev/null +++ b/tests/legacy-cli/e2e/tests/misc/ask-analytics.ts @@ -0,0 +1,34 @@ +import { createDir, rimraf } from '../../utils/fs'; +import { + execWithEnv, + killAllProcesses, + waitForAnyProcessOutputToMatch, +} from '../../utils/process'; + +const packages = require('../../../../../lib/packages').packages; + +export default async function() { + // Create a temporary directory to install the CLI + await createDir('../ask-analytics'); + const cwd = process.cwd(); + process.chdir('../ask-analytics'); + + try { + // Install the CLI with TTY force enabled + const execution = execWithEnv( + 'npm', + ['install', packages['@angular/cli'].tar], + { ...process.env, 'NG_FORCE_TTY': '1' }, + ); + + // Check if the prompt is shown + await waitForAnyProcessOutputToMatch(/Would you like to share anonymous usage data/); + + } finally { + killAllProcesses(); + + // Cleanup + process.chdir(cwd); + await rimraf('../ask-analytics'); + } +}