Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c46b31f

Browse filesBrowse files
MoLowdanielleadams
authored andcommitted
lib: support FORCE_COLOR for non TTY streams
PR-URL: #48034 Backport-PR-URL: #48684 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
1 parent a2bfe02 commit c46b31f
Copy full SHA for c46b31f

File tree

Expand file treeCollapse file tree

14 files changed

+110
-40
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

14 files changed

+110
-40
lines changed
Open diff view settings
Collapse file

‎lib/internal/console/constructor.js‎

Copy file name to clipboardExpand all lines: lib/internal/console/constructor.js
+7-4Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ const kMaxGroupIndentation = 1000;
8080
// Lazy loaded for startup performance.
8181
let cliTable;
8282

83+
let utilColors;
84+
function lazyUtilColors() {
85+
utilColors ??= require('internal/util/colors');
86+
return utilColors;
87+
}
88+
8389
// Track amount of indentation required via `console.group()`.
8490
const kGroupIndent = Symbol('kGroupIndent');
8591
const kGroupIndentationWidth = Symbol('kGroupIndentWidth');
@@ -96,7 +102,6 @@ const kUseStdout = Symbol('kUseStdout');
96102
const kUseStderr = Symbol('kUseStderr');
97103

98104
const optionsMap = new SafeWeakMap();
99-
100105
function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
101106
// We have to test new.target here to see if this function is called
102107
// with new, because we need to define a custom instanceof to accommodate
@@ -315,9 +320,7 @@ ObjectDefineProperties(Console.prototype, {
315320
value: function(stream) {
316321
let color = this[kColorMode];
317322
if (color === 'auto') {
318-
color = stream.isTTY && (
319-
typeof stream.getColorDepth === 'function' ?
320-
stream.getColorDepth() > 2 : true);
323+
color = lazyUtilColors().shouldColorize(stream);
321324
}
322325

323326
const options = optionsMap.get(this);
Collapse file

‎lib/internal/errors.js‎

Copy file name to clipboardExpand all lines: lib/internal/errors.js
+7-4Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,12 @@ function lazyInternalUtilInspect() {
190190
return internalUtilInspect;
191191
}
192192

193+
let utilColors;
194+
function lazyUtilColors() {
195+
utilColors ??= require('internal/util/colors');
196+
return utilColors;
197+
}
198+
193199
let buffer;
194200
function lazyBuffer() {
195201
buffer ??= require('buffer').Buffer;
@@ -795,10 +801,7 @@ const fatalExceptionStackEnhancers = {
795801
colors: defaultColors,
796802
},
797803
} = 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);
802805
try {
803806
return inspect(error, {
804807
colors,
Collapse file

‎lib/internal/test_runner/reporter/spec.js‎

Copy file name to clipboardExpand all lines: lib/internal/test_runner/reporter/spec.js
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ const {
1414
const assert = require('assert');
1515
const Transform = require('internal/streams/transform');
1616
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');
1818
const { kSubtestsFailed } = require('internal/test_runner/test');
1919
const { getCoverageReport } = require('internal/test_runner/utils');
2020

21-
const inspectOptions = { __proto__: null, colors: hasColors, breakLength: Infinity };
21+
const inspectOptions = { __proto__: null, colors: shouldColorize(process.stdout), breakLength: Infinity };
2222

2323
const colors = {
2424
'__proto__': null,
Collapse file

‎lib/internal/util/colors.js‎

Copy file name to clipboardExpand all lines: lib/internal/util/colors.js
+15-1Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
'use strict';
22

3+
let internalTTy;
4+
function lazyInternalTTY() {
5+
internalTTy ??= require('internal/tty');
6+
return internalTTy;
7+
}
8+
39
module.exports = {
410
blue: '',
511
green: '',
@@ -8,9 +14,17 @@ module.exports = {
814
gray: '',
915
clear: '',
1016
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+
},
1125
refresh() {
1226
if (process.stderr.isTTY) {
13-
const hasColors = process.stderr.hasColors();
27+
const hasColors = module.exports.shouldColorize(process.stderr);
1428
module.exports.blue = hasColors ? '\u001b[34m' : '';
1529
module.exports.green = hasColors ? '\u001b[32m' : '';
1630
module.exports.white = hasColors ? '\u001b[39m' : '';
Collapse file

‎lib/internal/util/debuglog.js‎

Copy file name to clipboardExpand all lines: lib/internal/util/debuglog.js
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,19 @@ function emitWarningIfNeeded(set) {
4646

4747
const noop = () => {};
4848

49+
let utilColors;
50+
function lazyUtilColors() {
51+
utilColors ??= require('internal/util/colors');
52+
return utilColors;
53+
}
54+
4955
function debuglogImpl(enabled, set) {
5056
if (debugImpls[set] === undefined) {
5157
if (enabled) {
5258
const pid = process.pid;
5359
emitWarningIfNeeded(set);
5460
debugImpls[set] = function debug(...args) {
55-
const colors = process.stderr.hasColors && process.stderr.hasColors();
61+
const colors = lazyUtilColors().shouldColorize(process.stderr);
5662
const msg = formatWithOptions({ colors }, ...args);
5763
const coloredPID = inspect(pid, { colors });
5864
process.stderr.write(format('%s %s: %s\n', set, coloredPID, msg));
Collapse file

‎lib/repl.js‎

Copy file name to clipboardExpand all lines: lib/repl.js
+2-5Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ const {
122122
commonPrefix,
123123
} = require('internal/readline/utils');
124124
const { Console } = require('console');
125+
const { shouldColorize } = require('internal/util/colors');
125126
const CJSModule = require('internal/modules/cjs/loader').Module;
126127
let _builtinLibs = ArrayPrototypeFilter(
127128
CJSModule.builtinModules,
@@ -272,11 +273,7 @@ function REPLServer(prompt,
272273

273274
if (options.terminal && options.useColors === undefined) {
274275
// If possible, check if stdout supports colors or not.
275-
if (options.output.hasColors) {
276-
options.useColors = options.output.hasColors();
277-
} else if (process.env.NODE_DISABLE_COLORS === undefined) {
278-
options.useColors = true;
279-
}
276+
options.useColors = shouldColorize(options.output) || process.env.NODE_DISABLE_COLORS === undefined;
280277
}
281278

282279
// TODO(devsnek): Add a test case for custom eval functions.
Collapse file

‎test/common/assertSnapshot.js‎

Copy file name to clipboardExpand all lines: test/common/assertSnapshot.js
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ async function assertSnapshot(actual, filename = process.argv[1]) {
5454
* @param {boolean} [options.tty] - whether to spawn the process in a pseudo-tty
5555
* @returns {Promise<void>}
5656
*/
57-
async function spawnAndAssert(filename, transform = (x) => x, { tty = false } = {}) {
57+
async function spawnAndAssert(filename, transform = (x) => x, { tty = false, ...options } = {}) {
5858
if (tty && common.isWindows) {
5959
test({ skip: 'Skipping pseudo-tty tests, as pseudo terminals are not available on Windows.' });
6060
return;
6161
}
6262
const flags = common.parseTestFlags(filename);
6363
const executable = tty ? 'tools/pseudo-tty.py' : process.execPath;
6464
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);
6666
await assertSnapshot(transform(`${stdout}${stderr}`), filename);
6767
}
6868

Collapse file
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use strict';
2+
3+
require('../../common');
4+
5+
console.log(123, 'foo', { bar: 'baz' });
Collapse file
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
123 foo { bar: 'baz' }
Collapse file
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
throw new Error('Should include grayed stack trace')

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.