From 298e9c93878e967fd5cbe48d37ee14073dafaf1a Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:44:50 +0200 Subject: [PATCH] task: Allow Rerun action to override properties of task being reran (#10468) For example: ``` "alt-t": [ "task::Rerun", { "reevaluate_context": true, "allow_concurrent_runs": true } ], ``` Overriding `allow_concurrent_runs` to `true` by itself should terminate current instance of the task, if there's any. This PR also fixes task deduplication in terminal panel to use expanded label and not the id, which depends on task context. It kinda aligns with how task rerun worked prior to #10341 . That's omitted in the release notes though, as it's not in Preview yet. Release Notes: - `Task::Rerun` action can now override `allow_concurrent_runs` and `use_new_terminal` properties of the task that is being reran. --- crates/task/src/task_template.rs | 3 ++- crates/tasks_ui/src/lib.rs | 19 +++++++++++++++++-- crates/tasks_ui/src/modal.rs | 10 +++++++++- crates/terminal_view/src/terminal_panel.rs | 6 +++--- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/crates/task/src/task_template.rs b/crates/task/src/task_template.rs index 2f77f7b8f25b355e6450d7bc253412a71b117d7a..3845121c73bad384fd2d4f2323ffe7abe6d6d7c1 100644 --- a/crates/task/src/task_template.rs +++ b/crates/task/src/task_template.rs @@ -102,7 +102,8 @@ impl TaskTemplate { let full_label = substitute_all_template_variables_in_str(&self.label, &task_variables)?; let command = substitute_all_template_variables_in_str(&self.command, &task_variables)?; let args = substitute_all_template_variables_in_vec(self.args.clone(), &task_variables)?; - let task_hash = to_hex_hash(self) + + let task_hash = to_hex_hash(&self) .context("hashing task template") .log_err()?; let variables_hash = to_hex_hash(&task_variables) diff --git a/crates/tasks_ui/src/lib.rs b/crates/tasks_ui/src/lib.rs index b1969c6cb6aa5e1fb1962eb7582e4ad529fac2c9..3d047ed565fbfe219b1ea3f69b5b8b42360c2ae0 100644 --- a/crates/tasks_ui/src/lib.rs +++ b/crates/tasks_ui/src/lib.rs @@ -23,13 +23,19 @@ pub fn init(cx: &mut AppContext) { workspace .register_action(spawn_task_or_modal) .register_action(move |workspace, action: &modal::Rerun, cx| { - if let Some((task_source_kind, last_scheduled_task)) = + if let Some((task_source_kind, mut last_scheduled_task)) = workspace.project().update(cx, |project, cx| { project.task_inventory().read(cx).last_scheduled_task() }) { if action.reevaluate_context { - let original_task = last_scheduled_task.original_task; + let mut original_task = last_scheduled_task.original_task; + if let Some(allow_concurrent_runs) = action.allow_concurrent_runs { + original_task.allow_concurrent_runs = allow_concurrent_runs; + } + if let Some(use_new_terminal) = action.use_new_terminal { + original_task.use_new_terminal = use_new_terminal; + } let cwd = task_cwd(workspace, cx).log_err().flatten(); let task_context = task_context(workspace, cwd, cx); schedule_task( @@ -41,6 +47,15 @@ pub fn init(cx: &mut AppContext) { cx, ) } else { + if let Some(resolved) = last_scheduled_task.resolved.as_mut() { + if let Some(allow_concurrent_runs) = action.allow_concurrent_runs { + resolved.allow_concurrent_runs = allow_concurrent_runs; + } + if let Some(use_new_terminal) = action.use_new_terminal { + resolved.use_new_terminal = use_new_terminal; + } + } + schedule_resolved_task( workspace, task_source_kind, diff --git a/crates/tasks_ui/src/modal.rs b/crates/tasks_ui/src/modal.rs index 324be3fe94b975bf615b05cea165e105f9e8f418..2c316d7320d73a64602ce4f947af5bcbf0ff178a 100644 --- a/crates/tasks_ui/src/modal.rs +++ b/crates/tasks_ui/src/modal.rs @@ -38,12 +38,20 @@ impl Spawn { /// Rerun last task #[derive(PartialEq, Clone, Deserialize, Default)] pub struct Rerun { - #[serde(default)] /// Controls whether the task context is reevaluated prior to execution of a task. /// If it is not, environment variables such as ZED_COLUMN, ZED_FILE are gonna be the same as in the last execution of a task /// If it is, these variables will be updated to reflect current state of editor at the time task::Rerun is executed. /// default: false + #[serde(default)] pub reevaluate_context: bool, + /// Overrides `allow_concurrent_runs` property of the task being reran. + /// Default: null + #[serde(default)] + pub allow_concurrent_runs: Option, + /// Overrides `use_new_terminal` property of the task being reran. + /// Default: null + #[serde(default)] + pub use_new_terminal: Option, } impl_actions!(task, [Rerun, Spawn]); diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index 801d6d1ed0c6856aad8a5a69202b418d0dc02381..3a25d690a5c2e5cf7a5f5cbb3c7f42d96c06434a 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -334,7 +334,7 @@ impl TerminalPanel { return; } - let terminals_for_task = self.terminals_for_task(&spawn_in_terminal.id, cx); + let terminals_for_task = self.terminals_for_task(&spawn_in_terminal.label, cx); if terminals_for_task.is_empty() { self.spawn_in_new_terminal(spawn_task, working_directory, cx); return; @@ -435,7 +435,7 @@ impl TerminalPanel { fn terminals_for_task( &self, - id: &TaskId, + label: &str, cx: &mut AppContext, ) -> Vec<(usize, View)> { self.pane @@ -445,7 +445,7 @@ impl TerminalPanel { .filter_map(|(index, item)| Some((index, item.act_as::(cx)?))) .filter_map(|(index, terminal_view)| { let task_state = terminal_view.read(cx).terminal().read(cx).task()?; - if &task_state.id == id { + if &task_state.label == label { Some((index, terminal_view)) } else { None