fix(task): show package name of task when --recursive (#30136)

This commit is contained in:
David Sherret 2025-07-17 17:42:50 -04:00 committed by GitHub
parent b7680dde5e
commit 61a7913a8b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 124 additions and 92 deletions

View file

@ -206,6 +206,7 @@ pub async fn execute_script(
return task_runner
.run_deno_task(
&Url::from_directory_path(cli_options.initial_cwd()).unwrap(),
None,
"",
&TaskDefinition {
command: Some(task_flags.task.as_ref().unwrap().to_string()),
@ -234,6 +235,7 @@ pub async fn execute_script(
struct RunSingleOptions<'a> {
task_name: &'a str,
package_name: Option<&'a str>,
script: &'a str,
cwd: PathBuf,
custom_commands: HashMap<String, Rc<dyn ShellCommand>>,
@ -354,10 +356,11 @@ impl<'a> TaskRunner<'a> {
return Some(
async move {
match task.task_or_script {
TaskOrScript::Task(_, def) => {
TaskOrScript::Task { task: def, .. } => {
runner
.run_deno_task(
task.folder_url,
task.task_or_script.folder_url(),
task.task_or_script.package_name(),
task.name,
def,
kill_signal,
@ -365,12 +368,13 @@ impl<'a> TaskRunner<'a> {
)
.await
}
TaskOrScript::Script(scripts, _) => {
TaskOrScript::Script { details, .. } => {
runner
.run_npm_script(
task.folder_url,
task.task_or_script.folder_url(),
task.task_or_script.package_name(),
task.name,
scripts,
&details.tasks,
kill_signal,
args,
)
@ -426,17 +430,17 @@ impl<'a> TaskRunner<'a> {
pub async fn run_deno_task(
&self,
dir_url: &Url,
package_name: Option<&str>,
task_name: &str,
definition: &TaskDefinition,
kill_signal: KillSignal,
argv: &'a [String],
) -> Result<i32, deno_core::anyhow::Error> {
let Some(command) = &definition.command else {
log::info!(
"{} {} {}",
colors::green("Task"),
colors::cyan(task_name),
colors::gray("(no command)")
self.output_task(
task_name,
package_name,
&colors::gray("(no command)").to_string(),
);
return Ok(0);
};
@ -457,6 +461,7 @@ impl<'a> TaskRunner<'a> {
self
.run_single(RunSingleOptions {
task_name,
package_name,
script: command,
cwd,
custom_commands,
@ -469,6 +474,7 @@ impl<'a> TaskRunner<'a> {
pub async fn run_npm_script(
&self,
dir_url: &Url,
package_name: Option<&str>,
task_name: &str,
scripts: &IndexMap<String, String>,
kill_signal: KillSignal,
@ -500,6 +506,7 @@ impl<'a> TaskRunner<'a> {
let exit_code = self
.run_single(RunSingleOptions {
task_name,
package_name,
script,
cwd: cwd.clone(),
custom_commands: custom_commands.clone(),
@ -522,6 +529,7 @@ impl<'a> TaskRunner<'a> {
) -> Result<i32, AnyError> {
let RunSingleOptions {
task_name,
package_name,
script,
cwd,
custom_commands,
@ -529,8 +537,9 @@ impl<'a> TaskRunner<'a> {
argv,
} = opts;
output_task(
opts.task_name,
self.output_task(
task_name,
package_name,
&task_runner::get_script_with_args(script, argv),
);
@ -564,6 +573,26 @@ impl<'a> TaskRunner<'a> {
}
Ok(())
}
fn output_task(
&self,
task_name: &str,
package_name: Option<&str>,
script: &str,
) {
log::info!(
"{} {}{} {}",
colors::green("Task"),
colors::cyan(task_name),
package_name
.filter(
|_| self.task_flags.recursive || self.task_flags.filter.is_some()
)
.map(|p| format!(" ({})", colors::gray(p)))
.unwrap_or_default(),
script,
);
}
}
#[derive(Debug)]
@ -575,7 +604,6 @@ enum TaskError {
struct ResolvedTask<'a> {
id: usize,
name: &'a str,
folder_url: &'a Url,
task_or_script: TaskOrScript<'a>,
dependencies: Vec<usize>,
}
@ -585,26 +613,20 @@ fn sort_tasks_topo<'a>(
task_name: &str,
) -> Result<Vec<ResolvedTask<'a>>, TaskError> {
trait TasksConfig {
fn task(
&self,
name: &str,
) -> Option<(&Url, TaskOrScript, &dyn TasksConfig)>;
fn task(&self, name: &str) -> Option<(TaskOrScript, &dyn TasksConfig)>;
}
impl TasksConfig for WorkspaceTasksConfig {
fn task(
&self,
name: &str,
) -> Option<(&Url, TaskOrScript, &dyn TasksConfig)> {
fn task(&self, name: &str) -> Option<(TaskOrScript, &dyn TasksConfig)> {
if let Some(member) = &self.member {
if let Some((dir_url, task_or_script)) = member.task(name) {
return Some((dir_url, task_or_script, self as &dyn TasksConfig));
if let Some(task_or_script) = member.task(name) {
return Some((task_or_script, self as &dyn TasksConfig));
}
}
if let Some(root) = &self.root {
if let Some((dir_url, task_or_script)) = root.task(name) {
if let Some(task_or_script) = root.task(name) {
// switch to only using the root tasks for the dependencies
return Some((dir_url, task_or_script, root as &dyn TasksConfig));
return Some((task_or_script, root as &dyn TasksConfig));
}
}
None
@ -612,13 +634,10 @@ fn sort_tasks_topo<'a>(
}
impl TasksConfig for WorkspaceMemberTasksConfig {
fn task(
&self,
name: &str,
) -> Option<(&Url, TaskOrScript, &dyn TasksConfig)> {
self.task(name).map(|(dir_url, task_or_script)| {
(dir_url, task_or_script, self as &dyn TasksConfig)
})
fn task(&self, name: &str) -> Option<(TaskOrScript, &dyn TasksConfig)> {
self
.task(name)
.map(|task_or_script| (task_or_script, self as &dyn TasksConfig))
}
}
@ -628,16 +647,14 @@ fn sort_tasks_topo<'a>(
mut path: Vec<(&'a Url, &'a str)>,
tasks_config: &'a dyn TasksConfig,
) -> Result<usize, TaskError> {
let Some((folder_url, task_or_script, tasks_config)) =
tasks_config.task(name)
else {
let Some((task_or_script, tasks_config)) = tasks_config.task(name) else {
return Err(TaskError::NotFound(name.to_string()));
};
if let Some(existing_task) = sorted
.iter()
.find(|task| task.name == name && task.folder_url == folder_url)
{
let folder_url = task_or_script.folder_url();
if let Some(existing_task) = sorted.iter().find(|task| {
task.name == name && task.task_or_script.folder_url() == folder_url
}) {
// already exists
return Ok(existing_task.id);
}
@ -650,7 +667,7 @@ fn sort_tasks_topo<'a>(
}
let mut dependencies: Vec<usize> = Vec::new();
if let TaskOrScript::Task(_, task) = task_or_script {
if let TaskOrScript::Task { task, .. } = task_or_script {
dependencies.reserve(task.dependencies.len());
for dep in &task.dependencies {
let mut path = path.clone();
@ -663,7 +680,6 @@ fn sort_tasks_topo<'a>(
sorted.push(ResolvedTask {
id,
name,
folder_url,
task_or_script,
dependencies,
});
@ -710,15 +726,6 @@ fn matches_package(
false
}
fn output_task(task_name: &str, script: &str) {
log::info!(
"{} {} {}",
colors::green("Task"),
colors::cyan(task_name),
script,
);
}
fn print_available_tasks_workspace(
cli_options: &Arc<CliOptions>,
package_regex: &Regex,
@ -729,8 +736,7 @@ fn print_available_tasks_workspace(
let workspace = cli_options.workspace();
let mut matched = false;
for (folder_url, folder) in workspace.config_folders_sorted_by_dependencies()
{
for (folder_url, folder) in workspace.config_folders() {
if !recursive && !matches_package(folder, force_use_pkg_json, package_regex)
{
continue;
@ -927,7 +933,7 @@ fn visit_task_and_dependencies(
visited.insert(name.to_string());
if let Some((_, TaskOrScript::Task(_, task))) = &tasks_config.task(name) {
if let Some(TaskOrScript::Task { task, .. }) = &tasks_config.task(name) {
for dep in &task.dependencies {
visit_task_and_dependencies(tasks_config, visited, dep);
}

View file

@ -1941,6 +1941,7 @@ impl WorkspaceDirectory {
tasks.map(|tasks| WorkspaceMemberTasksConfigFile {
folder_url: url_parent(&deno_json.specifier),
tasks,
package_name: deno_json.json.name.clone(),
})
})
.map_err(|error| ToTasksConfigError {
@ -1954,6 +1955,7 @@ impl WorkspaceDirectory {
WorkspaceMemberTasksConfigFile {
folder_url: url_parent(&pkg_json.specifier()),
tasks: scripts,
package_name: pkg_json.name.clone(),
}
}),
None => None,
@ -2110,13 +2112,36 @@ impl WorkspaceDirectory {
pub enum TaskOrScript<'a> {
/// A task from a deno.json.
Task(&'a IndexMap<String, TaskDefinition>, &'a TaskDefinition),
Task {
details: &'a WorkspaceMemberTasksConfigFile<TaskDefinition>,
task: &'a TaskDefinition,
},
/// A script from a package.json.
Script(&'a IndexMap<String, String>, &'a str),
Script {
details: &'a WorkspaceMemberTasksConfigFile<String>,
task: &'a str,
},
}
impl<'a> TaskOrScript<'a> {
pub fn package_name(&self) -> Option<&'a str> {
match self {
TaskOrScript::Task { details, .. } => details.package_name.as_deref(),
TaskOrScript::Script { details, .. } => details.package_name.as_deref(),
}
}
pub fn folder_url(&self) -> &'a Url {
match self {
TaskOrScript::Task { details, .. } => &details.folder_url,
TaskOrScript::Script { details, .. } => &details.folder_url,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WorkspaceMemberTasksConfigFile<TValue> {
pub package_name: Option<String>,
pub folder_url: Url,
pub tasks: IndexMap<String, TValue>,
}
@ -2180,23 +2205,21 @@ impl WorkspaceMemberTasksConfig {
.unwrap_or(0)
}
pub fn task(&self, name: &str) -> Option<(&Url, TaskOrScript)> {
pub fn task(&self, name: &str) -> Option<TaskOrScript> {
self
.deno_json
.as_ref()
.and_then(|config| {
config
.tasks
.get(name)
.map(|t| (&config.folder_url, TaskOrScript::Task(&config.tasks, t)))
config.tasks.get(name).map(|task| TaskOrScript::Task {
details: config,
task,
})
})
.or_else(|| {
self.package_json.as_ref().and_then(|config| {
config.tasks.get(name).map(|task| {
(
&config.folder_url,
TaskOrScript::Script(&config.tasks, task),
)
config.tasks.get(name).map(|script| TaskOrScript::Script {
details: config,
task: script,
})
})
})
@ -2239,7 +2262,7 @@ impl WorkspaceTasksConfig {
)
}
pub fn task(&self, name: &str) -> Option<(&Url, TaskOrScript)> {
pub fn task(&self, name: &str) -> Option<TaskOrScript> {
self
.member
.as_ref()
@ -2699,6 +2722,7 @@ pub mod test {
assert_eq!(workspace_dir.workspace.diagnostics(), vec![]);
let root_deno_json = Some(WorkspaceMemberTasksConfigFile {
folder_url: url_from_directory_path(&root_dir()).unwrap(),
package_name: None,
tasks: IndexMap::from([
("hi".to_string(), "echo hi".into()),
("overwrite".to_string(), "echo overwrite".into()),
@ -2738,6 +2762,7 @@ pub mod test {
deno_json: Some(WorkspaceMemberTasksConfigFile {
folder_url: url_from_directory_path(&root_dir().join("member"))
.unwrap(),
package_name: None,
tasks: IndexMap::from([
("overwrite".to_string(), "echo overwritten".into()),
("bye".to_string(), "echo bye".into()),
@ -2768,6 +2793,7 @@ pub mod test {
package_json: Some(WorkspaceMemberTasksConfigFile {
folder_url: url_from_directory_path(&root_dir().join("pkg_json"))
.unwrap(),
package_name: None,
tasks: IndexMap::from([(
"script".to_string(),
"echo 1".to_string()

View file

@ -1,4 +1,4 @@
Task dev echo '@deno/bar'
Task dev (@deno/bar) echo '@deno/bar'
@deno/bar
Task dev echo '@deno/foo'
Task dev (@deno/foo) echo '@deno/foo'
@deno/foo

View file

@ -1,2 +1,2 @@
Task dev echo '@deno/foo'
Task dev (@deno/foo) echo '@deno/foo'
@deno/foo

View file

@ -1,2 +1,2 @@
Task dev echo '@deno/foo'
Task dev (@deno/foo) echo '@deno/foo'
@deno/foo

View file

@ -1,4 +1,4 @@
Task dev echo '@deno/bar'
Task dev (@deno/bar) echo '@deno/bar'
@deno/bar
Task dev echo '@deno/foo'
Task dev (@deno/foo) echo '@deno/foo'
@deno/foo

View file

@ -1,2 +1,2 @@
Task dev echo '@foo/bar'
Task dev (@foo/bar) echo '@foo/bar'
@foo/bar

View file

@ -1,4 +1,4 @@
Task dev echo '@foo/bar'
Task dev (@foo/bar) echo '@foo/bar'
@foo/bar
Task dev echo '@foo/baz'
Task dev (@foo/baz) echo '@foo/baz'
@foo/baz

View file

@ -1,4 +1,4 @@
Task dev echo '@foo/bar'
Task dev (@foo/bar) echo '@foo/bar'
@foo/bar
Task dev echo '@foo/baz'
Task dev (@foo/baz) echo '@foo/baz'
@foo/baz

View file

@ -1,4 +1,4 @@
Task dev echo 'bar'
Task dev (bar) echo 'bar'
bar
Task dev echo 'foo'
Task dev (foo) echo 'foo'
foo

View file

@ -1,2 +1,2 @@
Task dev echo 'foo'
Task dev (foo) echo 'foo'
foo

View file

@ -1,2 +1,2 @@
Task dev echo 'foo'
Task dev (foo) echo 'foo'
foo

View file

@ -1,4 +1,4 @@
Task dev echo 'multi-a'
Task dev (multi-a) echo 'multi-a'
multi-a
Task dev echo 'multi-b'
Task dev (multi-b) echo 'multi-b'
multi-b

View file

@ -1,4 +1,4 @@
Task dev echo 'bar'
Task dev (bar) echo 'bar'
bar
Task dev echo 'foo'
Task dev (foo) echo 'foo'
foo

View file

@ -1,2 +1,2 @@
Task dev echo '@foo/bar'
Task dev (@foo/bar) echo '@foo/bar'
@foo/bar

View file

@ -1,4 +1,4 @@
Task dev echo '@foo/bar'
Task dev (@foo/bar) echo '@foo/bar'
@foo/bar
Task dev echo '@foo/baz'
Task dev (@foo/baz) echo '@foo/baz'
@foo/baz

View file

@ -1,4 +1,4 @@
Task dev echo '@foo/bar'
Task dev (@foo/bar) echo '@foo/bar'
@foo/bar
Task dev echo '@foo/baz'
Task dev (@foo/baz) echo '@foo/baz'
@foo/baz

View file

@ -1,4 +1,4 @@
Task build echo b
Task build (b) echo b
b
Task build echo a
Task build (a) echo a
a