mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-19 04:22:53 +08:00
refactor: use ansi-colors instead of removed terminal utils
This commit is contained in:
parent
6d43e320b6
commit
622d08447d
@ -33,19 +33,19 @@ process.chdir(path.join(__dirname, '..'));
|
|||||||
let logger = null;
|
let logger = null;
|
||||||
try {
|
try {
|
||||||
logger = new (require('@angular-devkit/core').logging.IndentLogger)('root');
|
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;
|
const filter = require('rxjs/operators').filter;
|
||||||
|
|
||||||
logger
|
logger
|
||||||
.pipe(filter(entry => (entry.level !== 'debug' || args.verbose)))
|
.pipe(filter(entry => (entry.level !== 'debug' || args.verbose)))
|
||||||
.subscribe(entry => {
|
.subscribe(entry => {
|
||||||
let color = gray;
|
let color = colors.gray;
|
||||||
let output = process.stdout;
|
let output = process.stdout;
|
||||||
switch (entry.level) {
|
switch (entry.level) {
|
||||||
case 'info': color = white; break;
|
case 'info': color = colors.white; break;
|
||||||
case 'warn': color = yellow; break;
|
case 'warn': color = colors.yellow; break;
|
||||||
case 'error': color = red; output = process.stderr; break;
|
case 'error': color = colors.red; output = process.stderr; break;
|
||||||
case 'fatal': color = x => bold(red(x)); output = process.stderr; break;
|
case 'fatal': color = x => colors.bold.red(x); output = process.stderr; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
output.write(color(entry.message) + '\n');
|
output.write(color(entry.message) + '\n');
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
import { createConsoleLogger } from '@angular-devkit/core/node';
|
import { createConsoleLogger } from '@angular-devkit/core/node';
|
||||||
import { format } from 'util';
|
import { format } from 'util';
|
||||||
import { runCommand } from '../../models/command-runner';
|
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 { getWorkspaceRaw } from '../../utilities/config';
|
||||||
import { writeErrorToLogFile } from '../../utilities/log-file';
|
import { writeErrorToLogFile } from '../../utilities/log-file';
|
||||||
import { getWorkspaceDetails } from '../../utilities/project';
|
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, {
|
const logger = createConsoleLogger(isDebug, process.stdout, process.stderr, {
|
||||||
info: s => (supportsColor ? s : removeColor(s)),
|
info: s => (colors.enabled ? s : removeColor(s)),
|
||||||
debug: s => (supportsColor ? s : removeColor(s)),
|
debug: s => (colors.enabled ? s : removeColor(s)),
|
||||||
warn: s => (supportsColor ? colors.bold.yellow(s) : removeColor(s)),
|
warn: s => (colors.enabled ? colors.bold.yellow(s) : removeColor(s)),
|
||||||
error: s => (supportsColor ? colors.bold.red(s) : removeColor(s)),
|
error: s => (colors.enabled ? colors.bold.red(s) : removeColor(s)),
|
||||||
fatal: s => (supportsColor ? colors.bold.red(s) : removeColor(s)),
|
fatal: s => (colors.enabled ? colors.bold.red(s) : removeColor(s)),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Redirect console to logger
|
// Redirect console to logger
|
||||||
|
@ -8,18 +8,22 @@
|
|||||||
import * as ansiColors from 'ansi-colors';
|
import * as ansiColors from 'ansi-colors';
|
||||||
import { WriteStream } from 'tty';
|
import { WriteStream } from 'tty';
|
||||||
|
|
||||||
|
type AnsiColors = typeof ansiColors;
|
||||||
|
|
||||||
// Typings do not contain the function call (added in Node.js v9.9.0)
|
// 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 instanceof WriteStream &&
|
||||||
((process.stdout as unknown) as { getColorDepth(): number }).getColorDepth() > 1;
|
((process.stdout as unknown) as { getColorDepth(): number }).getColorDepth() > 1;
|
||||||
|
|
||||||
export function removeColor(text: string): string {
|
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 a separate instance to prevent unintended global changes to the color configuration
|
||||||
// create function is not defined in the typings
|
// 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();
|
const colors = (ansiColors as AnsiColors & { create: () => AnsiColors }).create();
|
||||||
colors.enabled = supportsColor;
|
colors.enabled = supportsColor;
|
||||||
|
|
||||||
export { colors };
|
export { colors };
|
||||||
|
@ -22,6 +22,7 @@ ts_library(
|
|||||||
"@npm//@types/minimist",
|
"@npm//@types/minimist",
|
||||||
"@npm//@types/node",
|
"@npm//@types/node",
|
||||||
"@npm//@types/progress",
|
"@npm//@types/progress",
|
||||||
|
"@npm//ansi-colors",
|
||||||
"@npm//rxjs",
|
"@npm//rxjs",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -8,8 +8,9 @@
|
|||||||
*/
|
*/
|
||||||
import { Architect, BuilderInfo, BuilderProgressState, Target } from '@angular-devkit/architect';
|
import { Architect, BuilderInfo, BuilderProgressState, Target } from '@angular-devkit/architect';
|
||||||
import { WorkspaceNodeModulesArchitectHost } from '@angular-devkit/architect/node';
|
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 { NodeJsSyncHost, createConsoleLogger } from '@angular-devkit/core/node';
|
||||||
|
import * as ansiColors from 'ansi-colors';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import * as minimist from 'minimist';
|
import * as minimist from 'minimist';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
@ -68,6 +69,10 @@ interface BarInfo {
|
|||||||
target?: Target;
|
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(
|
async function _executeTarget(
|
||||||
parentLogger: logging.Logger,
|
parentLogger: logging.Logger,
|
||||||
workspace: workspaces.WorkspaceDefinition,
|
workspace: workspaces.WorkspaceDefinition,
|
||||||
@ -139,9 +144,9 @@ async function _executeTarget(
|
|||||||
.pipe(
|
.pipe(
|
||||||
tap(result => {
|
tap(result => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
parentLogger.info(terminal.green('SUCCESS'));
|
parentLogger.info(colors.green('SUCCESS'));
|
||||||
} else {
|
} else {
|
||||||
parentLogger.info(terminal.yellow('FAILURE'));
|
parentLogger.info(colors.red('FAILURE'));
|
||||||
}
|
}
|
||||||
parentLogger.info('Result: ' + JSON.stringify({ ...result, info: undefined }, null, 4));
|
parentLogger.info('Result: ' + JSON.stringify({ ...result, info: undefined }, null, 4));
|
||||||
|
|
||||||
@ -157,7 +162,7 @@ async function _executeTarget(
|
|||||||
|
|
||||||
return success ? 0 : 1;
|
return success ? 0 : 1;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
parentLogger.info(terminal.red('ERROR'));
|
parentLogger.info(colors.red('ERROR'));
|
||||||
parentLogger.info('\nLogs:');
|
parentLogger.info('\nLogs:');
|
||||||
logs.forEach(l => parentLogger.next(l));
|
logs.forEach(l => parentLogger.next(l));
|
||||||
|
|
||||||
@ -173,7 +178,13 @@ async function main(args: string[]): Promise<number> {
|
|||||||
const argv = minimist(args, { boolean: ['help'] });
|
const argv = minimist(args, { boolean: ['help'] });
|
||||||
|
|
||||||
/** Create the DevKit Logger used through the CLI. */
|
/** 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.
|
// Check the target.
|
||||||
const targetStr = argv._[0] || '';
|
const targetStr = argv._[0] || '';
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/architect": "0.0.0",
|
"@angular-devkit/architect": "0.0.0",
|
||||||
"@angular-devkit/core": "0.0.0",
|
"@angular-devkit/core": "0.0.0",
|
||||||
|
"ansi-colors": "4.1.1",
|
||||||
"minimist": "1.2.5",
|
"minimist": "1.2.5",
|
||||||
"progress": "2.0.3",
|
"progress": "2.0.3",
|
||||||
"rxjs": "6.6.3",
|
"rxjs": "6.6.3",
|
||||||
|
@ -32,6 +32,7 @@ ts_library(
|
|||||||
"@npm//@types/minimist",
|
"@npm//@types/minimist",
|
||||||
"@npm//@types/node",
|
"@npm//@types/node",
|
||||||
"@npm//@types/pidusage",
|
"@npm//@types/pidusage",
|
||||||
|
"@npm//ansi-colors",
|
||||||
"@npm//rxjs",
|
"@npm//rxjs",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/core": "0.0.0",
|
"@angular-devkit/core": "0.0.0",
|
||||||
|
"ansi-colors": "4.1.1",
|
||||||
"minimist": "1.2.5",
|
"minimist": "1.2.5",
|
||||||
"pidusage": "2.0.21",
|
"pidusage": "2.0.21",
|
||||||
"pidtree": "0.5.0",
|
"pidtree": "0.5.0",
|
||||||
|
@ -7,8 +7,9 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* 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 { ProcessOutput } from '@angular-devkit/core/node';
|
||||||
|
import * as ansiColors from 'ansi-colors';
|
||||||
import { appendFileSync, writeFileSync } from 'fs';
|
import { appendFileSync, writeFileSync } from 'fs';
|
||||||
import * as minimist from 'minimist';
|
import * as minimist from 'minimist';
|
||||||
import { filter, map, toArray } from 'rxjs/operators';
|
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.
|
// Log to console.
|
||||||
logger
|
logger
|
||||||
.pipe(filter(entry => (entry.level != 'debug' || argv['verbose'])))
|
.pipe(filter(entry => (entry.level != 'debug' || argv['verbose'])))
|
||||||
.subscribe(entry => {
|
.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;
|
let output = stdout;
|
||||||
switch (entry.level) {
|
switch (entry.level) {
|
||||||
case 'info':
|
case 'info':
|
||||||
color = s => s;
|
color = s => s;
|
||||||
break;
|
break;
|
||||||
case 'warn':
|
case 'warn':
|
||||||
color = terminal.yellow;
|
color = colors.yellow;
|
||||||
output = stderr;
|
output = stderr;
|
||||||
break;
|
break;
|
||||||
case 'error':
|
case 'error':
|
||||||
color = terminal.red;
|
color = colors.red;
|
||||||
output = stderr;
|
output = stderr;
|
||||||
break;
|
break;
|
||||||
case 'fatal':
|
case 'fatal':
|
||||||
color = (x: string) => terminal.bold(terminal.red(x));
|
color = (x: string) => colors.bold.red(x);
|
||||||
output = stderr;
|
output = stderr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,7 @@ ts_library(
|
|||||||
"@npm//@types/webpack-dev-server",
|
"@npm//@types/webpack-dev-server",
|
||||||
"@npm//@types/webpack-sources",
|
"@npm//@types/webpack-sources",
|
||||||
"@npm//ajv",
|
"@npm//ajv",
|
||||||
|
"@npm//ansi-colors",
|
||||||
"@npm//autoprefixer",
|
"@npm//autoprefixer",
|
||||||
"@npm//babel-loader",
|
"@npm//babel-loader",
|
||||||
"@npm//browserslist",
|
"@npm//browserslist",
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"@babel/template": "7.10.4",
|
"@babel/template": "7.10.4",
|
||||||
"@jsdevtools/coverage-istanbul-loader": "3.0.5",
|
"@jsdevtools/coverage-istanbul-loader": "3.0.5",
|
||||||
"@ngtools/webpack": "0.0.0",
|
"@ngtools/webpack": "0.0.0",
|
||||||
|
"ansi-colors": "4.1.1",
|
||||||
"autoprefixer": "9.8.6",
|
"autoprefixer": "9.8.6",
|
||||||
"babel-loader": "8.1.0",
|
"babel-loader": "8.1.0",
|
||||||
"browserslist": "^4.9.1",
|
"browserslist": "^4.9.1",
|
||||||
|
@ -7,12 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
// tslint:disable
|
// tslint:disable
|
||||||
// TODO: cleanup this file, it's copied as is from Angular CLI.
|
// 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 { WebpackLoggingCallback } from '@angular-devkit/build-webpack';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import { colors as ansiColors } from '../../utils/color';
|
||||||
|
|
||||||
const { bold, green, red, reset, white, yellow } = terminal;
|
|
||||||
|
|
||||||
export function formatSize(size: number): string {
|
export function formatSize(size: number): string {
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
@ -37,8 +35,8 @@ export function generateBundleStats(
|
|||||||
},
|
},
|
||||||
colors: boolean,
|
colors: boolean,
|
||||||
): string {
|
): string {
|
||||||
const g = (x: string) => (colors ? bold(green(x)) : x);
|
const g = (x: string) => (colors ? ansiColors.bold.green(x) : x);
|
||||||
const y = (x: string) => (colors ? bold(yellow(x)) : x);
|
const y = (x: string) => (colors ? ansiColors.bold.yellow(x) : x);
|
||||||
|
|
||||||
const id = info.id ? y(info.id.toString()) : '';
|
const id = info.id ? y(info.id.toString()) : '';
|
||||||
const size = typeof info.size === 'number' ? ` ${formatSize(info.size)}` : '';
|
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 {
|
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`
|
return `Date: ${w(new Date().toISOString())} - Hash: ${w(hash)} - Time: ${w('' + time)}ms`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function statsToString(json: any, statsConfig: any) {
|
export function statsToString(json: any, statsConfig: any) {
|
||||||
const colors = statsConfig.colors;
|
const colors = statsConfig.colors;
|
||||||
const rs = (x: string) => colors ? reset(x) : x;
|
const rs = (x: string) => colors ? ansiColors.reset(x) : x;
|
||||||
const w = (x: string) => colors ? bold(white(x)) : x;
|
const w = (x: string) => colors ? ansiColors.bold.white(x) : x;
|
||||||
|
|
||||||
const changedChunksStats = json.chunks
|
const changedChunksStats = json.chunks
|
||||||
.filter((chunk: any) => chunk.rendered)
|
.filter((chunk: any) => chunk.rendered)
|
||||||
@ -97,8 +95,8 @@ const ERRONEOUS_WARNINGS_FILTER = (warning: string) => ![
|
|||||||
|
|
||||||
export function statsWarningsToString(json: any, statsConfig: any): string {
|
export function statsWarningsToString(json: any, statsConfig: any): string {
|
||||||
const colors = statsConfig.colors;
|
const colors = statsConfig.colors;
|
||||||
const rs = (x: string) => colors ? reset(x) : x;
|
const rs = (x: string) => colors ? ansiColors.reset(x) : x;
|
||||||
const y = (x: string) => colors ? bold(yellow(x)) : x;
|
const y = (x: string) => colors ? ansiColors.bold.yellow(x) : x;
|
||||||
const warnings = [...json.warnings];
|
const warnings = [...json.warnings];
|
||||||
if (json.children) {
|
if (json.children) {
|
||||||
warnings.push(...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 {
|
export function statsErrorsToString(json: any, statsConfig: any): string {
|
||||||
const colors = statsConfig.colors;
|
const colors = statsConfig.colors;
|
||||||
const rs = (x: string) => colors ? reset(x) : x;
|
const rs = (x: string) => colors ? ansiColors.reset(x) : x;
|
||||||
const r = (x: string) => colors ? bold(red(x)) : x;
|
const r = (x: string) => colors ? ansiColors.bold.red(x) : x;
|
||||||
const errors = [...json.errors];
|
const errors = [...json.errors];
|
||||||
if (json.children) {
|
if (json.children) {
|
||||||
errors.push(...json.children
|
errors.push(...json.children
|
||||||
|
29
packages/angular_devkit/build_angular/src/utils/color.ts
Normal file
29
packages/angular_devkit/build_angular/src/utils/color.ts
Normal file
@ -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 };
|
@ -6,7 +6,7 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import { filter } from 'rxjs/operators';
|
import { filter } from 'rxjs/operators';
|
||||||
import { logging, terminal } from '../src';
|
import { logging } from '../src';
|
||||||
|
|
||||||
export interface ProcessOutput {
|
export interface ProcessOutput {
|
||||||
write(buffer: string | Buffer): boolean;
|
write(buffer: string | Buffer): boolean;
|
||||||
@ -24,20 +24,15 @@ export function createConsoleLogger(
|
|||||||
const logger = new logging.IndentLogger('cling');
|
const logger = new logging.IndentLogger('cling');
|
||||||
|
|
||||||
logger
|
logger
|
||||||
.pipe(filter(entry => (entry.level != 'debug' || verbose)))
|
.pipe(filter(entry => entry.level !== 'debug' || verbose))
|
||||||
.subscribe(entry => {
|
.subscribe(entry => {
|
||||||
let color = colors && colors[entry.level];
|
const color = colors && colors[entry.level];
|
||||||
let output = stdout;
|
let output = stdout;
|
||||||
|
|
||||||
switch (entry.level) {
|
switch (entry.level) {
|
||||||
case 'info':
|
|
||||||
break;
|
|
||||||
case 'warn':
|
case 'warn':
|
||||||
color = color || (s => terminal.bold(terminal.yellow(s)));
|
|
||||||
output = stderr;
|
|
||||||
break;
|
|
||||||
case 'fatal':
|
case 'fatal':
|
||||||
case 'error':
|
case 'error':
|
||||||
color = color || (s => terminal.bold(terminal.red(s)));
|
|
||||||
output = stderr;
|
output = stderr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* Use of this source code is governed by an MIT-style license that can be
|
* 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
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as experimental from './experimental/jobs/job-registry';
|
import * as experimental from './experimental/jobs/job-registry';
|
||||||
import * as fs from './fs';
|
import * as fs from './fs';
|
||||||
export * from './cli-logger';
|
export * from './cli-logger';
|
||||||
|
@ -41,6 +41,7 @@ ts_library(
|
|||||||
"@npm//@types/inquirer",
|
"@npm//@types/inquirer",
|
||||||
"@npm//@types/minimist",
|
"@npm//@types/minimist",
|
||||||
"@npm//@types/node",
|
"@npm//@types/node",
|
||||||
|
"@npm//ansi-colors",
|
||||||
"@npm//inquirer", # @external
|
"@npm//inquirer", # @external
|
||||||
"@npm//minimist", # @external
|
"@npm//minimist", # @external
|
||||||
"@npm//rxjs",
|
"@npm//rxjs",
|
||||||
|
@ -16,7 +16,6 @@ import {
|
|||||||
normalize,
|
normalize,
|
||||||
schema,
|
schema,
|
||||||
tags,
|
tags,
|
||||||
terminal,
|
|
||||||
virtualFs,
|
virtualFs,
|
||||||
} from '@angular-devkit/core';
|
} from '@angular-devkit/core';
|
||||||
import { NodeJsSyncHost, ProcessOutput, createConsoleLogger } from '@angular-devkit/core/node';
|
import { NodeJsSyncHost, ProcessOutput, createConsoleLogger } from '@angular-devkit/core/node';
|
||||||
@ -26,6 +25,7 @@ import {
|
|||||||
formats,
|
formats,
|
||||||
} from '@angular-devkit/schematics';
|
} from '@angular-devkit/schematics';
|
||||||
import { NodeWorkflow, validateOptionsWithSchema } from '@angular-devkit/schematics/tools';
|
import { NodeWorkflow, validateOptionsWithSchema } from '@angular-devkit/schematics/tools';
|
||||||
|
import * as ansiColors from 'ansi-colors';
|
||||||
import * as inquirer from 'inquirer';
|
import * as inquirer from 'inquirer';
|
||||||
import * as minimist from 'minimist';
|
import * as minimist from 'minimist';
|
||||||
|
|
||||||
@ -117,6 +117,7 @@ function _createPromptProvider(): schema.PromptProvider {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line: no-big-function
|
||||||
export async function main({
|
export async function main({
|
||||||
args,
|
args,
|
||||||
stdout = process.stdout,
|
stdout = process.stdout,
|
||||||
@ -124,8 +125,19 @@ export async function main({
|
|||||||
}: MainOptions): Promise<0 | 1> {
|
}: MainOptions): Promise<0 | 1> {
|
||||||
const argv = parseArgs(args);
|
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. */
|
/** 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) {
|
if (argv.help) {
|
||||||
logger.info(getUsage());
|
logger.info(getUsage());
|
||||||
|
|
||||||
@ -205,20 +217,20 @@ export async function main({
|
|||||||
break;
|
break;
|
||||||
case 'update':
|
case 'update':
|
||||||
loggingQueue.push(tags.oneLine`
|
loggingQueue.push(tags.oneLine`
|
||||||
${terminal.white('UPDATE')} ${eventPath} (${event.content.length} bytes)
|
${colors.white('UPDATE')} ${eventPath} (${event.content.length} bytes)
|
||||||
`);
|
`);
|
||||||
break;
|
break;
|
||||||
case 'create':
|
case 'create':
|
||||||
loggingQueue.push(tags.oneLine`
|
loggingQueue.push(tags.oneLine`
|
||||||
${terminal.green('CREATE')} ${eventPath} (${event.content.length} bytes)
|
${colors.green('CREATE')} ${eventPath} (${event.content.length} bytes)
|
||||||
`);
|
`);
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
loggingQueue.push(`${terminal.yellow('DELETE')} ${eventPath}`);
|
loggingQueue.push(`${colors.yellow('DELETE')} ${eventPath}`);
|
||||||
break;
|
break;
|
||||||
case 'rename':
|
case 'rename':
|
||||||
const eventToPath = event.to.startsWith('/') ? event.to.substr(1) : event.to;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
"@angular-devkit/core": "0.0.0",
|
"@angular-devkit/core": "0.0.0",
|
||||||
"@angular-devkit/schematics": "0.0.0",
|
"@angular-devkit/schematics": "0.0.0",
|
||||||
"@schematics/schematics": "0.0.0",
|
"@schematics/schematics": "0.0.0",
|
||||||
|
"ansi-colors": "4.1.1",
|
||||||
"inquirer": "7.3.3",
|
"inquirer": "7.3.3",
|
||||||
"minimist": "1.2.5",
|
"minimist": "1.2.5",
|
||||||
"rxjs": "6.6.3",
|
"rxjs": "6.6.3",
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
// tslint:disable:no-implicit-dependencies
|
// tslint:disable:no-implicit-dependencies
|
||||||
// tslint:disable:no-console
|
// 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 * as glob from 'glob';
|
||||||
import 'jasmine';
|
import 'jasmine';
|
||||||
import { SpecReporter as JasmineSpecReporter } from 'jasmine-spec-reporter';
|
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);
|
const baseAverageMult = pad(precision(stat.average / stat.base.average), multPad);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
terminal.colors.yellow(tags.indentBy(6)`
|
colors.yellow(tags.indentBy(6)`
|
||||||
count: ${count}
|
count: ${count}
|
||||||
fastest: ${fastest}
|
fastest: ${fastest}
|
||||||
(base) ${baseFastest}
|
(base) ${baseFastest}
|
||||||
@ -101,7 +102,7 @@ class BenchmarkReporter extends JasmineSpecReporter implements jasmine.CustomRep
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log(
|
console.log(
|
||||||
terminal.colors.yellow(tags.indentBy(6)`
|
colors.yellow(tags.indentBy(6)`
|
||||||
count: ${count}
|
count: ${count}
|
||||||
fastest: ${fastest}
|
fastest: ${fastest}
|
||||||
slowest: ${slowest}
|
slowest: ${slowest}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
|
import * as ansiColors from 'ansi-colors';
|
||||||
import { SpawnOptions } from "child_process";
|
import { SpawnOptions } from "child_process";
|
||||||
import * as child_process from 'child_process';
|
import * as child_process from 'child_process';
|
||||||
import { terminal } from '@angular-devkit/core';
|
import { concat, defer, EMPTY, from} from 'rxjs';
|
||||||
import { Observable, concat, defer, EMPTY, from} from 'rxjs';
|
|
||||||
import {repeat, takeLast} from 'rxjs/operators';
|
import {repeat, takeLast} from 'rxjs/operators';
|
||||||
import {getGlobalVariable} from './env';
|
import {getGlobalVariable} from './env';
|
||||||
import {rimraf} from './fs';
|
|
||||||
import {catchError} from 'rxjs/operators';
|
import {catchError} from 'rxjs/operators';
|
||||||
const treeKill = require('tree-kill');
|
const treeKill = require('tree-kill');
|
||||||
|
|
||||||
@ -25,6 +24,10 @@ export type ProcessOutput = {
|
|||||||
|
|
||||||
|
|
||||||
function _exec(options: ExecOptions, cmd: string, args: string[]): Promise<ProcessOutput> {
|
function _exec(options: ExecOptions, cmd: string, args: string[]): Promise<ProcessOutput> {
|
||||||
|
// 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 stdout = '';
|
||||||
let stderr = '';
|
let stderr = '';
|
||||||
const cwd = process.cwd();
|
const cwd = process.cwd();
|
||||||
@ -42,9 +45,9 @@ function _exec(options: ExecOptions, cmd: string, args: string[]): Promise<Proc
|
|||||||
.join(', ')
|
.join(', ')
|
||||||
.replace(/^(.+)$/, ' [$1]'); // Proper formatting.
|
.replace(/^(.+)$/, ' [$1]'); // Proper formatting.
|
||||||
|
|
||||||
console.log(terminal.blue(`Running \`${cmd} ${args.map(x => `"${x}"`).join(' ')}\`${flags}...`));
|
console.log(colors.blue(`Running \`${cmd} ${args.map(x => `"${x}"`).join(' ')}\`${flags}...`));
|
||||||
console.log(terminal.blue(`CWD: ${cwd}`));
|
console.log(colors.blue(`CWD: ${cwd}`));
|
||||||
console.log(terminal.blue(`ENV: ${JSON.stringify(env)}`));
|
console.log(colors.blue(`ENV: ${JSON.stringify(env)}`));
|
||||||
const spawnOptions: SpawnOptions = {
|
const spawnOptions: SpawnOptions = {
|
||||||
cwd,
|
cwd,
|
||||||
...env ? { env } : {},
|
...env ? { env } : {},
|
||||||
@ -75,7 +78,7 @@ function _exec(options: ExecOptions, cmd: string, args: string[]): Promise<Proc
|
|||||||
data.toString('utf-8')
|
data.toString('utf-8')
|
||||||
.split(/[\n\r]+/)
|
.split(/[\n\r]+/)
|
||||||
.filter(line => line !== '')
|
.filter(line => line !== '')
|
||||||
.forEach(line => console.error(terminal.yellow(' ' + line)));
|
.forEach(line => console.error(colors.yellow(' ' + line)));
|
||||||
});
|
});
|
||||||
|
|
||||||
_processes.push(childProcess);
|
_processes.push(childProcess);
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// This may seem awkward but we're using Logger in our e2e. At this point the unit tests
|
// 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.
|
// 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 { createConsoleLogger } from '@angular-devkit/core/node';
|
||||||
|
import * as colors from 'ansi-colors';
|
||||||
import { spawn } from 'child_process';
|
import { spawn } from 'child_process';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as glob from 'glob';
|
import * as glob from 'glob';
|
||||||
@ -11,8 +12,6 @@ import * as path from 'path';
|
|||||||
import { setGlobalVariable } from './e2e/utils/env';
|
import { setGlobalVariable } from './e2e/utils/env';
|
||||||
import { gitClean } from './e2e/utils/git';
|
import { gitClean } from './e2e/utils/git';
|
||||||
|
|
||||||
const { blue, bold, green, red, yellow, white } = terminal;
|
|
||||||
|
|
||||||
Error.stackTraceLimit = Infinity;
|
Error.stackTraceLimit = Infinity;
|
||||||
|
|
||||||
// tslint:disable:no-global-tslint-disable no-console
|
// tslint:disable:no-global-tslint-disable no-console
|
||||||
@ -57,7 +56,14 @@ const argv = minimist(process.argv.slice(2), {
|
|||||||
*/
|
*/
|
||||||
process.exitCode = 255;
|
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];
|
const logStack = [logger];
|
||||||
function lastLogger() {
|
function lastLogger() {
|
||||||
return logStack[logStack.length - 1];
|
return logStack[logStack.length - 1];
|
||||||
@ -227,14 +233,14 @@ testsToRun
|
|||||||
registryProcess.kill();
|
registryProcess.kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(green('Done.'));
|
console.log(colors.green('Done.'));
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
},
|
},
|
||||||
err => {
|
err => {
|
||||||
console.log('\n');
|
console.log('\n');
|
||||||
console.error(red(`Test "${currentFileName}" failed...`));
|
console.error(colors.red(`Test "${currentFileName}" failed...`));
|
||||||
console.error(red(err.message));
|
console.error(colors.red(err.message));
|
||||||
console.error(red(err.stack));
|
console.error(colors.red(err.stack));
|
||||||
|
|
||||||
if (registryProcess) {
|
if (registryProcess) {
|
||||||
registryProcess.kill();
|
registryProcess.kill();
|
||||||
@ -262,13 +268,13 @@ function printHeader(testName: string, testIndex: number) {
|
|||||||
: (testIndex - allSetups.length) * nbShards + shardId + allSetups.length) + 1;
|
: (testIndex - allSetups.length) * nbShards + shardId + allSetups.length) + 1;
|
||||||
const length = tests.length + allSetups.length;
|
const length = tests.length + allSetups.length;
|
||||||
const shard =
|
const shard =
|
||||||
shardId === null ? '' : yellow(` [${shardId}:${nbShards}]` + bold(` (${fullIndex}/${length})`));
|
shardId === null ? '' : colors.yellow(` [${shardId}:${nbShards}]` + colors.bold(` (${fullIndex}/${length})`));
|
||||||
console.log(green(`Running "${bold(blue(testName))}" (${bold(white(text))}${shard})...`));
|
console.log(colors.green(`Running "${colors.bold.blue(testName)}" (${colors.bold.white(text)}${shard})...`));
|
||||||
}
|
}
|
||||||
|
|
||||||
function printFooter(testName: string, startTime: number) {
|
function printFooter(testName: string, startTime: number) {
|
||||||
// Round to hundredth of a second.
|
// Round to hundredth of a second.
|
||||||
const t = Math.round((Date.now() - startTime) / 10) / 100;
|
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('');
|
console.log('');
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user