diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-05-14 17:32:09 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-14 17:32:09 -0400 |
commit | e39b94f3aa09bc77280b98caebb9ae472f8f6c5a (patch) | |
tree | 8bfaec53de64cd6dcfccf2045f4231265b091fdd | |
parent | 1e2b0a22196ab2a17ceae855293fdcd5a2596161 (diff) |
fix(runtime): output to stderr with colors if a tty and stdout is piped (#23813)
This also fixes a bug where Deno would output to stderr with colours
when piped and stdout was not piped.
-rw-r--r-- | cli/worker.rs | 6 | ||||
-rw-r--r-- | ext/console/01_console.js | 53 | ||||
-rw-r--r-- | runtime/js/99_main.js | 16 | ||||
-rw-r--r-- | runtime/ops/bootstrap.rs | 13 | ||||
-rw-r--r-- | runtime/worker_bootstrap.rs | 6 |
5 files changed, 61 insertions, 33 deletions
diff --git a/cli/worker.rs b/cli/worker.rs index a05dff4b2..a49929ca5 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -601,7 +601,8 @@ impl CliMainWorkerFactory { locale: deno_core::v8::icu::get_language_tag(), location: shared.options.location.clone(), no_color: !colors::use_color(), - is_tty: deno_terminal::is_stdout_tty(), + is_stdout_tty: deno_terminal::is_stdout_tty(), + is_stderr_tty: deno_terminal::is_stderr_tty(), unstable: shared.options.unstable, unstable_features, user_agent: version::get_user_agent().to_string(), @@ -811,7 +812,8 @@ fn create_web_worker_callback( locale: deno_core::v8::icu::get_language_tag(), location: Some(args.main_module.clone()), no_color: !colors::use_color(), - is_tty: deno_terminal::is_stdout_tty(), + is_stdout_tty: deno_terminal::is_stdout_tty(), + is_stderr_tty: deno_terminal::is_stderr_tty(), unstable: shared.options.unstable, unstable_features, user_agent: version::get_user_agent().to_string(), diff --git a/ext/console/01_console.js b/ext/console/01_console.js index b851b4035..2b8075668 100644 --- a/ext/console/01_console.js +++ b/ext/console/01_console.js @@ -156,14 +156,20 @@ const { Uint8Array, } = primordials; -let noColor = () => false; +let noColorStdout = () => false; +let noColorStderr = () => false; -function setNoColorFn(fn) { - noColor = fn; +function setNoColorFns(stdoutFn, stderrFn) { + noColorStdout = stdoutFn; + noColorStderr = stderrFn; } -function getNoColor() { - return noColor(); +function getStdoutNoColor() { + return noColorStdout(); +} + +function getStderrNoColor() { + return noColorStderr(); } function assert(cond, msg = "Assertion failed.") { @@ -2927,6 +2933,7 @@ function cssToAnsi(css, prevCss = null) { function inspectArgs(args, inspectOptions = {}) { const ctx = { ...getDefaultInspectOptions(), + colors: inspectOptions.colors ?? !noColorStdout(), ...inspectOptions, }; if (inspectOptions.iterableLimit !== undefined) { @@ -2939,7 +2946,7 @@ function inspectArgs(args, inspectOptions = {}) { if (ctx.maxArrayLength === null) ctx.maxArrayLength = Infinity; if (ctx.maxStringLength === null) ctx.maxStringLength = Infinity; - const noColor = getNoColor(); + const noColor = !ctx.colors; const first = args[0]; let a = 0; let string = ""; @@ -3053,12 +3060,12 @@ const countMap = new SafeMap(); const timerMap = new SafeMap(); const isConsoleInstance = Symbol("isConsoleInstance"); -function getConsoleInspectOptions() { - const color = !getNoColor(); +/** @param noColor {boolean} */ +function getConsoleInspectOptions(noColor) { return { ...getDefaultInspectOptions(), - colors: color, - stylize: color ? createStylizeWithColor(styles, colors) : stylizeNoColor, + colors: !noColor, + stylize: noColor ? stylizeNoColor : createStylizeWithColor(styles, colors), }; } @@ -3090,7 +3097,7 @@ class Console { log = (...args) => { this.#printFunc( inspectArgs(args, { - ...getConsoleInspectOptions(), + ...getConsoleInspectOptions(noColorStdout()), indentLevel: this.indentLevel, }) + "\n", 1, @@ -3100,7 +3107,7 @@ class Console { debug = (...args) => { this.#printFunc( inspectArgs(args, { - ...getConsoleInspectOptions(), + ...getConsoleInspectOptions(noColorStdout()), indentLevel: this.indentLevel, }) + "\n", 0, @@ -3110,7 +3117,7 @@ class Console { info = (...args) => { this.#printFunc( inspectArgs(args, { - ...getConsoleInspectOptions(), + ...getConsoleInspectOptions(noColorStdout()), indentLevel: this.indentLevel, }) + "\n", 1, @@ -3119,8 +3126,10 @@ class Console { dir = (obj = undefined, options = {}) => { this.#printFunc( - inspectArgs([obj], { ...getConsoleInspectOptions(), ...options }) + - "\n", + inspectArgs([obj], { + ...getConsoleInspectOptions(noColorStdout()), + ...options, + }) + "\n", 1, ); }; @@ -3130,7 +3139,7 @@ class Console { warn = (...args) => { this.#printFunc( inspectArgs(args, { - ...getConsoleInspectOptions(), + ...getConsoleInspectOptions(noColorStderr()), indentLevel: this.indentLevel, }) + "\n", 2, @@ -3140,7 +3149,7 @@ class Console { error = (...args) => { this.#printFunc( inspectArgs(args, { - ...getConsoleInspectOptions(), + ...getConsoleInspectOptions(noColorStderr()), indentLevel: this.indentLevel, }) + "\n", 3, @@ -3353,7 +3362,10 @@ class Console { trace = (...args) => { const message = inspectArgs( args, - { ...getConsoleInspectOptions(), indentLevel: 0 }, + { + ...getConsoleInspectOptions(noColorStderr()), + indentLevel: 0, + }, ); const err = { name: "Trace", @@ -3473,10 +3485,11 @@ export { formatNumber, formatValue, getDefaultInspectOptions, - getNoColor, + getStderrNoColor, + getStdoutNoColor, inspect, inspectArgs, quoteString, - setNoColorFn, + setNoColorFns, styles, }; diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 2ea122e34..fcec6b91a 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -8,7 +8,8 @@ import { core, internals, primordials } from "ext:core/mod.js"; const ops = core.ops; import { op_bootstrap_args, - op_bootstrap_is_tty, + op_bootstrap_is_stderr_tty, + op_bootstrap_is_stdout_tty, op_bootstrap_no_color, op_bootstrap_pid, op_main_module, @@ -62,10 +63,10 @@ import * as timers from "ext:deno_web/02_timers.js"; import { customInspect, getDefaultInspectOptions, - getNoColor, + getStderrNoColor, inspectArgs, quoteString, - setNoColorFn, + setNoColorFns, } from "ext:deno_console/01_console.js"; import * as performance from "ext:deno_web/15_performance.js"; import * as url from "ext:deno_url/00_url.js"; @@ -379,7 +380,10 @@ function importScripts(...urls) { const opArgs = memoizeLazy(() => op_bootstrap_args()); const opPid = memoizeLazy(() => op_bootstrap_pid()); -setNoColorFn(() => op_bootstrap_no_color() || !op_bootstrap_is_tty()); +setNoColorFns( + () => op_bootstrap_no_color() || !op_bootstrap_is_stdout_tty(), + () => op_bootstrap_no_color() || !op_bootstrap_is_stderr_tty(), +); function formatException(error) { if ( @@ -390,11 +394,11 @@ function formatException(error) { } else if (typeof error == "string") { return `Uncaught ${ inspectArgs([quoteString(error, getDefaultInspectOptions())], { - colors: !getNoColor(), + colors: !getStderrNoColor(), }) }`; } else { - return `Uncaught ${inspectArgs([error], { colors: !getNoColor() })}`; + return `Uncaught ${inspectArgs([error], { colors: !getStderrNoColor() })}`; } } diff --git a/runtime/ops/bootstrap.rs b/runtime/ops/bootstrap.rs index cbb87db88..eb9dbc6e8 100644 --- a/runtime/ops/bootstrap.rs +++ b/runtime/ops/bootstrap.rs @@ -16,7 +16,8 @@ deno_core::extension!( op_bootstrap_language, op_bootstrap_log_level, op_bootstrap_no_color, - op_bootstrap_is_tty, + op_bootstrap_is_stdout_tty, + op_bootstrap_is_stderr_tty, op_bootstrap_unstable_args, op_snapshot_options, ], @@ -117,7 +118,13 @@ pub fn op_bootstrap_no_color(state: &mut OpState) -> bool { } #[op2(fast)] -pub fn op_bootstrap_is_tty(state: &mut OpState) -> bool { +pub fn op_bootstrap_is_stdout_tty(state: &mut OpState) -> bool { let options = state.borrow::<BootstrapOptions>(); - options.is_tty + options.is_stdout_tty +} + +#[op2(fast)] +pub fn op_bootstrap_is_stderr_tty(state: &mut OpState) -> bool { + let options = state.borrow::<BootstrapOptions>(); + options.is_stderr_tty } diff --git a/runtime/worker_bootstrap.rs b/runtime/worker_bootstrap.rs index 31cb883db..e1abf87fc 100644 --- a/runtime/worker_bootstrap.rs +++ b/runtime/worker_bootstrap.rs @@ -76,7 +76,8 @@ pub struct BootstrapOptions { pub location: Option<ModuleSpecifier>, /// Sets `Deno.noColor` in JS runtime. pub no_color: bool, - pub is_tty: bool, + pub is_stdout_tty: bool, + pub is_stderr_tty: bool, // --unstable flag, deprecated pub unstable: bool, // --unstable-* flags @@ -109,7 +110,8 @@ impl Default for BootstrapOptions { user_agent, cpu_count, no_color: !colors::use_color(), - is_tty: deno_terminal::is_stdout_tty(), + is_stdout_tty: deno_terminal::is_stdout_tty(), + is_stderr_tty: deno_terminal::is_stderr_tty(), enable_op_summary_metrics: Default::default(), enable_testing_features: Default::default(), log_level: Default::default(), |