diff --git a/packages/angular/cli/src/utilities/environment-options.ts b/packages/angular/cli/src/utilities/environment-options.ts index 0f01ce8b09cb..4c4e1b734444 100644 --- a/packages/angular/cli/src/utilities/environment-options.ts +++ b/packages/angular/cli/src/utilities/environment-options.ts @@ -6,28 +6,63 @@ * found in the LICENSE file at https://angular.dev/license */ -function isPresent(variable: string | undefined): variable is string { - return typeof variable === 'string' && variable !== ''; -} +/** A set of strings that are considered "truthy" when parsing environment variables. */ +const TRUTHY_VALUES = new Set(['1', 'true']); -function isDisabled(variable: string | undefined): boolean { - return isPresent(variable) && (variable === '0' || variable.toLowerCase() === 'false'); -} +/** A set of strings that are considered "falsy" when parsing environment variables. */ +const FALSY_VALUES = new Set(['0', 'false']); -function isEnabled(variable: string | undefined): boolean { - return isPresent(variable) && (variable === '1' || variable.toLowerCase() === 'true'); +/** + * Checks if an environment variable is present and has a non-empty value. + * @param variable The environment variable to check. + * @returns `true` if the variable is a non-empty string. + */ +function isPresent(variable: string | undefined): variable is string { + return typeof variable === 'string' && variable !== ''; } -function optional(variable: string | undefined): boolean | undefined { +/** + * Parses an environment variable into a boolean or undefined. + * @returns `true` if the variable is truthy ('1', 'true'). + * @returns `false` if the variable is falsy ('0', 'false'). + * @returns `undefined` if the variable is not present or has an unknown value. + */ +function parseTristate(variable: string | undefined): boolean | undefined { if (!isPresent(variable)) { return undefined; } - return isEnabled(variable); + const value = variable.toLowerCase(); + if (TRUTHY_VALUES.has(value)) { + return true; + } + if (FALSY_VALUES.has(value)) { + return false; + } + + return undefined; } -export const analyticsDisabled = isDisabled(process.env['NG_CLI_ANALYTICS']); -export const isCI = isEnabled(process.env['CI']); -export const disableVersionCheck = isEnabled(process.env['NG_DISABLE_VERSION_CHECK']); -export const ngDebug = isEnabled(process.env['NG_DEBUG']); -export const forceAutocomplete = optional(process.env['NG_FORCE_AUTOCOMPLETE']); +/** Disables all analytics reporting when the `NG_CLI_ANALYTICS` environment variable is set to '0' or 'false'. */ +export const analyticsDisabled = parseTristate(process.env['NG_CLI_ANALYTICS']) === false; + +/** Identifies when the CLI is running in a Continuous Integration environment. */ +export const isCI = parseTristate(process.env['CI']) === true; + +/** Disables the automatic version check when the `NG_DISABLE_VERSION_CHECK` environment variable is enabled. */ +export const disableVersionCheck = parseTristate(process.env['NG_DISABLE_VERSION_CHECK']) === true; + +/** Enables debugging messages when the `NG_DEBUG` environment variable is enabled. */ +export const ngDebug = parseTristate(process.env['NG_DEBUG']) === true; + +/** + * Forces the autocomplete script to be generated. + * The `NG_FORCE_AUTOCOMPLETE` environment variable can be 'true', 'false', or undefined (for default behavior). + */ +export const forceAutocomplete = parseTristate(process.env['NG_FORCE_AUTOCOMPLETE']); + +/** + * When enabled, forces TTY mode. + * The `NG_FORCE_TTY` environment variable can be 'true', 'false', or undefined (for default behavior). + */ +export const forceTty = parseTristate(process.env['NG_FORCE_TTY']); diff --git a/packages/angular/cli/src/utilities/tty.ts b/packages/angular/cli/src/utilities/tty.ts index db6543926941..e8750b7c79fe 100644 --- a/packages/angular/cli/src/utilities/tty.ts +++ b/packages/angular/cli/src/utilities/tty.ts @@ -6,17 +6,16 @@ * found in the LICENSE file at https://angular.dev/license */ -function _isTruthy(value: undefined | string): boolean { - // Returns true if value is a string that is anything but 0 or false. - return value !== undefined && value !== '0' && value.toUpperCase() !== 'FALSE'; -} +import { forceTty, isCI } from './environment-options'; +/** + * Determines if the `stream` is a TTY. + * + * @param stream A NodeJS stream to check. Defaults to `process.stdout`. + * @returns `true` if the `stream` is a TTY, `false` otherwise. This detection is overridden + * by the `NG_FORCE_TTY` environment variable. In a CI environment, this will also be `false` + * unless `NG_FORCE_TTY` is set. + */ export function isTTY(stream: NodeJS.WriteStream = process.stdout): boolean { - // If we force TTY, we always return true. - const force = process.env['NG_FORCE_TTY']; - if (force !== undefined) { - return _isTruthy(force); - } - - return !!stream.isTTY && !_isTruthy(process.env['CI']); + return forceTty ?? (!!stream.isTTY && !isCI); }