From a70932b1acf97d20cc04cb7c875cdddd2fe11637 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 5 Jun 2019 19:48:41 -0400 Subject: [PATCH] refactor(@angular/cli): standardize color handling and support checking Node.js 10+ provides built-in functionality to test for color support based on chalk's `supports-color` package as well as several others. This alleviates the need for custom code or third-party packages to determine color support. In addition for this PR, the `ansi-colors` package is added to the CLI which provides color, cross-platform symbol, and style/color removal support. The package is light-weight, contains typings, and has no dependencies. The removal support is leveraged to remove all styling from logger messages when color is not supported. This removes a current defect in which color/styling is still displayed if generated manually or via methods that do not perform supportability checks. Finally, the typically used console functions are overriden to leverage the logger to ensure that the color processing is applied to third-party code (e.g., webpack internally as well as some of its loaders and plugins) which output to the console directly. --- package.json | 1 + packages/angular/cli/BUILD | 1 + packages/angular/cli/lib/cli/index.ts | 23 ++++++++++++++++++----- packages/angular/cli/package.json | 1 + yarn.lock | 5 +++++ 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 22cc9b3343..3377133e38 100644 --- a/package.json +++ b/package.json @@ -107,6 +107,7 @@ "@types/webpack-sources": "^0.1.5", "@yarnpkg/lockfile": "1.1.0", "ajv": "6.10.0", + "ansi-colors": "3.2.4", "common-tags": "^1.8.0", "conventional-changelog": "^1.1.0", "conventional-commits-parser": "^3.0.0", diff --git a/packages/angular/cli/BUILD b/packages/angular/cli/BUILD index f225157d9a..6361ada810 100644 --- a/packages/angular/cli/BUILD +++ b/packages/angular/cli/BUILD @@ -41,6 +41,7 @@ ts_library( "@npm//@types/semver", "@npm//@types/universal-analytics", "@npm//@types/uuid", + "@npm//ansi-colors", "@npm//rxjs", ], ) diff --git a/packages/angular/cli/lib/cli/index.ts b/packages/angular/cli/lib/cli/index.ts index aac8708aba..f0c5069c45 100644 --- a/packages/angular/cli/lib/cli/index.ts +++ b/packages/angular/cli/lib/cli/index.ts @@ -5,25 +5,38 @@ * 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 { terminal } from '@angular-devkit/core'; import { createConsoleLogger } from '@angular-devkit/core/node'; +import * as colors from 'ansi-colors'; +import { WriteStream } from 'tty'; +import { format } from 'util'; import { runCommand } from '../../models/command-runner'; import { getWorkspaceRaw } from '../../utilities/config'; import { getWorkspaceDetails } from '../../utilities/project'; - export default async function(options: { testing?: boolean, cliArgs: string[] }) { + // 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; + const logger = createConsoleLogger( false, process.stdout, process.stderr, { - warn: s => terminal.bold(terminal.yellow(s)), - error: s => terminal.bold(terminal.red(s)), - fatal: s => terminal.bold(terminal.red(s)), + info: s => supportsColor ? s : colors.unstyle(s), + debug: s => supportsColor ? s : colors.unstyle(s), + warn: s => supportsColor ? colors.bold.yellow(s) : colors.unstyle(s), + error: s => supportsColor ? colors.bold.red(s) : colors.unstyle(s), + fatal: s => supportsColor ? colors.bold.red(s) : colors.unstyle(s), }, ); + // Redirect console to logger + console.log = function() { logger.info(format.apply(null, arguments)); }; + console.info = function() { logger.info(format.apply(null, arguments)); }; + console.warn = function() { logger.warn(format.apply(null, arguments)); }; + console.error = function() { logger.error(format.apply(null, arguments)); }; + let projectDetails = getWorkspaceDetails(); if (projectDetails === null) { const [, localPath] = getWorkspaceRaw('local'); diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index 57bbcce14c..1eec7d2635 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -31,6 +31,7 @@ "@schematics/angular": "0.0.0", "@schematics/update": "0.0.0", "@yarnpkg/lockfile": "1.1.0", + "ansi-colors": "3.2.4", "debug": "^4.1.1", "ini": "1.3.5", "inquirer": "6.3.1", diff --git a/yarn.lock b/yarn.lock index 9dc4eeea1d..cf962d90a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -988,6 +988,11 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" +ansi-colors@3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + ansi-colors@^3.0.0: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.1.tgz#9638047e4213f3428a11944a7d4b31cba0a3ff95"