From 14e406498672e7b8fbbfbcb7a057f798358909b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 18 Dec 2024 02:32:37 +0000 Subject: [PATCH] fix(task): properly handle task name wildcards with --recursive (#27396) This commit fixes `deno task` by checking if the provided task name actually has a wildcard char ("*"). Previously, if the "--recursive" flag was passed, the task name was treated as a regex, which lead to a situation where exact task name resulted in a regex that matched all tasks with the specific prefix. This commit fixes it, by checking if the provided task name, is an exact name, or is it a wildcard match. Closes https://github.com/denoland/deno/issues/27370 Closes https://github.com/denoland/deno/issues/27401 Closes https://github.com/denoland/deno/issues/27408 --- cli/tools/task.rs | 50 ++++++++++++++++++- .../task/workspace_regex_match/__test__.jsonc | 11 ++++ .../task/workspace_regex_match/deno.json | 6 +++ .../specs/task/workspace_regex_match/root.out | 3 ++ .../workspace_regex_match/subdir/deno.json | 5 ++ 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 tests/specs/task/workspace_regex_match/__test__.jsonc create mode 100644 tests/specs/task/workspace_regex_match/deno.json create mode 100644 tests/specs/task/workspace_regex_match/root.out create mode 100644 tests/specs/task/workspace_regex_match/subdir/deno.json diff --git a/cli/tools/task.rs b/cli/tools/task.rs index 25d1d66710..ec9b238847 100644 --- a/cli/tools/task.rs +++ b/cli/tools/task.rs @@ -94,7 +94,7 @@ pub async fn execute_script( return Ok(0); }; - let task_regex = arg_to_regex(task_name)?; + let task_name_filter = arg_to_task_name_filter(task_name)?; let mut packages_task_info: Vec = vec![]; for folder in workspace.config_folders() { @@ -137,12 +137,20 @@ pub async fn execute_script( // Match tasks in deno.json for name in tasks_config.task_names() { - if task_regex.is_match(name) && !visited.contains(name) { + let matches_filter = match &task_name_filter { + TaskNameFilter::Exact(n) => *n == name, + TaskNameFilter::Regex(re) => re.is_match(name), + }; + if matches_filter && !visited.contains(name) { matched.insert(name.to_string()); visit_task(&tasks_config, &mut visited, name); } } + if matched.is_empty() { + continue; + } + packages_task_info.push(PackageTaskInfo { matched_tasks: matched .iter() @@ -902,3 +910,41 @@ fn strip_ansi_codes_and_escape_control_chars(s: &str) -> String { }) .collect() } + +fn arg_to_task_name_filter(input: &str) -> Result { + if !input.contains("*") { + return Ok(TaskNameFilter::Exact(input)); + } + + let mut regex_str = regex::escape(input); + regex_str = regex_str.replace("\\*", ".*"); + let re = Regex::new(®ex_str)?; + Ok(TaskNameFilter::Regex(re)) +} + +#[derive(Debug)] +enum TaskNameFilter<'s> { + Exact(&'s str), + Regex(regex::Regex), +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_arg_to_task_name_filter() { + assert!(matches!( + arg_to_task_name_filter("test").unwrap(), + TaskNameFilter::Exact("test") + )); + assert!(matches!( + arg_to_task_name_filter("test-").unwrap(), + TaskNameFilter::Exact("test-") + )); + assert!(matches!( + arg_to_task_name_filter("test*").unwrap(), + TaskNameFilter::Regex(_) + )); + } +} diff --git a/tests/specs/task/workspace_regex_match/__test__.jsonc b/tests/specs/task/workspace_regex_match/__test__.jsonc new file mode 100644 index 0000000000..258c288d44 --- /dev/null +++ b/tests/specs/task/workspace_regex_match/__test__.jsonc @@ -0,0 +1,11 @@ +{ + "tempDir": true, + "tests": { + // Regression test for https://github.com/denoland/deno/issues/27370 + "root": { + "args": "task test-all", + "output": "root.out", + "exitCode": 0 + } + } +} diff --git a/tests/specs/task/workspace_regex_match/deno.json b/tests/specs/task/workspace_regex_match/deno.json new file mode 100644 index 0000000000..ce040ba5ab --- /dev/null +++ b/tests/specs/task/workspace_regex_match/deno.json @@ -0,0 +1,6 @@ +{ + "workspace": ["./subdir"], + "tasks": { + "test-all": "deno task --recursive test" + } +} diff --git a/tests/specs/task/workspace_regex_match/root.out b/tests/specs/task/workspace_regex_match/root.out new file mode 100644 index 0000000000..9da724a5c0 --- /dev/null +++ b/tests/specs/task/workspace_regex_match/root.out @@ -0,0 +1,3 @@ +Task test-all deno task --recursive test +Task test echo 'ok' +ok diff --git a/tests/specs/task/workspace_regex_match/subdir/deno.json b/tests/specs/task/workspace_regex_match/subdir/deno.json new file mode 100644 index 0000000000..78d768e396 --- /dev/null +++ b/tests/specs/task/workspace_regex_match/subdir/deno.json @@ -0,0 +1,5 @@ +{ + "tasks": { + "test": "echo 'ok'" + } +}