Skip to content

Commit

Permalink
fix(task): don't panic with filter on missing task argument (#27180)
Browse files Browse the repository at this point in the history
We were panicing when running `deno task --filter foo` without a task
argument.

Fixes #27177
  • Loading branch information
marvinhagemeister authored and bartlomieju committed Dec 5, 2024
1 parent e05a305 commit 36d8d73
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 30 deletions.
126 changes: 96 additions & 30 deletions cli/tools/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,41 +78,24 @@ pub async fn execute_script(
let packages_task_configs: Vec<PackageTaskInfo> = if let Some(filter) =
&task_flags.filter
{
let task_name = task_flags.task.as_ref().unwrap();

// Filter based on package name
let package_regex = arg_to_regex(filter)?;
let task_regex = arg_to_regex(task_name)?;

let mut packages_task_info: Vec<PackageTaskInfo> = vec![];
let workspace = cli_options.workspace();

fn matches_package(
config: &FolderConfigs,
force_use_pkg_json: bool,
regex: &Regex,
) -> bool {
if !force_use_pkg_json {
if let Some(deno_json) = &config.deno_json {
if let Some(name) = &deno_json.json.name {
if regex.is_match(name) {
return true;
}
}
}
}
let Some(task_name) = &task_flags.task else {
print_available_tasks_workspace(
cli_options,
&package_regex,
filter,
force_use_pkg_json,
)?;

if let Some(package_json) = &config.pkg_json {
if let Some(name) = &package_json.name {
if regex.is_match(name) {
return true;
}
}
}
return Ok(0);
};

false
}
let task_regex = arg_to_regex(task_name)?;
let mut packages_task_info: Vec<PackageTaskInfo> = vec![];

let workspace = cli_options.workspace();
for folder in workspace.config_folders() {
if !matches_package(folder.1, force_use_pkg_json, &package_regex) {
continue;
Expand Down Expand Up @@ -198,6 +181,7 @@ pub async fn execute_script(
&mut std::io::stdout(),
&cli_options.start_dir,
&tasks_config,
None,
)?;
return Ok(0);
};
Expand Down Expand Up @@ -315,6 +299,7 @@ impl<'a> TaskRunner<'a> {
&mut std::io::stderr(),
&self.cli_options.start_dir,
tasks_config,
None,
)
}

Expand Down Expand Up @@ -675,6 +660,32 @@ fn sort_tasks_topo<'a>(
Ok(sorted)
}

fn matches_package(
config: &FolderConfigs,
force_use_pkg_json: bool,
regex: &Regex,
) -> bool {
if !force_use_pkg_json {
if let Some(deno_json) = &config.deno_json {
if let Some(name) = &deno_json.json.name {
if regex.is_match(name) {
return true;
}
}
}
}

if let Some(package_json) = &config.pkg_json {
if let Some(name) = &package_json.name {
if regex.is_match(name) {
return true;
}
}
}

false
}

fn output_task(task_name: &str, script: &str) {
log::info!(
"{} {} {}",
Expand All @@ -684,12 +695,67 @@ fn output_task(task_name: &str, script: &str) {
);
}

fn print_available_tasks_workspace(
cli_options: &Arc<CliOptions>,
package_regex: &Regex,
filter: &str,
force_use_pkg_json: bool,
) -> Result<(), AnyError> {
let workspace = cli_options.workspace();

let mut matched = false;
for folder in workspace.config_folders() {
if !matches_package(folder.1, force_use_pkg_json, package_regex) {
continue;
}
matched = true;

let member_dir = workspace.resolve_member_dir(folder.0);
let mut tasks_config = member_dir.to_tasks_config()?;

let mut pkg_name = folder
.1
.deno_json
.as_ref()
.and_then(|deno| deno.json.name.clone())
.or(folder.1.pkg_json.as_ref().and_then(|pkg| pkg.name.clone()));

if force_use_pkg_json {
tasks_config = tasks_config.with_only_pkg_json();
pkg_name = folder.1.pkg_json.as_ref().and_then(|pkg| pkg.name.clone());
}

print_available_tasks(
&mut std::io::stdout(),
&cli_options.start_dir,
&tasks_config,
pkg_name,
)?;
}

if !matched {
log::warn!(
"{}",
colors::red(format!("No package name matched the filter '{}' in available 'deno.json' or 'package.json' files.", filter))
);
}

Ok(())
}

fn print_available_tasks(
writer: &mut dyn std::io::Write,
workspace_dir: &Arc<WorkspaceDirectory>,
tasks_config: &WorkspaceTasksConfig,
pkg_name: Option<String>,
) -> Result<(), std::io::Error> {
writeln!(writer, "{}", colors::green("Available tasks:"))?;
let heading = if let Some(s) = pkg_name {
format!("Available tasks ({}):", colors::cyan(s))
} else {
"Available tasks:".to_string()
};

writeln!(writer, "{}", colors::green(heading))?;
let is_cwd_root_dir = tasks_config.root.is_none();

if tasks_config.is_empty() {
Expand Down
20 changes: 20 additions & 0 deletions tests/specs/task/filter/__test__.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
"args": "task --filter @foo/* dev",
"output": "npm_workspace_order.out"
},
"npm_filter_no_match_no_task": {
"cwd": "./npm",
"args": "task --filter @asdf",
"output": "npm_filter_no_match_no_task.out"
},
"npm_filter_no_task": {
"cwd": "./npm",
"args": "task --filter *",
"output": "npm_filter_no_task.out"
},
"deno_all": {
"cwd": "./deno",
"args": "task --filter * dev",
Expand All @@ -54,6 +64,16 @@
"cwd": "./deno_workspace_order",
"args": "task --filter @foo/* dev",
"output": "deno_workspace_order.out"
},
"deno_filter_no_match_no_task": {
"cwd": "./deno",
"args": "task --filter @asdf",
"output": "deno_filter_no_match_no_task.out"
},
"deno_filter_no_task": {
"cwd": "./deno",
"args": "task --filter *",
"output": "deno_filter_no_task.out"
}
}
}
1 change: 1 addition & 0 deletions tests/specs/task/filter/deno_filter_no_match_no_task.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
No package name matched the filter '@asdf' in available 'deno.json' or 'package.json' files.
6 changes: 6 additions & 0 deletions tests/specs/task/filter/deno_filter_no_task.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Available tasks (@deno/bar):
- dev
echo '@deno/bar'
Available tasks (@deno/foo):
- dev
echo '@deno/foo'
1 change: 1 addition & 0 deletions tests/specs/task/filter/npm_filter_no_match_no_task.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
No package name matched the filter '@asdf' in available 'deno.json' or 'package.json' files.
6 changes: 6 additions & 0 deletions tests/specs/task/filter/npm_filter_no_task.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Available tasks (bar):
- dev (package.json)
echo 'bar'
Available tasks (foo):
- dev (package.json)
echo 'foo'

0 comments on commit 36d8d73

Please sign in to comment.