From 866f82095ec691b23b5db329d9dbfc2539b4e5d4 Mon Sep 17 00:00:00 2001 From: Bradley Farias Date: Mon, 7 Feb 2022 10:04:26 -0600 Subject: [PATCH 1/7] util: make debuglog show up in --inspect logs --- lib/internal/bootstrap/browser.js | 2 -- lib/internal/util/debuglog.js | 22 ++++++++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/internal/bootstrap/browser.js b/lib/internal/bootstrap/browser.js index 68dac3b1ca4b8c..798d21ea16f3dd 100644 --- a/lib/internal/bootstrap/browser.js +++ b/lib/internal/bootstrap/browser.js @@ -78,8 +78,6 @@ function createGlobalConsole(consoleFromVM) { const inspector = require('internal/util/inspector'); // This will be exposed by `require('inspector').console` later. inspector.consoleFromVM = consoleFromVM; - // TODO(joyeecheung): postpone this until the first time inspector - // is activated. inspector.wrapConsole(consoleFromNode, consoleFromVM); const { setConsoleExtensionInstaller } = internalBinding('inspector'); // Setup inspector command line API. diff --git a/lib/internal/util/debuglog.js b/lib/internal/util/debuglog.js index 4b5c7cab44ad77..de0d1aab42daed 100644 --- a/lib/internal/util/debuglog.js +++ b/lib/internal/util/debuglog.js @@ -9,6 +9,24 @@ const { StringPrototypeToLowerCase, StringPrototypeToUpperCase, } = primordials; +const wrapDebugLog = (set, logger) => { + const { hasInspector } = internalBinding('config'); + if (hasInspector) { + const { consoleCall } = internalBinding('inspector'); + const pid = process.pid; + return (...args) => { + const inspect = require('internal/util/inspector'); + return consoleCall((maybeFmt, ...args) => { + if (typeof maybeFmt === 'string') { + inspect.consoleFromVM.debug(`%s %i: ${maybeFmt}`, set, pid, ...args); + } else { + inspect.consoleFromVM.debug(`%s %i:`, set, pid, maybeFmt, ...args); + } + }, logger, ...args); + }; + } + return logger; +}; const { inspect, format, formatWithOptions } = require('internal/util/inspect'); @@ -51,12 +69,12 @@ function debuglogImpl(enabled, set) { if (enabled) { const pid = process.pid; emitWarningIfNeeded(set); - debugImpls[set] = function debug(...args) { + debugImpls[set] = wrapDebugLog(set, function debug(...args) { const colors = process.stderr.hasColors && process.stderr.hasColors(); const msg = formatWithOptions({ colors }, ...args); const coloredPID = inspect(pid, { colors }); process.stderr.write(format('%s %s: %s\n', set, coloredPID, msg)); - }; + }); } else { debugImpls[set] = noop; } From 8a363f23f1ff2bf5028ac01429d356a15f74c117 Mon Sep 17 00:00:00 2001 From: Bradley Farias Date: Mon, 7 Feb 2022 10:28:52 -0600 Subject: [PATCH 2/7] fixup: linter --- lib/internal/util/debuglog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/util/debuglog.js b/lib/internal/util/debuglog.js index de0d1aab42daed..68dd9976ac3e21 100644 --- a/lib/internal/util/debuglog.js +++ b/lib/internal/util/debuglog.js @@ -20,7 +20,7 @@ const wrapDebugLog = (set, logger) => { if (typeof maybeFmt === 'string') { inspect.consoleFromVM.debug(`%s %i: ${maybeFmt}`, set, pid, ...args); } else { - inspect.consoleFromVM.debug(`%s %i:`, set, pid, maybeFmt, ...args); + inspect.consoleFromVM.debug('%s %i:', set, pid, maybeFmt, ...args); } }, logger, ...args); }; From 3851a8fabbed5c1e78dca0ad25a61da1fed3769f Mon Sep 17 00:00:00 2001 From: Bradley Farias Date: Mon, 7 Feb 2022 13:18:23 -0600 Subject: [PATCH 3/7] fixup: simplify --- lib/internal/util/debuglog.js | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/lib/internal/util/debuglog.js b/lib/internal/util/debuglog.js index 68dd9976ac3e21..edf411d11684d6 100644 --- a/lib/internal/util/debuglog.js +++ b/lib/internal/util/debuglog.js @@ -9,26 +9,6 @@ const { StringPrototypeToLowerCase, StringPrototypeToUpperCase, } = primordials; -const wrapDebugLog = (set, logger) => { - const { hasInspector } = internalBinding('config'); - if (hasInspector) { - const { consoleCall } = internalBinding('inspector'); - const pid = process.pid; - return (...args) => { - const inspect = require('internal/util/inspector'); - return consoleCall((maybeFmt, ...args) => { - if (typeof maybeFmt === 'string') { - inspect.consoleFromVM.debug(`%s %i: ${maybeFmt}`, set, pid, ...args); - } else { - inspect.consoleFromVM.debug('%s %i:', set, pid, maybeFmt, ...args); - } - }, logger, ...args); - }; - } - return logger; -}; - -const { inspect, format, formatWithOptions } = require('internal/util/inspect'); // `debugImpls` and `testEnabled` are deliberately not initialized so any call // to `debuglog()` before `initializeDebugEnv()` is called will throw. @@ -69,12 +49,15 @@ function debuglogImpl(enabled, set) { if (enabled) { const pid = process.pid; emitWarningIfNeeded(set); - debugImpls[set] = wrapDebugLog(set, function debug(...args) { - const colors = process.stderr.hasColors && process.stderr.hasColors(); - const msg = formatWithOptions({ colors }, ...args); - const coloredPID = inspect(pid, { colors }); - process.stderr.write(format('%s %s: %s\n', set, coloredPID, msg)); - }); + debugImpls[set] = function debug(maybeFmt, ...args) { + if (typeof maybeFmt === 'string') { + // eslint-disable-next-line + console.debug(`%s %i: ${maybeFmt}`, set, pid, ...args); + } else { + // eslint-disable-next-line + console.debug('%s %i:', set, pid, maybeFmt, ...args); + } + }; } else { debugImpls[set] = noop; } From fdb31dd1e3ed3167252fb43014a814a62cad5761 Mon Sep 17 00:00:00 2001 From: Bradley Farias Date: Mon, 7 Mar 2022 15:18:39 -0600 Subject: [PATCH 4/7] fixup: oh no, this is bringing in something like #32308 --- lib/internal/console/constructor.js | 4 ++ lib/internal/console/global.js | 9 ++++- lib/internal/util/debuglog.js | 4 +- test/embedding/test-embedding.js | 27 ++++++++----- test/sequential/test-util-debug.js | 61 +++++++++++++++++------------ 5 files changed, 68 insertions(+), 37 deletions(-) diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js index 695a56164b7d84..7d68d1d4207de8 100644 --- a/lib/internal/console/constructor.js +++ b/lib/internal/console/constructor.js @@ -299,6 +299,10 @@ ObjectDefineProperties(Console.prototype, { ...consolePropAttributes, value: function(stream) { let color = this[kColorMode]; + if (typeof color === 'function') { + color = color(); + process._rawDebug(`COLOR: ${color}`) + } if (color === 'auto') { color = stream.isTTY && ( typeof stream.getColorDepth === 'function' ? diff --git a/lib/internal/console/global.js b/lib/internal/console/global.js index d6c0c24d529dcc..9362c54cbd38a9 100644 --- a/lib/internal/console/global.js +++ b/lib/internal/console/global.js @@ -20,6 +20,7 @@ const { ReflectOwnKeys, } = primordials; +const console = require('console'); const { Console, kBindStreamsLazy, @@ -44,8 +45,14 @@ for (const prop of ReflectOwnKeys(Console.prototype)) { ReflectDefineProperty(globalConsole, prop, desc); } +const { + getColorDepth +} = require('internal/tty'); globalConsole[kBindStreamsLazy](process); -globalConsole[kBindProperties](true, 'auto'); +globalConsole[kBindProperties](true, () => { + process._rawDebug('getColorDepth ' + getColorDepth()); + return getColorDepth() > 2 || 'auto'; +}); // This is a legacy feature - the Console constructor is exposed on // the global console instance. diff --git a/lib/internal/util/debuglog.js b/lib/internal/util/debuglog.js index edf411d11684d6..d3a19b745ed048 100644 --- a/lib/internal/util/debuglog.js +++ b/lib/internal/util/debuglog.js @@ -52,10 +52,10 @@ function debuglogImpl(enabled, set) { debugImpls[set] = function debug(maybeFmt, ...args) { if (typeof maybeFmt === 'string') { // eslint-disable-next-line - console.debug(`%s %i: ${maybeFmt}`, set, pid, ...args); + console.error(`%s %o: ${maybeFmt}`, set, pid, ...args); } else { // eslint-disable-next-line - console.debug('%s %i:', set, pid, maybeFmt, ...args); + console.error('%s %o:', set, pid, maybeFmt, ...args); } }; } else { diff --git a/test/embedding/test-embedding.js b/test/embedding/test-embedding.js index 2fbaaf0ef81a49..8ff84d6ce55d60 100644 --- a/test/embedding/test-embedding.js +++ b/test/embedding/test-embedding.js @@ -13,31 +13,40 @@ if (common.isWindows) { } binary = path.resolve(__dirname, '..', '..', binary); +const env = { + ...process.env, + NODE_DISABLE_COLORS: true +}; +const spawnOptions = { + env, + encoding: 'utf8' +}; + assert.strictEqual( - child_process.spawnSync(binary, ['console.log(42)']) - .stdout.toString().trim(), + child_process.spawnSync(binary, ['console.log(42)'], spawnOptions) + .stdout.trim(), '42'); assert.strictEqual( - child_process.spawnSync(binary, ['console.log(embedVars.nön_ascıı)']) - .stdout.toString().trim(), + child_process.spawnSync(binary, ['console.log(embedVars.nön_ascıı)'], spawnOptions) + .stdout.trim(), '🏳️‍🌈'); assert.strictEqual( - child_process.spawnSync(binary, ['console.log(42)']) - .stdout.toString().trim(), + child_process.spawnSync(binary, ['console.log(42)'], spawnOptions) + .stdout.trim(), '42'); assert.strictEqual( - child_process.spawnSync(binary, ['throw new Error()']).status, + child_process.spawnSync(binary, ['throw new Error()'], spawnOptions).status, 1); assert.strictEqual( - child_process.spawnSync(binary, ['process.exitCode = 8']).status, + child_process.spawnSync(binary, ['process.exitCode = 8'], spawnOptions).status, 8); const fixturePath = JSON.stringify(fixtures.path('exit.js')); assert.strictEqual( - child_process.spawnSync(binary, [`require(${fixturePath})`, 92]).status, + child_process.spawnSync(binary, [`require(${fixturePath})`, 92], spawnOptions).status, 92); diff --git a/test/sequential/test-util-debug.js b/test/sequential/test-util-debug.js index f8be25f6f880b8..3cef3c1b559108 100644 --- a/test/sequential/test-util-debug.js +++ b/test/sequential/test-util-debug.js @@ -32,27 +32,27 @@ else parent(); function parent() { - test('foo,tud,bar', true, 'tud'); - test('foo,tud', true, 'tud'); - test('tud,bar', true, 'tud'); + // test('foo,tud,bar', true, 'tud'); + // test('foo,tud', true, 'tud'); + // test('tud,bar', true, 'tud'); test('tud', true, 'tud'); - test('foo,bar', false, 'tud'); - test('', false, 'tud'); + // test('foo,bar', false, 'tud'); + // test('', false, 'tud'); - test('###', true, '###'); - test('hi:)', true, 'hi:)'); - test('f$oo', true, 'f$oo'); - test('f$oo', false, 'f.oo'); - test('no-bar-at-all', false, 'bar'); + // test('###', true, '###'); + // test('hi:)', true, 'hi:)'); + // test('f$oo', true, 'f$oo'); + // test('f$oo', false, 'f.oo'); + // test('no-bar-at-all', false, 'bar'); - test('test-abc', true, 'test-abc'); - test('test-a', false, 'test-abc'); - test('test-*', true, 'test-abc'); - test('test-*c', true, 'test-abc'); - test('test-*abc', true, 'test-abc'); - test('abc-test', true, 'abc-test'); - test('a*-test', true, 'abc-test'); - test('*-test', true, 'abc-test'); + // test('test-abc', true, 'test-abc'); + // test('test-a', false, 'test-abc'); + // test('test-*', true, 'test-abc'); + // test('test-*c', true, 'test-abc'); + // test('test-*abc', true, 'test-abc'); + // test('abc-test', true, 'abc-test'); + // test('a*-test', true, 'abc-test'); + // test('*-test', true, 'abc-test'); } function test(environ, shouldWrite, section, forceColors = false) { @@ -100,17 +100,28 @@ function test(environ, shouldWrite, section, forceColors = false) { }); child.on('close', common.mustCall((c) => { - assert(!c); - assert.strictEqual(err, expectErr); - assert.strictEqual(out, expectOut); - // Run the test again, this time with colors enabled. - if (!forceColors) { - test(environ, shouldWrite, section, true); + try { + assert(!c); + assert.strictEqual(err, expectErr); + // assert.strictEqual(out, expectOut); + // Run the test again, this time with colors enabled. + if (!forceColors) { + test(environ, shouldWrite, section, true); + } + } catch (e) { + console.error('FAILED PERMUTATION:', {environ, shouldWrite, section, forceColors}); + console.error('COMMAND:', Object.entries({ + NODE_DEBUG: environ, + FORCE_COLOR: forceColors ? 'true' : 'false' + }).reduce( + (acc, [k,v]) => {acc.push(`${k}=${JSON.stringify(v)}`); return acc}, + [] + ).join(' '), 'node', [__filename, 'child', JSON.stringify(section)].join(' '), ) + throw e; } })); } - function child(section) { const tty = require('tty'); // Make sure we check for colors, no matter of the stream's default. From 8f0869ee4063646c2c65cfaf8fe1539ebf609a4a Mon Sep 17 00:00:00 2001 From: Bradley Farias Date: Mon, 7 Mar 2022 15:29:53 -0600 Subject: [PATCH 5/7] fixup: linter --- lib/internal/console/constructor.js | 2 +- lib/internal/console/global.js | 2 -- test/sequential/test-util-debug.js | 8 ++++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js index 7d68d1d4207de8..f6db0c00f8485b 100644 --- a/lib/internal/console/constructor.js +++ b/lib/internal/console/constructor.js @@ -301,7 +301,7 @@ ObjectDefineProperties(Console.prototype, { let color = this[kColorMode]; if (typeof color === 'function') { color = color(); - process._rawDebug(`COLOR: ${color}`) + process._rawDebug(`COLOR: ${color}`); } if (color === 'auto') { color = stream.isTTY && ( diff --git a/lib/internal/console/global.js b/lib/internal/console/global.js index 9362c54cbd38a9..4ba628e8369677 100644 --- a/lib/internal/console/global.js +++ b/lib/internal/console/global.js @@ -20,7 +20,6 @@ const { ReflectOwnKeys, } = primordials; -const console = require('console'); const { Console, kBindStreamsLazy, @@ -50,7 +49,6 @@ const { } = require('internal/tty'); globalConsole[kBindStreamsLazy](process); globalConsole[kBindProperties](true, () => { - process._rawDebug('getColorDepth ' + getColorDepth()); return getColorDepth() > 2 || 'auto'; }); diff --git a/test/sequential/test-util-debug.js b/test/sequential/test-util-debug.js index 3cef3c1b559108..a1b99585111cc0 100644 --- a/test/sequential/test-util-debug.js +++ b/test/sequential/test-util-debug.js @@ -103,20 +103,20 @@ function test(environ, shouldWrite, section, forceColors = false) { try { assert(!c); assert.strictEqual(err, expectErr); - // assert.strictEqual(out, expectOut); + assert.strictEqual(out, expectOut); // Run the test again, this time with colors enabled. if (!forceColors) { test(environ, shouldWrite, section, true); } } catch (e) { - console.error('FAILED PERMUTATION:', {environ, shouldWrite, section, forceColors}); + console.error('FAILED PERMUTATION:', { environ, shouldWrite, section, forceColors }); console.error('COMMAND:', Object.entries({ NODE_DEBUG: environ, FORCE_COLOR: forceColors ? 'true' : 'false' }).reduce( - (acc, [k,v]) => {acc.push(`${k}=${JSON.stringify(v)}`); return acc}, + (acc, [k, v]) => { acc.push(`${k}=${JSON.stringify(v)}`); return acc; }, [] - ).join(' '), 'node', [__filename, 'child', JSON.stringify(section)].join(' '), ) + ).join(' '), 'node', [__filename, 'child', JSON.stringify(section)].join(' ')); throw e; } })); From 0766e1d79a1c149b3c4f70e26a2cbe1ce5e2f93c Mon Sep 17 00:00:00 2001 From: Bradley Farias Date: Tue, 8 Mar 2022 08:57:28 -0600 Subject: [PATCH 6/7] fixup: bad leftovers --- lib/internal/console/constructor.js | 1 - test/sequential/test-util-debug.js | 36 ++++++++++++++--------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js index f6db0c00f8485b..36e68d8b522ce3 100644 --- a/lib/internal/console/constructor.js +++ b/lib/internal/console/constructor.js @@ -301,7 +301,6 @@ ObjectDefineProperties(Console.prototype, { let color = this[kColorMode]; if (typeof color === 'function') { color = color(); - process._rawDebug(`COLOR: ${color}`); } if (color === 'auto') { color = stream.isTTY && ( diff --git a/test/sequential/test-util-debug.js b/test/sequential/test-util-debug.js index a1b99585111cc0..d565ca6ae00895 100644 --- a/test/sequential/test-util-debug.js +++ b/test/sequential/test-util-debug.js @@ -32,27 +32,27 @@ else parent(); function parent() { - // test('foo,tud,bar', true, 'tud'); - // test('foo,tud', true, 'tud'); - // test('tud,bar', true, 'tud'); + test('foo,tud,bar', true, 'tud'); + test('foo,tud', true, 'tud'); + test('tud,bar', true, 'tud'); test('tud', true, 'tud'); - // test('foo,bar', false, 'tud'); - // test('', false, 'tud'); + test('foo,bar', false, 'tud'); + test('', false, 'tud'); - // test('###', true, '###'); - // test('hi:)', true, 'hi:)'); - // test('f$oo', true, 'f$oo'); - // test('f$oo', false, 'f.oo'); - // test('no-bar-at-all', false, 'bar'); + test('###', true, '###'); + test('hi:)', true, 'hi:)'); + test('f$oo', true, 'f$oo'); + test('f$oo', false, 'f.oo'); + test('no-bar-at-all', false, 'bar'); - // test('test-abc', true, 'test-abc'); - // test('test-a', false, 'test-abc'); - // test('test-*', true, 'test-abc'); - // test('test-*c', true, 'test-abc'); - // test('test-*abc', true, 'test-abc'); - // test('abc-test', true, 'abc-test'); - // test('a*-test', true, 'abc-test'); - // test('*-test', true, 'abc-test'); + test('test-abc', true, 'test-abc'); + test('test-a', false, 'test-abc'); + test('test-*', true, 'test-abc'); + test('test-*c', true, 'test-abc'); + test('test-*abc', true, 'test-abc'); + test('abc-test', true, 'abc-test'); + test('a*-test', true, 'abc-test'); + test('*-test', true, 'abc-test'); } function test(environ, shouldWrite, section, forceColors = false) { From af6dce8829cd7a25318dbda966b4de4a9df8c7ca Mon Sep 17 00:00:00 2001 From: Bradley Farias Date: Tue, 8 Mar 2022 14:12:13 -0600 Subject: [PATCH 7/7] fixup: change test rather than altering console behavior --- lib/internal/console/constructor.js | 3 --- lib/internal/console/global.js | 7 +------ test/embedding/test-embedding.js | 27 +++++++++------------------ test/sequential/test-util-debug.js | 14 +++++++++++++- 4 files changed, 23 insertions(+), 28 deletions(-) diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js index 36e68d8b522ce3..695a56164b7d84 100644 --- a/lib/internal/console/constructor.js +++ b/lib/internal/console/constructor.js @@ -299,9 +299,6 @@ ObjectDefineProperties(Console.prototype, { ...consolePropAttributes, value: function(stream) { let color = this[kColorMode]; - if (typeof color === 'function') { - color = color(); - } if (color === 'auto') { color = stream.isTTY && ( typeof stream.getColorDepth === 'function' ? diff --git a/lib/internal/console/global.js b/lib/internal/console/global.js index 4ba628e8369677..d6c0c24d529dcc 100644 --- a/lib/internal/console/global.js +++ b/lib/internal/console/global.js @@ -44,13 +44,8 @@ for (const prop of ReflectOwnKeys(Console.prototype)) { ReflectDefineProperty(globalConsole, prop, desc); } -const { - getColorDepth -} = require('internal/tty'); globalConsole[kBindStreamsLazy](process); -globalConsole[kBindProperties](true, () => { - return getColorDepth() > 2 || 'auto'; -}); +globalConsole[kBindProperties](true, 'auto'); // This is a legacy feature - the Console constructor is exposed on // the global console instance. diff --git a/test/embedding/test-embedding.js b/test/embedding/test-embedding.js index 8ff84d6ce55d60..2fbaaf0ef81a49 100644 --- a/test/embedding/test-embedding.js +++ b/test/embedding/test-embedding.js @@ -13,40 +13,31 @@ if (common.isWindows) { } binary = path.resolve(__dirname, '..', '..', binary); -const env = { - ...process.env, - NODE_DISABLE_COLORS: true -}; -const spawnOptions = { - env, - encoding: 'utf8' -}; - assert.strictEqual( - child_process.spawnSync(binary, ['console.log(42)'], spawnOptions) - .stdout.trim(), + child_process.spawnSync(binary, ['console.log(42)']) + .stdout.toString().trim(), '42'); assert.strictEqual( - child_process.spawnSync(binary, ['console.log(embedVars.nön_ascıı)'], spawnOptions) - .stdout.trim(), + child_process.spawnSync(binary, ['console.log(embedVars.nön_ascıı)']) + .stdout.toString().trim(), '🏳️‍🌈'); assert.strictEqual( - child_process.spawnSync(binary, ['console.log(42)'], spawnOptions) - .stdout.trim(), + child_process.spawnSync(binary, ['console.log(42)']) + .stdout.toString().trim(), '42'); assert.strictEqual( - child_process.spawnSync(binary, ['throw new Error()'], spawnOptions).status, + child_process.spawnSync(binary, ['throw new Error()']).status, 1); assert.strictEqual( - child_process.spawnSync(binary, ['process.exitCode = 8'], spawnOptions).status, + child_process.spawnSync(binary, ['process.exitCode = 8']).status, 8); const fixturePath = JSON.stringify(fixtures.path('exit.js')); assert.strictEqual( - child_process.spawnSync(binary, [`require(${fixturePath})`, 92], spawnOptions).status, + child_process.spawnSync(binary, [`require(${fixturePath})`, 92]).status, 92); diff --git a/test/sequential/test-util-debug.js b/test/sequential/test-util-debug.js index d565ca6ae00895..e76a585d65c127 100644 --- a/test/sequential/test-util-debug.js +++ b/test/sequential/test-util-debug.js @@ -112,7 +112,7 @@ function test(environ, shouldWrite, section, forceColors = false) { console.error('FAILED PERMUTATION:', { environ, shouldWrite, section, forceColors }); console.error('COMMAND:', Object.entries({ NODE_DEBUG: environ, - FORCE_COLOR: forceColors ? 'true' : 'false' + FORCE_COLOR: forceColors ? 'true' : '' }).reduce( (acc, [k, v]) => { acc.push(`${k}=${JSON.stringify(v)}`); return acc; }, [] @@ -125,9 +125,21 @@ function test(environ, shouldWrite, section, forceColors = false) { function child(section) { const tty = require('tty'); // Make sure we check for colors, no matter of the stream's default. + + const forceColors = process.env.FORCE_COLOR === 'true'; Object.defineProperty(process.stderr, 'hasColors', { value: tty.WriteStream.prototype.hasColors }); + Object.defineProperty(process.stderr, 'isTTY', { + value: forceColors, + }); + Object.defineProperty(process.stdout, 'hasColors', { + value: tty.WriteStream.prototype.hasColors + }); + Object.defineProperty(process.stdout, 'isTTY', { + value: forceColors, + }); + // eslint-disable-next-line no-restricted-syntax const debug = util.debuglog(section, common.mustCall((cb) => { assert.strictEqual(typeof cb, 'function');