Prefer project (worktree) tasks to language/global tasks in task::Spawn (#21706)
`Inventory::list_tasks()` in `project` crate now is ordered by task types. Worktree tasks comes first, language tasks second and global tasks last. That leads to `spawn_task_with_name()` from `task_ui` crate will find worktree task first, so it's possible to override global tasks at project level. * `Inventory::templates_from_settings()` splitted to `Inventory::global_templates_from_settings()` and `Inventory::worktree_templates_from_settings()`. * In tests function `list_tasks()` renamed to `list_tasks_sorted_by_last_used()`, because it call's `Inventory::used_and_current_resolved_tasks()`. Also added `list_tasks()` which calls `Inventory::list_tasks()`. Closes #20987 Release Notes: - Fix task::Spawn to search for task name in project tasks first.
This commit is contained in:
parent
ff2d20780f
commit
cbc226597c
1 changed files with 86 additions and 33 deletions
|
@ -81,7 +81,8 @@ impl Inventory {
|
|||
}
|
||||
|
||||
/// Pulls its task sources relevant to the worktree and the language given,
|
||||
/// returns all task templates with their source kinds, in no specific order.
|
||||
/// returns all task templates with their source kinds, worktree tasks first, language tasks second
|
||||
/// and global tasks last. No specific order inside source kinds groups.
|
||||
pub fn list_tasks(
|
||||
&self,
|
||||
file: Option<Arc<dyn File>>,
|
||||
|
@ -92,13 +93,15 @@ impl Inventory {
|
|||
let task_source_kind = language.as_ref().map(|language| TaskSourceKind::Language {
|
||||
name: language.name().0,
|
||||
});
|
||||
let global_tasks = self.global_templates_from_settings();
|
||||
let language_tasks = language
|
||||
.and_then(|language| language.context_provider()?.associated_tasks(file, cx))
|
||||
.into_iter()
|
||||
.flat_map(|tasks| tasks.0.into_iter())
|
||||
.flat_map(|task| Some((task_source_kind.clone()?, task)));
|
||||
.flat_map(|task| Some((task_source_kind.clone()?, task)))
|
||||
.chain(global_tasks);
|
||||
|
||||
self.templates_from_settings(worktree)
|
||||
self.worktree_templates_from_settings(worktree)
|
||||
.chain(language_tasks)
|
||||
.collect()
|
||||
}
|
||||
|
@ -165,14 +168,18 @@ impl Inventory {
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
let not_used_score = post_inc(&mut lru_score);
|
||||
let global_tasks = self.global_templates_from_settings();
|
||||
let language_tasks = language
|
||||
.and_then(|language| language.context_provider()?.associated_tasks(file, cx))
|
||||
.into_iter()
|
||||
.flat_map(|tasks| tasks.0.into_iter())
|
||||
.flat_map(|task| Some((task_source_kind.clone()?, task)));
|
||||
let new_resolved_tasks = self
|
||||
.templates_from_settings(worktree)
|
||||
.chain(language_tasks)
|
||||
.flat_map(|task| Some((task_source_kind.clone()?, task)))
|
||||
.chain(global_tasks);
|
||||
let worktree_tasks = self
|
||||
.worktree_templates_from_settings(worktree)
|
||||
.chain(language_tasks);
|
||||
|
||||
let new_resolved_tasks = worktree_tasks
|
||||
.filter_map(|(kind, task)| {
|
||||
let id_base = kind.to_id_base();
|
||||
Some((
|
||||
|
@ -235,9 +242,8 @@ impl Inventory {
|
|||
self.last_scheduled_tasks.retain(|(_, task)| &task.id != id);
|
||||
}
|
||||
|
||||
fn templates_from_settings(
|
||||
fn global_templates_from_settings(
|
||||
&self,
|
||||
worktree: Option<WorktreeId>,
|
||||
) -> impl '_ + Iterator<Item = (TaskSourceKind, TaskTemplate)> {
|
||||
self.templates_from_settings
|
||||
.global
|
||||
|
@ -252,7 +258,13 @@ impl Inventory {
|
|||
template,
|
||||
)
|
||||
})
|
||||
.chain(worktree.into_iter().flat_map(|worktree| {
|
||||
}
|
||||
|
||||
fn worktree_templates_from_settings(
|
||||
&self,
|
||||
worktree: Option<WorktreeId>,
|
||||
) -> impl '_ + Iterator<Item = (TaskSourceKind, TaskTemplate)> {
|
||||
worktree.into_iter().flat_map(|worktree| {
|
||||
self.templates_from_settings
|
||||
.worktree
|
||||
.get(&worktree)
|
||||
|
@ -273,7 +285,7 @@ impl Inventory {
|
|||
template.clone(),
|
||||
)
|
||||
})
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
/// Updates in-memory task metadata from the JSON string given.
|
||||
|
@ -407,6 +419,25 @@ mod test_inventory {
|
|||
inventory: &Model<Inventory>,
|
||||
worktree: Option<WorktreeId>,
|
||||
cx: &mut TestAppContext,
|
||||
) -> Vec<(TaskSourceKind, String)> {
|
||||
inventory.update(cx, |inventory, cx| {
|
||||
let task_context = &TaskContext::default();
|
||||
inventory
|
||||
.list_tasks(None, None, worktree, cx)
|
||||
.into_iter()
|
||||
.filter_map(|(source_kind, task)| {
|
||||
let id_base = source_kind.to_id_base();
|
||||
Some((source_kind, task.resolve_task(&id_base, task_context)?))
|
||||
})
|
||||
.map(|(source_kind, resolved_task)| (source_kind, resolved_task.resolved_label))
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) async fn list_tasks_sorted_by_last_used(
|
||||
inventory: &Model<Inventory>,
|
||||
worktree: Option<WorktreeId>,
|
||||
cx: &mut TestAppContext,
|
||||
) -> Vec<(TaskSourceKind, String)> {
|
||||
let (used, current) = inventory.update(cx, |inventory, cx| {
|
||||
inventory.used_and_current_resolved_tasks(worktree, None, &TaskContext::default(), cx)
|
||||
|
@ -789,6 +820,30 @@ mod tests {
|
|||
.unwrap();
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
list_tasks_sorted_by_last_used(&inventory, None, cx).await,
|
||||
worktree_independent_tasks,
|
||||
"Without a worktree, only worktree-independent tasks should be listed"
|
||||
);
|
||||
assert_eq!(
|
||||
list_tasks_sorted_by_last_used(&inventory, Some(worktree_1), cx).await,
|
||||
worktree_1_tasks
|
||||
.iter()
|
||||
.chain(worktree_independent_tasks.iter())
|
||||
.cloned()
|
||||
.sorted_by_key(|(kind, label)| (task_source_kind_preference(kind), label.clone()))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
assert_eq!(
|
||||
list_tasks_sorted_by_last_used(&inventory, Some(worktree_2), cx).await,
|
||||
worktree_2_tasks
|
||||
.iter()
|
||||
.chain(worktree_independent_tasks.iter())
|
||||
.cloned()
|
||||
.sorted_by_key(|(kind, label)| (task_source_kind_preference(kind), label.clone()))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
list_tasks(&inventory, None, cx).await,
|
||||
worktree_independent_tasks,
|
||||
|
@ -800,7 +855,6 @@ mod tests {
|
|||
.iter()
|
||||
.chain(worktree_independent_tasks.iter())
|
||||
.cloned()
|
||||
.sorted_by_key(|(kind, label)| (task_source_kind_preference(kind), label.clone()))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -809,7 +863,6 @@ mod tests {
|
|||
.iter()
|
||||
.chain(worktree_independent_tasks.iter())
|
||||
.cloned()
|
||||
.sorted_by_key(|(kind, label)| (task_source_kind_preference(kind), label.clone()))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue