mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
fix(console): support NO_COLOR and colors option in all scenarios (#21910)
Noticed in #21607
This commit is contained in:
parent
80d5ffbe7c
commit
bd1358efab
5 changed files with 55 additions and 24 deletions
|
@ -2335,10 +2335,14 @@ const denoInspectDefaultOptions = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function getDefaultInspectOptions() {
|
function getDefaultInspectOptions() {
|
||||||
|
const color = !getNoColor();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
budget: {},
|
budget: {},
|
||||||
seen: [],
|
seen: [],
|
||||||
...denoInspectDefaultOptions,
|
...denoInspectDefaultOptions,
|
||||||
|
colors: color,
|
||||||
|
stylize: color ? createStylizeWithColor(styles, colors) : stylizeNoColor,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2939,7 +2943,6 @@ function inspectArgs(args, inspectOptions = {}) {
|
||||||
if (ctx.maxArrayLength === null) ctx.maxArrayLength = Infinity;
|
if (ctx.maxArrayLength === null) ctx.maxArrayLength = Infinity;
|
||||||
if (ctx.maxStringLength === null) ctx.maxStringLength = Infinity;
|
if (ctx.maxStringLength === null) ctx.maxStringLength = Infinity;
|
||||||
|
|
||||||
const noColor = getNoColor();
|
|
||||||
const first = args[0];
|
const first = args[0];
|
||||||
let a = 0;
|
let a = 0;
|
||||||
let string = "";
|
let string = "";
|
||||||
|
@ -2982,7 +2985,7 @@ function inspectArgs(args, inspectOptions = {}) {
|
||||||
formattedArg = formatValue(ctx, args[a++], 0);
|
formattedArg = formatValue(ctx, args[a++], 0);
|
||||||
} else if (char == "c") {
|
} else if (char == "c") {
|
||||||
const value = args[a++];
|
const value = args[a++];
|
||||||
if (!noColor) {
|
if (ctx.colors) {
|
||||||
const css = parseCss(value);
|
const css = parseCss(value);
|
||||||
formattedArg = cssToAnsi(css, prevCss);
|
formattedArg = cssToAnsi(css, prevCss);
|
||||||
if (formattedArg != "") {
|
if (formattedArg != "") {
|
||||||
|
@ -3053,15 +3056,6 @@ const countMap = new SafeMap();
|
||||||
const timerMap = new SafeMap();
|
const timerMap = new SafeMap();
|
||||||
const isConsoleInstance = Symbol("isConsoleInstance");
|
const isConsoleInstance = Symbol("isConsoleInstance");
|
||||||
|
|
||||||
function getConsoleInspectOptions() {
|
|
||||||
const color = !getNoColor();
|
|
||||||
return {
|
|
||||||
...getDefaultInspectOptions(),
|
|
||||||
colors: color,
|
|
||||||
stylize: color ? createStylizeWithColor(styles, colors) : stylizeNoColor,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class Console {
|
class Console {
|
||||||
#printFunc = null;
|
#printFunc = null;
|
||||||
[isConsoleInstance] = false;
|
[isConsoleInstance] = false;
|
||||||
|
@ -3090,7 +3084,7 @@ class Console {
|
||||||
log = (...args) => {
|
log = (...args) => {
|
||||||
this.#printFunc(
|
this.#printFunc(
|
||||||
inspectArgs(args, {
|
inspectArgs(args, {
|
||||||
...getConsoleInspectOptions(),
|
...getDefaultInspectOptions(),
|
||||||
indentLevel: this.indentLevel,
|
indentLevel: this.indentLevel,
|
||||||
}) + "\n",
|
}) + "\n",
|
||||||
1,
|
1,
|
||||||
|
@ -3100,7 +3094,7 @@ class Console {
|
||||||
debug = (...args) => {
|
debug = (...args) => {
|
||||||
this.#printFunc(
|
this.#printFunc(
|
||||||
inspectArgs(args, {
|
inspectArgs(args, {
|
||||||
...getConsoleInspectOptions(),
|
...getDefaultInspectOptions(),
|
||||||
indentLevel: this.indentLevel,
|
indentLevel: this.indentLevel,
|
||||||
}) + "\n",
|
}) + "\n",
|
||||||
0,
|
0,
|
||||||
|
@ -3110,7 +3104,7 @@ class Console {
|
||||||
info = (...args) => {
|
info = (...args) => {
|
||||||
this.#printFunc(
|
this.#printFunc(
|
||||||
inspectArgs(args, {
|
inspectArgs(args, {
|
||||||
...getConsoleInspectOptions(),
|
...getDefaultInspectOptions(),
|
||||||
indentLevel: this.indentLevel,
|
indentLevel: this.indentLevel,
|
||||||
}) + "\n",
|
}) + "\n",
|
||||||
1,
|
1,
|
||||||
|
@ -3119,7 +3113,7 @@ class Console {
|
||||||
|
|
||||||
dir = (obj = undefined, options = {}) => {
|
dir = (obj = undefined, options = {}) => {
|
||||||
this.#printFunc(
|
this.#printFunc(
|
||||||
inspectArgs([obj], { ...getConsoleInspectOptions(), ...options }) +
|
inspectArgs([obj], { ...getDefaultInspectOptions(), ...options }) +
|
||||||
"\n",
|
"\n",
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
|
@ -3130,7 +3124,7 @@ class Console {
|
||||||
warn = (...args) => {
|
warn = (...args) => {
|
||||||
this.#printFunc(
|
this.#printFunc(
|
||||||
inspectArgs(args, {
|
inspectArgs(args, {
|
||||||
...getConsoleInspectOptions(),
|
...getDefaultInspectOptions(),
|
||||||
indentLevel: this.indentLevel,
|
indentLevel: this.indentLevel,
|
||||||
}) + "\n",
|
}) + "\n",
|
||||||
2,
|
2,
|
||||||
|
@ -3140,7 +3134,7 @@ class Console {
|
||||||
error = (...args) => {
|
error = (...args) => {
|
||||||
this.#printFunc(
|
this.#printFunc(
|
||||||
inspectArgs(args, {
|
inspectArgs(args, {
|
||||||
...getConsoleInspectOptions(),
|
...getDefaultInspectOptions(),
|
||||||
indentLevel: this.indentLevel,
|
indentLevel: this.indentLevel,
|
||||||
}) + "\n",
|
}) + "\n",
|
||||||
3,
|
3,
|
||||||
|
@ -3353,7 +3347,7 @@ class Console {
|
||||||
trace = (...args) => {
|
trace = (...args) => {
|
||||||
const message = inspectArgs(
|
const message = inspectArgs(
|
||||||
args,
|
args,
|
||||||
{ ...getConsoleInspectOptions(), indentLevel: 0 },
|
{ ...getDefaultInspectOptions(), indentLevel: 0 },
|
||||||
);
|
);
|
||||||
const err = {
|
const err = {
|
||||||
name: "Trace",
|
name: "Trace",
|
||||||
|
|
|
@ -316,6 +316,7 @@ pub struct TestCommandBuilder {
|
||||||
args_text: String,
|
args_text: String,
|
||||||
args_vec: Vec<String>,
|
args_vec: Vec<String>,
|
||||||
split_output: bool,
|
split_output: bool,
|
||||||
|
skip_strip_ansi: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestCommandBuilder {
|
impl TestCommandBuilder {
|
||||||
|
@ -327,6 +328,7 @@ impl TestCommandBuilder {
|
||||||
stderr: None,
|
stderr: None,
|
||||||
stdin_text: None,
|
stdin_text: None,
|
||||||
split_output: false,
|
split_output: false,
|
||||||
|
skip_strip_ansi: false,
|
||||||
cwd: None,
|
cwd: None,
|
||||||
envs: Default::default(),
|
envs: Default::default(),
|
||||||
envs_remove: Default::default(),
|
envs_remove: Default::default(),
|
||||||
|
@ -410,6 +412,11 @@ impl TestCommandBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn skip_strip_ansi(mut self) -> Self {
|
||||||
|
self.skip_strip_ansi = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stdin<T: Into<Stdio>>(mut self, cfg: T) -> Self {
|
pub fn stdin<T: Into<Stdio>>(mut self, cfg: T) -> Self {
|
||||||
self.stdin = Some(StdioContainer::new(cfg.into()));
|
self.stdin = Some(StdioContainer::new(cfg.into()));
|
||||||
self
|
self
|
||||||
|
@ -533,8 +540,14 @@ impl TestCommandBuilder {
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sanitize_output(text: String, args: &[OsString]) -> String {
|
fn sanitize_output(
|
||||||
let mut text = strip_ansi_codes(&text).to_string();
|
mut text: String,
|
||||||
|
args: &[OsString],
|
||||||
|
skip_strip_ansi: bool,
|
||||||
|
) -> String {
|
||||||
|
if !skip_strip_ansi {
|
||||||
|
text = strip_ansi_codes(&text).to_string();
|
||||||
|
}
|
||||||
// deno test's output capturing flushes with a zero-width space in order to
|
// deno test's output capturing flushes with a zero-width space in order to
|
||||||
// synchronize the output pipes. Occasionally this zero width space
|
// synchronize the output pipes. Occasionally this zero width space
|
||||||
// might end up in the output so strip it from the output comparison here.
|
// might end up in the output so strip it from the output comparison here.
|
||||||
|
@ -581,14 +594,15 @@ impl TestCommandBuilder {
|
||||||
// and dropping it closes them.
|
// and dropping it closes them.
|
||||||
drop(command);
|
drop(command);
|
||||||
|
|
||||||
let combined = combined_reader
|
let combined = combined_reader.map(|pipe| {
|
||||||
.map(|pipe| sanitize_output(read_pipe_to_string(pipe), &args));
|
sanitize_output(read_pipe_to_string(pipe), &args, self.skip_strip_ansi)
|
||||||
|
});
|
||||||
|
|
||||||
let status = process.wait().unwrap();
|
let status = process.wait().unwrap();
|
||||||
let std_out_err = std_out_err_handle.map(|(stdout, stderr)| {
|
let std_out_err = std_out_err_handle.map(|(stdout, stderr)| {
|
||||||
(
|
(
|
||||||
sanitize_output(stdout.join().unwrap(), &args),
|
sanitize_output(stdout.join().unwrap(), &args, self.skip_strip_ansi),
|
||||||
sanitize_output(stderr.join().unwrap(), &args),
|
sanitize_output(stderr.join().unwrap(), &args, self.skip_strip_ansi),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let exit_code = status.code();
|
let exit_code = status.code();
|
||||||
|
|
|
@ -490,6 +490,7 @@ pub struct CheckOutputIntegrationTest<'a> {
|
||||||
pub http_server: bool,
|
pub http_server: bool,
|
||||||
pub envs: Vec<(String, String)>,
|
pub envs: Vec<(String, String)>,
|
||||||
pub env_clear: bool,
|
pub env_clear: bool,
|
||||||
|
pub skip_strip_ansi: bool,
|
||||||
pub temp_cwd: bool,
|
pub temp_cwd: bool,
|
||||||
/// Copies the files at the specified directory in the "testdata" directory
|
/// Copies the files at the specified directory in the "testdata" directory
|
||||||
/// to the temp folder and runs the test from there. This is useful when
|
/// to the temp folder and runs the test from there. This is useful when
|
||||||
|
@ -531,6 +532,9 @@ impl<'a> CheckOutputIntegrationTest<'a> {
|
||||||
if self.env_clear {
|
if self.env_clear {
|
||||||
command_builder = command_builder.env_clear();
|
command_builder = command_builder.env_clear();
|
||||||
}
|
}
|
||||||
|
if self.skip_strip_ansi {
|
||||||
|
command_builder = command_builder.skip_strip_ansi();
|
||||||
|
}
|
||||||
if let Some(cwd) = &self.cwd {
|
if let Some(cwd) = &self.cwd {
|
||||||
command_builder = command_builder.current_dir(cwd);
|
command_builder = command_builder.current_dir(cwd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5140,3 +5140,17 @@ console.log(add(3, 4));
|
||||||
let output = test_context.new_command().args("run main.ts").run();
|
let output = test_context.new_command().args("run main.ts").run();
|
||||||
output.assert_matches_text("[WILDCARD]5\n7\n");
|
output.assert_matches_text("[WILDCARD]5\n7\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inspect_color_overwrite() {
|
||||||
|
let test_context = TestContextBuilder::new().build();
|
||||||
|
let output = test_context
|
||||||
|
.new_command()
|
||||||
|
.skip_strip_ansi()
|
||||||
|
.split_output()
|
||||||
|
.env("NO_COLOR", "1")
|
||||||
|
.args("run run/inspect_color_overwrite.ts")
|
||||||
|
.run();
|
||||||
|
|
||||||
|
assert_eq!(output.stdout(), "foo\u{1b}[31mbar\u{1b}[0m\n");
|
||||||
|
}
|
||||||
|
|
5
tests/testdata/run/inspect_color_overwrite.ts
vendored
Normal file
5
tests/testdata/run/inspect_color_overwrite.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
console.log(
|
||||||
|
Deno[Deno.internal].inspectArgs(["%cfoo%cbar", "", "color: red"], {
|
||||||
|
colors: true,
|
||||||
|
}),
|
||||||
|
);
|
Loading…
Reference in a new issue