GeezerVison is showing github.com — lib: support FORCE_COLOR for non TTY streams · nodejs/node@a90010a
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/console/constructor.js +7-4Lines changed: 7 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -79,6 +79,12 @@ const kMaxGroupIndentation = 1000; | 79 | 79 | // Lazy loaded for startup performance. | 80 | 80 | let cliTable; | 81 | 81 |
| | 82 | +let utilColors; | | 83 | +function lazyUtilColors() { | | 84 | + utilColors ??= require('internal/util/colors'); | | 85 | + return utilColors; | | 86 | +} | | 87 | + | 82 | 88 | // Track amount of indentation required via `console.group()`. | 83 | 89 | const kGroupIndent = Symbol('kGroupIndent'); | 84 | 90 | const kGroupIndentationWidth = Symbol('kGroupIndentWidth'); | @@ -95,7 +101,6 @@ const kUseStdout = Symbol('kUseStdout'); | 95 | 101 | const kUseStderr = Symbol('kUseStderr'); | 96 | 102 |
| 97 | 103 | const optionsMap = new SafeWeakMap(); | 98 | | - | 99 | 104 | function Console(options /* or: stdout, stderr, ignoreErrors = true */) { | 100 | 105 | // We have to test new.target here to see if this function is called | 101 | 106 | // with new, because we need to define a custom instanceof to accommodate | @@ -314,9 +319,7 @@ ObjectDefineProperties(Console.prototype, { | 314 | 319 | value: function(stream) { | 315 | 320 | let color = this[kColorMode]; | 316 | 321 | if (color === 'auto') { | 317 | | - color = stream.isTTY && ( | 318 | | - typeof stream.getColorDepth === 'function' ? | 319 | | - stream.getColorDepth() > 2 : true); | | 322 | + color = lazyUtilColors().shouldColorize(stream); | 320 | 323 | } | 321 | 324 |
| 322 | 325 | const options = optionsMap.get(this); | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/errors.js +7-4Lines changed: 7 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -190,6 +190,12 @@ function lazyInternalUtilInspect() { | 190 | 190 | return internalUtilInspect; | 191 | 191 | } | 192 | 192 |
| | 193 | +let utilColors; | | 194 | +function lazyUtilColors() { | | 195 | + utilColors ??= require('internal/util/colors'); | | 196 | + return utilColors; | | 197 | +} | | 198 | + | 193 | 199 | let buffer; | 194 | 200 | function lazyBuffer() { | 195 | 201 | buffer ??= require('buffer').Buffer; | @@ -795,10 +801,7 @@ const fatalExceptionStackEnhancers = { | 795 | 801 | colors: defaultColors, | 796 | 802 | }, | 797 | 803 | } = lazyInternalUtilInspect(); | 798 | | - const colors = useColors && | 799 | | - ((internalBinding('util').guessHandleType(2) === 'TTY' && | 800 | | - require('internal/tty').hasColors()) || | 801 | | - defaultColors); | | 804 | + const colors = useColors && (lazyUtilColors().shouldColorize(process.stderr) || defaultColors); | 802 | 805 | try { | 803 | 806 | return inspect(error, { | 804 | 807 | colors, | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/test_runner/reporter/spec.js +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -14,11 +14,11 @@ const { | 14 | 14 | const assert = require('assert'); | 15 | 15 | const Transform = require('internal/streams/transform'); | 16 | 16 | const { inspectWithNoCustomRetry } = require('internal/errors'); | 17 | | -const { green, blue, red, white, gray, hasColors } = require('internal/util/colors'); | | 17 | +const { green, blue, red, white, gray, shouldColorize } = require('internal/util/colors'); | 18 | 18 | const { kSubtestsFailed } = require('internal/test_runner/test'); | 19 | 19 | const { getCoverageReport } = require('internal/test_runner/utils'); | 20 | 20 |
| 21 | | -const inspectOptions = { __proto__: null, colors: hasColors, breakLength: Infinity }; | | 21 | +const inspectOptions = { __proto__: null, colors: shouldColorize(process.stdout), breakLength: Infinity }; | 22 | 22 |
| 23 | 23 | const colors = { | 24 | 24 | '__proto__': null, | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/util/colors.js +15-1Lines changed: 15 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | 'use strict'; | 2 | 2 |
| | 3 | +let internalTTy; | | 4 | +function lazyInternalTTY() { | | 5 | + internalTTy ??= require('internal/tty'); | | 6 | + return internalTTy; | | 7 | +} | | 8 | + | 3 | 9 | module.exports = { | 4 | 10 | blue: '', | 5 | 11 | green: '', | @@ -8,9 +14,17 @@ module.exports = { | 8 | 14 | gray: '', | 9 | 15 | clear: '', | 10 | 16 | hasColors: false, | | 17 | + shouldColorize(stream) { | | 18 | + if (process.env.FORCE_COLOR !== undefined) { | | 19 | + return lazyInternalTTY().getColorDepth() > 2; | | 20 | + } | | 21 | + return stream?.isTTY && ( | | 22 | + typeof stream.getColorDepth === 'function' ? | | 23 | + stream.getColorDepth() > 2 : true); | | 24 | + }, | 11 | 25 | refresh() { | 12 | 26 | if (process.stderr.isTTY) { | 13 | | - const hasColors = process.stderr.hasColors(); | | 27 | + const hasColors = module.exports.shouldColorize(process.stderr); | 14 | 28 | module.exports.blue = hasColors ? '\u001b[34m' : ''; | 15 | 29 | module.exports.green = hasColors ? '\u001b[32m' : ''; | 16 | 30 | module.exports.white = hasColors ? '\u001b[39m' : ''; | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/util/debuglog.js +7-1Lines changed: 7 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -45,13 +45,19 @@ function emitWarningIfNeeded(set) { | 45 | 45 |
| 46 | 46 | const noop = () => {}; | 47 | 47 |
| | 48 | +let utilColors; | | 49 | +function lazyUtilColors() { | | 50 | + utilColors ??= require('internal/util/colors'); | | 51 | + return utilColors; | | 52 | +} | | 53 | + | 48 | 54 | function debuglogImpl(enabled, set) { | 49 | 55 | if (debugImpls[set] === undefined) { | 50 | 56 | if (enabled) { | 51 | 57 | const pid = process.pid; | 52 | 58 | emitWarningIfNeeded(set); | 53 | 59 | debugImpls[set] = function debug(...args) { | 54 | | - const colors = process.stderr.hasColors && process.stderr.hasColors(); | | 60 | + const colors = lazyUtilColors().shouldColorize(process.stderr); | 55 | 61 | const msg = formatWithOptions({ colors }, ...args); | 56 | 62 | const coloredPID = inspect(pid, { colors }); | 57 | 63 | process.stderr.write(format('%s %s: %s\n', set, coloredPID, msg)); | |
Collapse file Copy file name to clipboardExpand all lines: lib/repl.js +2-5Lines changed: 2 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -121,6 +121,7 @@ const { | 121 | 121 | commonPrefix, | 122 | 122 | } = require('internal/readline/utils'); | 123 | 123 | const { Console } = require('console'); | | 124 | +const { shouldColorize } = require('internal/util/colors'); | 124 | 125 | const CJSModule = require('internal/modules/cjs/loader').Module; | 125 | 126 | let _builtinLibs = ArrayPrototypeFilter( | 126 | 127 | CJSModule.builtinModules, | @@ -270,11 +271,7 @@ function REPLServer(prompt, | 270 | 271 |
| 271 | 272 | if (options.terminal && options.useColors === undefined) { | 272 | 273 | // If possible, check if stdout supports colors or not. | 273 | | - if (options.output.hasColors) { | 274 | | - options.useColors = options.output.hasColors(); | 275 | | - } else if (process.env.NODE_DISABLE_COLORS === undefined) { | 276 | | - options.useColors = true; | 277 | | - } | | 274 | + options.useColors = shouldColorize(options.output) || process.env.NODE_DISABLE_COLORS === undefined; | 278 | 275 | } | 279 | 276 |
| 280 | 277 | // TODO(devsnek): Add a test case for custom eval functions. | |
Collapse file Copy file name to clipboardExpand all lines: test/common/assertSnapshot.js +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -54,15 +54,15 @@ async function assertSnapshot(actual, filename = process.argv[1]) { | 54 | 54 | * @param {boolean} [options.tty] - whether to spawn the process in a pseudo-tty | 55 | 55 | * @returns {Promise<void>} | 56 | 56 | */ | 57 | | -async function spawnAndAssert(filename, transform = (x) => x, { tty = false } = {}) { | | 57 | +async function spawnAndAssert(filename, transform = (x) => x, { tty = false, ...options } = {}) { | 58 | 58 | if (tty && common.isWindows) { | 59 | 59 | test({ skip: 'Skipping pseudo-tty tests, as pseudo terminals are not available on Windows.' }); | 60 | 60 | return; | 61 | 61 | } | 62 | 62 | const flags = common.parseTestFlags(filename); | 63 | 63 | const executable = tty ? 'tools/pseudo-tty.py' : process.execPath; | 64 | 64 | const args = tty ? [process.execPath, ...flags, filename] : [...flags, filename]; | 65 | | - const { stdout, stderr } = await common.spawnPromisified(executable, args); | | 65 | + const { stdout, stderr } = await common.spawnPromisified(executable, args, options); | 66 | 66 | await assertSnapshot(transform(`${stdout}${stderr}`), filename); | 67 | 67 | } | 68 | 68 |
| |
Collapse file Copy file name to clipboard +5Lines changed: 5 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +require('../../common'); | | 4 | + | | 5 | +console.log(123, 'foo', { bar: 'baz' }); |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +[33m123[39m foo { bar: [32m'baz'[39m } |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +throw new Error('Should include grayed stack trace') |
|