From 622d08447d3f65ddd7438beda477cecc9be9c93e Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 10 Sep 2020 17:25:25 +0200 Subject: [PATCH] refactor: use ansi-colors instead of removed terminal utils --- bin/devkit-admin | 12 ++++---- packages/angular/cli/lib/cli/index.ts | 12 ++++---- packages/angular/cli/utilities/color.ts | 14 +++++---- .../angular_devkit/architect_cli/BUILD.bazel | 1 + .../architect_cli/bin/architect.ts | 21 ++++++++++---- .../angular_devkit/architect_cli/package.json | 1 + packages/angular_devkit/benchmark/BUILD.bazel | 1 + .../angular_devkit/benchmark/package.json | 1 + packages/angular_devkit/benchmark/src/main.ts | 15 ++++++---- .../angular_devkit/build_angular/BUILD.bazel | 1 + .../angular_devkit/build_angular/package.json | 1 + .../src/angular-cli-files/utilities/stats.ts | 24 +++++++-------- .../build_angular/src/utils/color.ts | 29 +++++++++++++++++++ .../angular_devkit/core/node/cli-logger.ts | 13 +++------ packages/angular_devkit/core/node/index.ts | 1 + .../angular_devkit/schematics_cli/BUILD.bazel | 1 + .../schematics_cli/bin/schematics.ts | 24 +++++++++++---- .../schematics_cli/package.json | 1 + scripts/benchmark.ts | 7 +++-- tests/legacy-cli/e2e/utils/process.ts | 17 ++++++----- tests/legacy-cli/e2e_runner.ts | 28 +++++++++++------- 21 files changed, 149 insertions(+), 76 deletions(-) create mode 100644 packages/angular_devkit/build_angular/src/utils/color.ts diff --git a/bin/devkit-admin b/bin/devkit-admin index f356b0d42e96..707a854a5b37 100755 --- a/bin/devkit-admin +++ b/bin/devkit-admin @@ -33,19 +33,19 @@ process.chdir(path.join(__dirname, '..')); let logger = null; try { logger = new (require('@angular-devkit/core').logging.IndentLogger)('root'); - const { bold, gray, red, yellow, white } = require('@angular-devkit/core').terminal; + const colors = require('ansi-colors').create(); const filter = require('rxjs/operators').filter; logger .pipe(filter(entry => (entry.level !== 'debug' || args.verbose))) .subscribe(entry => { - let color = gray; + let color = colors.gray; let output = process.stdout; switch (entry.level) { - case 'info': color = white; break; - case 'warn': color = yellow; break; - case 'error': color = red; output = process.stderr; break; - case 'fatal': color = x => bold(red(x)); output = process.stderr; break; + case 'info': color = colors.white; break; + case 'warn': color = colors.yellow; break; + case 'error': color = colors.red; output = process.stderr; break; + case 'fatal': color = x => colors.bold.red(x); output = process.stderr; break; } output.write(color(entry.message) + '\n'); diff --git a/packages/angular/cli/lib/cli/index.ts b/packages/angular/cli/lib/cli/index.ts index 170fb6012ac1..cf0cacdb715d 100644 --- a/packages/angular/cli/lib/cli/index.ts +++ b/packages/angular/cli/lib/cli/index.ts @@ -8,7 +8,7 @@ import { createConsoleLogger } from '@angular-devkit/core/node'; import { format } from 'util'; import { runCommand } from '../../models/command-runner'; -import { colors, removeColor, supportsColor } from '../../utilities/color'; +import { colors, removeColor } from '../../utilities/color'; import { getWorkspaceRaw } from '../../utilities/config'; import { writeErrorToLogFile } from '../../utilities/log-file'; import { getWorkspaceDetails } from '../../utilities/project'; @@ -49,11 +49,11 @@ export default async function(options: { testing?: boolean; cliArgs: string[] }) } const logger = createConsoleLogger(isDebug, process.stdout, process.stderr, { - info: s => (supportsColor ? s : removeColor(s)), - debug: s => (supportsColor ? s : removeColor(s)), - warn: s => (supportsColor ? colors.bold.yellow(s) : removeColor(s)), - error: s => (supportsColor ? colors.bold.red(s) : removeColor(s)), - fatal: s => (supportsColor ? colors.bold.red(s) : removeColor(s)), + info: s => (colors.enabled ? s : removeColor(s)), + debug: s => (colors.enabled ? s : removeColor(s)), + warn: s => (colors.enabled ? colors.bold.yellow(s) : removeColor(s)), + error: s => (colors.enabled ? colors.bold.red(s) : removeColor(s)), + fatal: s => (colors.enabled ? colors.bold.red(s) : removeColor(s)), }); // Redirect console to logger diff --git a/packages/angular/cli/utilities/color.ts b/packages/angular/cli/utilities/color.ts index d0a12c4a472e..6e7d11cb7fe2 100644 --- a/packages/angular/cli/utilities/color.ts +++ b/packages/angular/cli/utilities/color.ts @@ -8,18 +8,22 @@ import * as ansiColors from 'ansi-colors'; import { WriteStream } from 'tty'; +type AnsiColors = typeof ansiColors; + // Typings do not contain the function call (added in Node.js v9.9.0) -export const supportsColor = +const supportsColor = process.stdout instanceof WriteStream && ((process.stdout as unknown) as { getColorDepth(): number }).getColorDepth() > 1; export function removeColor(text: string): string { - return text.replace(new RegExp(ansiColors.ansiRegex), ''); + // This has been created because when colors.enabled is false unstyle doesn't work + // see: https://github.com/doowb/ansi-colors/blob/a4794363369d7b4d1872d248fc43a12761640d8e/index.js#L38 + return text.replace(ansiColors.ansiRegex, ''); } -// create a separate instance to prevent unintended global changes to the color configuration -// create function is not defined in the typings -const colors = (ansiColors as typeof ansiColors & { create: () => typeof ansiColors }).create(); +// Create a separate instance to prevent unintended global changes to the color configuration +// Create function is not defined in the typings. See: https://github.com/doowb/ansi-colors/pull/44 +const colors = (ansiColors as AnsiColors & { create: () => AnsiColors }).create(); colors.enabled = supportsColor; export { colors }; diff --git a/packages/angular_devkit/architect_cli/BUILD.bazel b/packages/angular_devkit/architect_cli/BUILD.bazel index 00c683c7cbbc..99c780a3c7f2 100644 --- a/packages/angular_devkit/architect_cli/BUILD.bazel +++ b/packages/angular_devkit/architect_cli/BUILD.bazel @@ -22,6 +22,7 @@ ts_library( "@npm//@types/minimist", "@npm//@types/node", "@npm//@types/progress", + "@npm//ansi-colors", "@npm//rxjs", ], ) diff --git a/packages/angular_devkit/architect_cli/bin/architect.ts b/packages/angular_devkit/architect_cli/bin/architect.ts index f2c7bb87a02c..668bb4270ab9 100644 --- a/packages/angular_devkit/architect_cli/bin/architect.ts +++ b/packages/angular_devkit/architect_cli/bin/architect.ts @@ -8,8 +8,9 @@ */ import { Architect, BuilderInfo, BuilderProgressState, Target } from '@angular-devkit/architect'; import { WorkspaceNodeModulesArchitectHost } from '@angular-devkit/architect/node'; -import { logging, schema, tags, terminal, workspaces } from '@angular-devkit/core'; +import { logging, schema, tags, workspaces } from '@angular-devkit/core'; import { NodeJsSyncHost, createConsoleLogger } from '@angular-devkit/core/node'; +import * as ansiColors from 'ansi-colors'; import { existsSync } from 'fs'; import * as minimist from 'minimist'; import * as path from 'path'; @@ -68,6 +69,10 @@ interface BarInfo { target?: Target; } +// Create a separate instance to prevent unintended global changes to the color configuration +// Create function is not defined in the typings. See: https://github.com/doowb/ansi-colors/pull/44 +const colors = (ansiColors as typeof ansiColors & { create: () => typeof ansiColors }).create(); + async function _executeTarget( parentLogger: logging.Logger, workspace: workspaces.WorkspaceDefinition, @@ -139,9 +144,9 @@ async function _executeTarget( .pipe( tap(result => { if (result.success) { - parentLogger.info(terminal.green('SUCCESS')); + parentLogger.info(colors.green('SUCCESS')); } else { - parentLogger.info(terminal.yellow('FAILURE')); + parentLogger.info(colors.red('FAILURE')); } parentLogger.info('Result: ' + JSON.stringify({ ...result, info: undefined }, null, 4)); @@ -157,7 +162,7 @@ async function _executeTarget( return success ? 0 : 1; } catch (err) { - parentLogger.info(terminal.red('ERROR')); + parentLogger.info(colors.red('ERROR')); parentLogger.info('\nLogs:'); logs.forEach(l => parentLogger.next(l)); @@ -173,7 +178,13 @@ async function main(args: string[]): Promise { const argv = minimist(args, { boolean: ['help'] }); /** Create the DevKit Logger used through the CLI. */ - const logger = createConsoleLogger(argv['verbose']); + const logger = createConsoleLogger(argv['verbose'], process.stdout, process.stderr, { + info: s => s, + debug: s => s, + warn: s => colors.bold.yellow(s), + error: s => colors.bold.red(s), + fatal: s => colors.bold.red(s), + }); // Check the target. const targetStr = argv._[0] || ''; diff --git a/packages/angular_devkit/architect_cli/package.json b/packages/angular_devkit/architect_cli/package.json index be8b19f951ec..98840fcf1758 100644 --- a/packages/angular_devkit/architect_cli/package.json +++ b/packages/angular_devkit/architect_cli/package.json @@ -15,6 +15,7 @@ "dependencies": { "@angular-devkit/architect": "0.0.0", "@angular-devkit/core": "0.0.0", + "ansi-colors": "4.1.1", "minimist": "1.2.5", "progress": "2.0.3", "rxjs": "6.6.3", diff --git a/packages/angular_devkit/benchmark/BUILD.bazel b/packages/angular_devkit/benchmark/BUILD.bazel index 74988797dfa3..a2a51076e6a1 100644 --- a/packages/angular_devkit/benchmark/BUILD.bazel +++ b/packages/angular_devkit/benchmark/BUILD.bazel @@ -32,6 +32,7 @@ ts_library( "@npm//@types/minimist", "@npm//@types/node", "@npm//@types/pidusage", + "@npm//ansi-colors", "@npm//rxjs", ], ) diff --git a/packages/angular_devkit/benchmark/package.json b/packages/angular_devkit/benchmark/package.json index 28ee333b195c..4a482add2b80 100644 --- a/packages/angular_devkit/benchmark/package.json +++ b/packages/angular_devkit/benchmark/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "@angular-devkit/core": "0.0.0", + "ansi-colors": "4.1.1", "minimist": "1.2.5", "pidusage": "2.0.21", "pidtree": "0.5.0", diff --git a/packages/angular_devkit/benchmark/src/main.ts b/packages/angular_devkit/benchmark/src/main.ts index 7c0e9d08bae7..96396c9bc544 100644 --- a/packages/angular_devkit/benchmark/src/main.ts +++ b/packages/angular_devkit/benchmark/src/main.ts @@ -7,8 +7,9 @@ * found in the LICENSE file at https://angular.io/license */ -import { logging, tags, terminal } from '@angular-devkit/core'; +import { logging, tags } from '@angular-devkit/core'; import { ProcessOutput } from '@angular-devkit/core/node'; +import * as ansiColors from 'ansi-colors'; import { appendFileSync, writeFileSync } from 'fs'; import * as minimist from 'minimist'; import { filter, map, toArray } from 'rxjs/operators'; @@ -102,26 +103,30 @@ export async function main({ })), ); + // Create a separate instance to prevent unintended global changes to the color configuration + // Create function is not defined in the typings. See: https://github.com/doowb/ansi-colors/pull/44 + const colors = (ansiColors as typeof ansiColors & { create: () => typeof ansiColors }).create(); + // Log to console. logger .pipe(filter(entry => (entry.level != 'debug' || argv['verbose']))) .subscribe(entry => { - let color: (s: string) => string = x => terminal.dim(terminal.white(x)); + let color: (s: string) => string = x => colors.dim.white(x); let output = stdout; switch (entry.level) { case 'info': color = s => s; break; case 'warn': - color = terminal.yellow; + color = colors.yellow; output = stderr; break; case 'error': - color = terminal.red; + color = colors.red; output = stderr; break; case 'fatal': - color = (x: string) => terminal.bold(terminal.red(x)); + color = (x: string) => colors.bold.red(x); output = stderr; break; } diff --git a/packages/angular_devkit/build_angular/BUILD.bazel b/packages/angular_devkit/build_angular/BUILD.bazel index f69e08e555ac..acb75903b1c8 100644 --- a/packages/angular_devkit/build_angular/BUILD.bazel +++ b/packages/angular_devkit/build_angular/BUILD.bazel @@ -131,6 +131,7 @@ ts_library( "@npm//@types/webpack-dev-server", "@npm//@types/webpack-sources", "@npm//ajv", + "@npm//ansi-colors", "@npm//autoprefixer", "@npm//babel-loader", "@npm//browserslist", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 7bf9b07d14a0..95c37a148bd1 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -19,6 +19,7 @@ "@babel/template": "7.10.4", "@jsdevtools/coverage-istanbul-loader": "3.0.5", "@ngtools/webpack": "0.0.0", + "ansi-colors": "4.1.1", "autoprefixer": "9.8.6", "babel-loader": "8.1.0", "browserslist": "^4.9.1", diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/stats.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/stats.ts index bb7881e46b0b..e5c699684a2c 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/stats.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/utilities/stats.ts @@ -7,12 +7,10 @@ */ // tslint:disable // TODO: cleanup this file, it's copied as is from Angular CLI. -import { logging, tags, terminal } from '@angular-devkit/core'; +import { logging, tags } from '@angular-devkit/core'; import { WebpackLoggingCallback } from '@angular-devkit/build-webpack'; import * as path from 'path'; - - -const { bold, green, red, reset, white, yellow } = terminal; +import { colors as ansiColors } from '../../utils/color'; export function formatSize(size: number): string { if (size <= 0) { @@ -37,8 +35,8 @@ export function generateBundleStats( }, colors: boolean, ): string { - const g = (x: string) => (colors ? bold(green(x)) : x); - const y = (x: string) => (colors ? bold(yellow(x)) : x); + const g = (x: string) => (colors ? ansiColors.bold.green(x) : x); + const y = (x: string) => (colors ? ansiColors.bold.yellow(x) : x); const id = info.id ? y(info.id.toString()) : ''; const size = typeof info.size === 'number' ? ` ${formatSize(info.size)}` : ''; @@ -53,14 +51,14 @@ export function generateBundleStats( } export function generateBuildStats(hash: string, time: number, colors: boolean): string { - const w = (x: string) => colors ? bold(white(x)) : x; + const w = (x: string) => colors ? ansiColors.bold.white(x) : x; return `Date: ${w(new Date().toISOString())} - Hash: ${w(hash)} - Time: ${w('' + time)}ms` } export function statsToString(json: any, statsConfig: any) { const colors = statsConfig.colors; - const rs = (x: string) => colors ? reset(x) : x; - const w = (x: string) => colors ? bold(white(x)) : x; + const rs = (x: string) => colors ? ansiColors.reset(x) : x; + const w = (x: string) => colors ? ansiColors.bold.white(x) : x; const changedChunksStats = json.chunks .filter((chunk: any) => chunk.rendered) @@ -97,8 +95,8 @@ const ERRONEOUS_WARNINGS_FILTER = (warning: string) => ![ export function statsWarningsToString(json: any, statsConfig: any): string { const colors = statsConfig.colors; - const rs = (x: string) => colors ? reset(x) : x; - const y = (x: string) => colors ? bold(yellow(x)) : x; + const rs = (x: string) => colors ? ansiColors.reset(x) : x; + const y = (x: string) => colors ? ansiColors.bold.yellow(x) : x; const warnings = [...json.warnings]; if (json.children) { warnings.push(...json.children @@ -116,8 +114,8 @@ export function statsWarningsToString(json: any, statsConfig: any): string { export function statsErrorsToString(json: any, statsConfig: any): string { const colors = statsConfig.colors; - const rs = (x: string) => colors ? reset(x) : x; - const r = (x: string) => colors ? bold(red(x)) : x; + const rs = (x: string) => colors ? ansiColors.reset(x) : x; + const r = (x: string) => colors ? ansiColors.bold.red(x) : x; const errors = [...json.errors]; if (json.children) { errors.push(...json.children diff --git a/packages/angular_devkit/build_angular/src/utils/color.ts b/packages/angular_devkit/build_angular/src/utils/color.ts new file mode 100644 index 000000000000..6e7d11cb7fe2 --- /dev/null +++ b/packages/angular_devkit/build_angular/src/utils/color.ts @@ -0,0 +1,29 @@ +/** + * @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 + */ +import * as ansiColors from 'ansi-colors'; +import { WriteStream } from 'tty'; + +type AnsiColors = typeof ansiColors; + +// Typings do not contain the function call (added in Node.js v9.9.0) +const supportsColor = + process.stdout instanceof WriteStream && + ((process.stdout as unknown) as { getColorDepth(): number }).getColorDepth() > 1; + +export function removeColor(text: string): string { + // This has been created because when colors.enabled is false unstyle doesn't work + // see: https://github.com/doowb/ansi-colors/blob/a4794363369d7b4d1872d248fc43a12761640d8e/index.js#L38 + return text.replace(ansiColors.ansiRegex, ''); +} + +// Create a separate instance to prevent unintended global changes to the color configuration +// Create function is not defined in the typings. See: https://github.com/doowb/ansi-colors/pull/44 +const colors = (ansiColors as AnsiColors & { create: () => AnsiColors }).create(); +colors.enabled = supportsColor; + +export { colors }; diff --git a/packages/angular_devkit/core/node/cli-logger.ts b/packages/angular_devkit/core/node/cli-logger.ts index 2a9eb1562f47..07cb5ef39aa9 100644 --- a/packages/angular_devkit/core/node/cli-logger.ts +++ b/packages/angular_devkit/core/node/cli-logger.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import { filter } from 'rxjs/operators'; -import { logging, terminal } from '../src'; +import { logging } from '../src'; export interface ProcessOutput { write(buffer: string | Buffer): boolean; @@ -24,20 +24,15 @@ export function createConsoleLogger( const logger = new logging.IndentLogger('cling'); logger - .pipe(filter(entry => (entry.level != 'debug' || verbose))) + .pipe(filter(entry => entry.level !== 'debug' || verbose)) .subscribe(entry => { - let color = colors && colors[entry.level]; + const color = colors && colors[entry.level]; let output = stdout; + switch (entry.level) { - case 'info': - break; case 'warn': - color = color || (s => terminal.bold(terminal.yellow(s))); - output = stderr; - break; case 'fatal': case 'error': - color = color || (s => terminal.bold(terminal.red(s))); output = stderr; break; } diff --git a/packages/angular_devkit/core/node/index.ts b/packages/angular_devkit/core/node/index.ts index 119ba6c961ad..3f3e175f4315 100644 --- a/packages/angular_devkit/core/node/index.ts +++ b/packages/angular_devkit/core/node/index.ts @@ -5,6 +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 * as experimental from './experimental/jobs/job-registry'; import * as fs from './fs'; export * from './cli-logger'; diff --git a/packages/angular_devkit/schematics_cli/BUILD.bazel b/packages/angular_devkit/schematics_cli/BUILD.bazel index 8e7e2e2f50d0..c55b903cdd8e 100644 --- a/packages/angular_devkit/schematics_cli/BUILD.bazel +++ b/packages/angular_devkit/schematics_cli/BUILD.bazel @@ -41,6 +41,7 @@ ts_library( "@npm//@types/inquirer", "@npm//@types/minimist", "@npm//@types/node", + "@npm//ansi-colors", "@npm//inquirer", # @external "@npm//minimist", # @external "@npm//rxjs", diff --git a/packages/angular_devkit/schematics_cli/bin/schematics.ts b/packages/angular_devkit/schematics_cli/bin/schematics.ts index 995da0589705..a48242c7408f 100644 --- a/packages/angular_devkit/schematics_cli/bin/schematics.ts +++ b/packages/angular_devkit/schematics_cli/bin/schematics.ts @@ -16,7 +16,6 @@ import { normalize, schema, tags, - terminal, virtualFs, } from '@angular-devkit/core'; import { NodeJsSyncHost, ProcessOutput, createConsoleLogger } from '@angular-devkit/core/node'; @@ -26,6 +25,7 @@ import { formats, } from '@angular-devkit/schematics'; import { NodeWorkflow, validateOptionsWithSchema } from '@angular-devkit/schematics/tools'; +import * as ansiColors from 'ansi-colors'; import * as inquirer from 'inquirer'; import * as minimist from 'minimist'; @@ -117,6 +117,7 @@ function _createPromptProvider(): schema.PromptProvider { }; } +// tslint:disable-next-line: no-big-function export async function main({ args, stdout = process.stdout, @@ -124,8 +125,19 @@ export async function main({ }: MainOptions): Promise<0 | 1> { const argv = parseArgs(args); + // Create a separate instance to prevent unintended global changes to the color configuration + // Create function is not defined in the typings. See: https://github.com/doowb/ansi-colors/pull/44 + const colors = (ansiColors as typeof ansiColors & { create: () => typeof ansiColors }).create(); + /** Create the DevKit Logger used through the CLI. */ - const logger = createConsoleLogger(argv['verbose'], stdout, stderr); + const logger = createConsoleLogger(argv['verbose'], stdout, stderr, { + info: s => s, + debug: s => s, + warn: s => colors.bold.yellow(s), + error: s => colors.bold.red(s), + fatal: s => colors.bold.red(s), + }); + if (argv.help) { logger.info(getUsage()); @@ -205,20 +217,20 @@ export async function main({ break; case 'update': loggingQueue.push(tags.oneLine` - ${terminal.white('UPDATE')} ${eventPath} (${event.content.length} bytes) + ${colors.white('UPDATE')} ${eventPath} (${event.content.length} bytes) `); break; case 'create': loggingQueue.push(tags.oneLine` - ${terminal.green('CREATE')} ${eventPath} (${event.content.length} bytes) + ${colors.green('CREATE')} ${eventPath} (${event.content.length} bytes) `); break; case 'delete': - loggingQueue.push(`${terminal.yellow('DELETE')} ${eventPath}`); + loggingQueue.push(`${colors.yellow('DELETE')} ${eventPath}`); break; case 'rename': const eventToPath = event.to.startsWith('/') ? event.to.substr(1) : event.to; - loggingQueue.push(`${terminal.blue('RENAME')} ${eventPath} => ${eventToPath}`); + loggingQueue.push(`${colors.blue('RENAME')} ${eventPath} => ${eventToPath}`); break; } }); diff --git a/packages/angular_devkit/schematics_cli/package.json b/packages/angular_devkit/schematics_cli/package.json index 69e132efd2a1..e3eacfc67846 100644 --- a/packages/angular_devkit/schematics_cli/package.json +++ b/packages/angular_devkit/schematics_cli/package.json @@ -18,6 +18,7 @@ "@angular-devkit/core": "0.0.0", "@angular-devkit/schematics": "0.0.0", "@schematics/schematics": "0.0.0", + "ansi-colors": "4.1.1", "inquirer": "7.3.3", "minimist": "1.2.5", "rxjs": "6.6.3", diff --git a/scripts/benchmark.ts b/scripts/benchmark.ts index 0fe179b9ac9a..4c02e85ca11f 100644 --- a/scripts/benchmark.ts +++ b/scripts/benchmark.ts @@ -7,7 +7,8 @@ */ // tslint:disable:no-implicit-dependencies // tslint:disable:no-console -import { tags, terminal } from '@angular-devkit/core'; +import { tags } from '@angular-devkit/core'; +import * as colors from 'ansi-colors'; import * as glob from 'glob'; import 'jasmine'; import { SpecReporter as JasmineSpecReporter } from 'jasmine-spec-reporter'; @@ -89,7 +90,7 @@ class BenchmarkReporter extends JasmineSpecReporter implements jasmine.CustomRep const baseAverageMult = pad(precision(stat.average / stat.base.average), multPad); console.log( - terminal.colors.yellow(tags.indentBy(6)` + colors.yellow(tags.indentBy(6)` count: ${count} fastest: ${fastest} (base) ${baseFastest} @@ -101,7 +102,7 @@ class BenchmarkReporter extends JasmineSpecReporter implements jasmine.CustomRep ); } else { console.log( - terminal.colors.yellow(tags.indentBy(6)` + colors.yellow(tags.indentBy(6)` count: ${count} fastest: ${fastest} slowest: ${slowest} diff --git a/tests/legacy-cli/e2e/utils/process.ts b/tests/legacy-cli/e2e/utils/process.ts index 697b558c853f..244ff1086534 100644 --- a/tests/legacy-cli/e2e/utils/process.ts +++ b/tests/legacy-cli/e2e/utils/process.ts @@ -1,10 +1,9 @@ +import * as ansiColors from 'ansi-colors'; import { SpawnOptions } from "child_process"; import * as child_process from 'child_process'; -import { terminal } from '@angular-devkit/core'; -import { Observable, concat, defer, EMPTY, from} from 'rxjs'; +import { concat, defer, EMPTY, from} from 'rxjs'; import {repeat, takeLast} from 'rxjs/operators'; import {getGlobalVariable} from './env'; -import {rimraf} from './fs'; import {catchError} from 'rxjs/operators'; const treeKill = require('tree-kill'); @@ -25,6 +24,10 @@ export type ProcessOutput = { function _exec(options: ExecOptions, cmd: string, args: string[]): Promise { + // Create a separate instance to prevent unintended global changes to the color configuration + // Create function is not defined in the typings. See: https://github.com/doowb/ansi-colors/pull/44 + const colors = (ansiColors as typeof ansiColors & { create: () => typeof ansiColors }).create(); + let stdout = ''; let stderr = ''; const cwd = process.cwd(); @@ -42,9 +45,9 @@ function _exec(options: ExecOptions, cmd: string, args: string[]): Promise `"${x}"`).join(' ')}\`${flags}...`)); - console.log(terminal.blue(`CWD: ${cwd}`)); - console.log(terminal.blue(`ENV: ${JSON.stringify(env)}`)); + console.log(colors.blue(`Running \`${cmd} ${args.map(x => `"${x}"`).join(' ')}\`${flags}...`)); + console.log(colors.blue(`CWD: ${cwd}`)); + console.log(colors.blue(`ENV: ${JSON.stringify(env)}`)); const spawnOptions: SpawnOptions = { cwd, ...env ? { env } : {}, @@ -75,7 +78,7 @@ function _exec(options: ExecOptions, cmd: string, args: string[]): Promise line !== '') - .forEach(line => console.error(terminal.yellow(' ' + line))); + .forEach(line => console.error(colors.yellow(' ' + line))); }); _processes.push(childProcess); diff --git a/tests/legacy-cli/e2e_runner.ts b/tests/legacy-cli/e2e_runner.ts index 19ac155152f1..68c945fd6298 100644 --- a/tests/legacy-cli/e2e_runner.ts +++ b/tests/legacy-cli/e2e_runner.ts @@ -1,7 +1,8 @@ // This may seem awkward but we're using Logger in our e2e. At this point the unit tests // have run already so it should be "safe", teehee. -import { logging, terminal } from '@angular-devkit/core'; +import { logging } from '@angular-devkit/core'; import { createConsoleLogger } from '@angular-devkit/core/node'; +import * as colors from 'ansi-colors'; import { spawn } from 'child_process'; import * as fs from 'fs'; import * as glob from 'glob'; @@ -11,8 +12,6 @@ import * as path from 'path'; import { setGlobalVariable } from './e2e/utils/env'; import { gitClean } from './e2e/utils/git'; -const { blue, bold, green, red, yellow, white } = terminal; - Error.stackTraceLimit = Infinity; // tslint:disable:no-global-tslint-disable no-console @@ -57,7 +56,14 @@ const argv = minimist(process.argv.slice(2), { */ process.exitCode = 255; -const logger = createConsoleLogger(argv.verbose); +const logger = createConsoleLogger(argv.verbose, process.stdout, process.stderr, { + info: s => s, + debug: s => s, + warn: s => colors.bold.yellow(s), + error: s => colors.bold.red(s), + fatal: s => colors.bold.red(s), +}); + const logStack = [logger]; function lastLogger() { return logStack[logStack.length - 1]; @@ -227,14 +233,14 @@ testsToRun registryProcess.kill(); } - console.log(green('Done.')); + console.log(colors.green('Done.')); process.exit(0); }, err => { console.log('\n'); - console.error(red(`Test "${currentFileName}" failed...`)); - console.error(red(err.message)); - console.error(red(err.stack)); + console.error(colors.red(`Test "${currentFileName}" failed...`)); + console.error(colors.red(err.message)); + console.error(colors.red(err.stack)); if (registryProcess) { registryProcess.kill(); @@ -262,13 +268,13 @@ function printHeader(testName: string, testIndex: number) { : (testIndex - allSetups.length) * nbShards + shardId + allSetups.length) + 1; const length = tests.length + allSetups.length; const shard = - shardId === null ? '' : yellow(` [${shardId}:${nbShards}]` + bold(` (${fullIndex}/${length})`)); - console.log(green(`Running "${bold(blue(testName))}" (${bold(white(text))}${shard})...`)); + shardId === null ? '' : colors.yellow(` [${shardId}:${nbShards}]` + colors.bold(` (${fullIndex}/${length})`)); + console.log(colors.green(`Running "${colors.bold.blue(testName)}" (${colors.bold.white(text)}${shard})...`)); } function printFooter(testName: string, startTime: number) { // Round to hundredth of a second. const t = Math.round((Date.now() - startTime) / 10) / 100; - console.log(green('Last step took ') + bold(blue(t)) + green('s...')); + console.log(colors.green('Last step took ') + colors.bold.blue('' + t) + colors.green('s...')); console.log(''); }