Skip to content

Commit

Permalink
start working on higher level impl
Browse files Browse the repository at this point in the history
  • Loading branch information
cartercanedy committed Jan 19, 2025
1 parent daf1524 commit 5d9e960
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 33 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 51 additions & 2 deletions crates/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ pub use proposed_changes_editor::{
ProposedChangeLocation, ProposedChangesEditor, ProposedChangesEditorToolbar,
};
use similar::{ChangeTag, TextDiff};
use tasks::task_context;
use std::iter::Peekable;
use task::{ResolvedTask, TaskTemplate, TaskVariables};

Expand Down Expand Up @@ -4205,12 +4206,37 @@ impl Editor {
let buffer = actions_menu.buffer;
let workspace = self.workspace()?;

let task_context = task_context(workspace, cx);

match action {
CodeActionsItem::Task(task_source_kind, resolved_task) => {
workspace.update(cx, |workspace, cx| {
workspace::tasks::schedule_resolved_task(
let worktree = match task_source_kind {
TaskSourceKind::Worktree { id, .. } => Some(id),
_ => None
};

let pre_tasks = workspace
.project()
.read(cx)
.task_store()
.read(cx)
.task_inventory()
.map_or(vec![], |inventory| {
inventory
.read(cx)
.build_pre_task_list(
&resolved_task,
worktree,
&task_context
)
.unwrap_or(vec![])
});

workspace::tasks::schedule_resolved_tasks(
workspace,
task_source_kind,
pre_task,
resolved_task,
false,
cx,
Expand Down Expand Up @@ -5087,9 +5113,32 @@ impl Editor {

workspace
.update(&mut cx, |workspace, cx| {
workspace::tasks::schedule_resolved_task(
let worktree = match task_source_kind {
TaskSourceKind::Worktree { id, .. } => Some(id),
_ => None
};

let pre_tasks = workspace
.project()
.read(cx)
.task_store()
.read(cx)
.task_inventory()
.map_or(vec![], |inventory| {
inventory
.read(cx)
.build_pre_task_list(
&resolved_task,
worktree,
task_context
)
.unwrap_or(vec![])
});

workspace::tasks::schedule_resolved_tasks(
workspace,
task_source_kind,
pre_tasks,
resolved_task,
false,
cx,
Expand Down
42 changes: 23 additions & 19 deletions crates/project/src/task_inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,37 +123,42 @@ impl Inventory {
}

/// Topological sort of the dependency graph of `task`
pub fn build_pre_task_list(&self, task: &TaskTemplate) -> anyhow::Result<Vec<(TaskSourceKind, TaskTemplate)>> {
// collect all tasks from all available worktrees
let tasks = self
.templates_from_settings
.worktree
.iter()
.flat_map(|leaf| {
self.worktree_templates_from_settings(Some(*leaf.0))
.chain(self.global_templates_from_settings())
.collect_vec()
pub fn build_pre_task_list(
&self,
base_task: &ResolvedTask,
worktree: Option<WorktreeId>,
task_context: &TaskContext,
) -> anyhow::Result<Vec<(TaskSourceKind, ResolvedTask)>> {
let tasks_in_scope = self
.worktree_templates_from_settings(worktree)
.chain(self.global_templates_from_settings())
.filter_map(|(kind, task)| {
let base_id = kind.to_id_base();
task
.resolve_task(&base_id, task_context)
.map(|task| (kind, task))
})
.unique_by(|(_, task)| task.label.clone())
.unique_by(|(_, task)| task.resolved_label.clone())
.collect_vec();

if let None = tasks
if let None = tasks_in_scope
.iter()
.find(|(_, TaskTemplate { label, .. })| task.label.as_str() == label.as_str())
.find(|(_, task)| task.resolved_label == base_task.resolved_label)
{
return Err(anyhow::anyhow!("couldn't find with label {} in available tasks", &task.label));
return Err(anyhow::anyhow!("couldn't find with label {} in available tasks", base_task.resolved_label));
}

// map task labels to their dep graph node idx, source, and dependencies
let nodes = tasks
let nodes = tasks_in_scope
.iter()
.enumerate()
.map(|(idx, (source, task))| (
task.label.as_str(),
task.display_label(),
(
idx as u32,
source,
task.pre
task
.resolved_pre_labels
.iter()
.map(|s| s.as_str())
.unique()
Expand Down Expand Up @@ -181,9 +186,8 @@ impl Inventory {
}
}


dep_graph
.subgraph(nodes.get(task.label.as_str()).unwrap().0)
.subgraph(nodes.get(base_task.resolved_label.as_str()).unwrap().0)
.topo_sort()
.map(|tasks| {
tasks
Expand Down
1 change: 1 addition & 0 deletions crates/task/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ sha2.workspace = true
shellexpand.workspace = true
util.workspace = true
zed_actions.workspace = true
itertools.workspace = true

[dev-dependencies]
gpui = { workspace = true, features = ["test-support"] }
2 changes: 2 additions & 0 deletions crates/task/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ pub struct ResolvedTask {
/// Further actions that need to take place after the resolved task is spawned,
/// with all task variables resolved.
pub resolved: Option<SpawnInTerminal>,
/// Pretasks with their variables expanded
pub resolved_pre_labels: Vec<String>
}

impl ResolvedTask {
Expand Down
17 changes: 17 additions & 0 deletions crates/task/src/task_template.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::path::PathBuf;
use itertools::Itertools as _;
use util::serde::default_true;

use anyhow::{bail, Context};
Expand Down Expand Up @@ -160,6 +161,7 @@ impl TaskTemplate {
None => None,
}
.or(cx.cwd.clone());

let human_readable_label = substitute_all_template_variables_in_str(
&self.label,
&truncated_variables,
Expand All @@ -176,18 +178,32 @@ impl TaskTemplate {
}
string
});

let full_label = substitute_all_template_variables_in_str(
&self.label,
&task_variables,
&variable_names,
&mut substituted_variables,
)?;

let pre_labels = self
.pre
.iter()
.filter_map(|pre_label| substitute_all_template_variables_in_str(
pre_label,
&truncated_variables,
&variable_names,
&mut substituted_variables
))
.collect_vec();

let command = substitute_all_template_variables_in_str(
&self.command,
&task_variables,
&variable_names,
&mut substituted_variables,
)?;

let args_with_substitutions = substitute_all_template_variables_in_vec(
&self.args,
&task_variables,
Expand Down Expand Up @@ -228,6 +244,7 @@ impl TaskTemplate {
substituted_variables,
original_task: self.clone(),
resolved_label: full_label.clone(),
resolved_pre_labels: pre_labels,
resolved: Some(SpawnInTerminal {
id,
cwd,
Expand Down
4 changes: 2 additions & 2 deletions crates/tasks_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use modal::{TaskOverrides, TasksModal};
use project::{Location, WorktreeId};
use task::{RevealTarget, TaskId};
use workspace::tasks::schedule_task;
use workspace::{tasks::schedule_resolved_task, Workspace};
use workspace::{tasks::schedule_resolved_tasks, Workspace};

mod modal;
mod settings;
Expand Down Expand Up @@ -70,7 +70,7 @@ pub fn init(cx: &mut AppContext) {
}
}

schedule_resolved_task(
schedule_resolved_tasks(
workspace,
task_source_kind,
last_scheduled_task,
Expand Down
46 changes: 40 additions & 6 deletions crates/tasks_ui/src/modal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ use std::sync::Arc;
use crate::active_item_selection_properties;
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
rems, Action, AnyElement, AppContext, DismissEvent, EventEmitter, FocusableView,
InteractiveElement, Model, ParentElement, Render, SharedString, Styled, Subscription, Task,
View, ViewContext, VisualContext, WeakView,
http_client::http::header::InvalidHeaderName, rems, Action, AnyElement, AppContext, DismissEvent, EventEmitter, FocusableView, InteractiveElement, Model, ParentElement, Render, SharedString, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView
};
use picker::{highlighted_match_with_paths::HighlightedText, Picker, PickerDelegate};
use project::{task_store::TaskStore, TaskSourceKind};
Expand All @@ -17,7 +15,7 @@ use ui::{
WindowContext,
};
use util::ResultExt;
use workspace::{tasks::schedule_resolved_task, ModalView, Workspace};
use workspace::{tasks::schedule_resolved_tasks, ModalView, Workspace};
pub use zed_actions::{Rerun, Spawn};

/// A modal used to spawn new tasks.
Expand Down Expand Up @@ -296,7 +294,36 @@ impl PickerDelegate for TasksModalDelegate {

self.workspace
.update(cx, |workspace, cx| {
schedule_resolved_task(workspace, task_source_kind, task, omit_history_entry, cx);
let worktree = match task_source_kind {
TaskSourceKind::Worktree { id, .. } => Some(id),
_ => None
};

let pre_tasks = workspace
.project()
.read(cx)
.task_store()
.read(cx)
.task_inventory()
.map_or(vec![], |inventory| {
inventory
.read(cx)
.build_pre_task_list(
&task,
worktree,
&self.task_context
)
.unwrap_or(vec![])
});

schedule_resolved_tasks(
workspace,
task_source_kind,
pre_tasks,
task,
omit_history_entry,
cx
);
})
.ok();
cx.emit(DismissEvent);
Expand Down Expand Up @@ -443,7 +470,14 @@ impl PickerDelegate for TasksModalDelegate {
}
self.workspace
.update(cx, |workspace, cx| {
schedule_resolved_task(workspace, task_source_kind, task, omit_history_entry, cx);
schedule_resolved_tasks(
workspace,
task_source_kind,
vec![],
task,
omit_history_entry,
cx
);
})
.ok();
cx.emit(DismissEvent);
Expand Down
15 changes: 12 additions & 3 deletions crates/workspace/src/tasks.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use itertools::Itertools as _;
use project::TaskSourceKind;
use remote::ConnectionState;
use task::{ResolvedTask, TaskContext, TaskTemplate};
Expand Down Expand Up @@ -29,7 +30,7 @@ pub fn schedule_task(
if let Some(spawn_in_terminal) =
task_to_resolve.resolve_task(&task_source_kind.to_id_base(), task_cx)
{
schedule_resolved_task(
schedule_resolved_tasks(
workspace,
task_source_kind,
spawn_in_terminal,
Expand All @@ -39,9 +40,10 @@ pub fn schedule_task(
}
}

pub fn schedule_resolved_task(
pub fn schedule_resolved_tasks(
workspace: &mut Workspace,
task_source_kind: TaskSourceKind,
pre_tasks: Vec<ResolvedTask>,
mut resolved_task: ResolvedTask,
omit_history: bool,
cx: &mut ViewContext<Workspace>,
Expand All @@ -60,8 +62,15 @@ pub fn schedule_resolved_task(
});
}

let mut all_tasks = pre_tasks
.into_iter()
.filter_map(|mut task| task.resolved.take())
.collect_vec();

all_tasks.push(spawn_in_terminal);

cx.emit(crate::Event::SpawnTask {
action: Box::new(spawn_in_terminal),
action: all_tasks,
});
}
}
2 changes: 1 addition & 1 deletion crates/workspace/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ pub enum Event {
ContactRequestedJoin(u64),
WorkspaceCreated(WeakView<Workspace>),
SpawnTask {
action: Box<SpawnInTerminal>,
action: Vec<SpawnInTerminal>,
},
OpenBundledFile {
text: Cow<'static, str>,
Expand Down

0 comments on commit 5d9e960

Please sign in to comment.