1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-03 04:48:52 -05:00

fix(task): strip ansi codes and control chars when printing tasks (#27100)

This commit is contained in:
Bartek Iwańczuk 2024-11-27 15:54:15 +00:00 committed by GitHub
parent e943c6a25d
commit 93adf37bdf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 91 additions and 3 deletions

View file

@ -8,6 +8,7 @@ use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc;
use console_static_text::ansi::strip_ansi_codes;
use deno_config::workspace::FolderConfigs;
use deno_config::workspace::TaskDefinition;
use deno_config::workspace::TaskOrScript;
@ -722,19 +723,47 @@ fn print_available_tasks(
if let Some(description) = &desc.task.description {
let slash_slash = colors::italic_gray("//");
for line in description.lines() {
writeln!(writer, " {slash_slash} {}", colors::italic_gray(line))?;
writeln!(
writer,
" {slash_slash} {}",
colors::italic_gray(strip_ansi_codes_and_escape_control_chars(line))
)?;
}
}
writeln!(writer, " {}", desc.task.command)?;
writeln!(
writer,
" {}",
strip_ansi_codes_and_escape_control_chars(&desc.task.command)
)?;
if !desc.task.dependencies.is_empty() {
let dependencies = desc
.task
.dependencies
.into_iter()
.map(|d| strip_ansi_codes_and_escape_control_chars(&d))
.collect::<Vec<_>>()
.join(", ");
writeln!(
writer,
" {} {}",
colors::gray("depends on:"),
colors::cyan(desc.task.dependencies.join(", "))
colors::cyan(dependencies)
)?;
}
}
Ok(())
}
fn strip_ansi_codes_and_escape_control_chars(s: &str) -> String {
strip_ansi_codes(s)
.chars()
.map(|c| match c {
'\n' => "\\n".to_string(),
'\r' => "\\r".to_string(),
'\t' => "\\t".to_string(),
c if c.is_control() => format!("\\x{:02x}", c as u8),
c => c.to_string(),
})
.collect()
}

View file

@ -3,6 +3,9 @@
// Most of the tests for this are in deno_task_shell.
// These tests are intended to only test integration.
use test_util as util;
use util::TestContextBuilder;
// use test_util::env_vars_for_npm_tests;
// use test_util::itest;
// use test_util::TestContext;
@ -28,3 +31,59 @@
// exit_code: 1,
// http_server: true,
// });
#[test]
fn deno_task_ansi_escape_codes() {
let context = TestContextBuilder::default().use_temp_cwd().build();
let temp_dir = context.temp_dir();
temp_dir.write("deno.json", r#"{
"tasks": {
"dev": "echo 'BOOO!!!'",
"next": "\u001b[3F\u001b[0G- dev\u001b[1E\u001b[2K echo 'I am your friend.'"
}
}
"#);
context
.new_command()
.args_vec(["task"])
.with_pty(|mut console| {
console.expect("Available tasks:");
console.expect("- dev");
console.expect(" echo 'BOOO!!!'");
console.expect("- next");
console.expect(" - dev echo 'I am your friend.'");
});
}
#[test]
fn deno_task_control_chars() {
let context = TestContextBuilder::default().use_temp_cwd().build();
let temp_dir = context.temp_dir();
temp_dir.write(
"deno.json",
r#"{
"tasks": {
"dev": "echo 'BOOO!!!' && \r echo hi there is my command",
"serve": {
"description": "this is a\tm\rangled description",
"command": "echo hello"
}
}
}
"#,
);
context
.new_command()
.args_vec(["task"])
.with_pty(|mut console| {
console.expect("Available tasks:");
console.expect("- dev");
console
.expect(" echo 'BOOO!!!' && \\r echo hi there is my command");
console.expect("- serve");
console.expect(" // this is a\\tm\\rangled description");
console.expect(" echo hello");
});
}