Cleanup corresponding task history on task file update (#31720)

Closes https://github.com/zed-industries/zed/issues/31715

Release Notes:

- Fixed old task history not erased after task file update
This commit is contained in:
Kirill Bulatov 2025-05-30 02:02:59 +03:00 committed by GitHub
parent cbed580db0
commit 406d975f39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -586,6 +586,13 @@ impl Inventory {
.global
.entry(path.to_owned())
.insert_entry(new_templates.collect());
self.last_scheduled_tasks.retain(|(kind, _)| {
if let TaskSourceKind::AbsPath { abs_path, .. } = kind {
abs_path != path
} else {
true
}
});
}
TaskSettingsLocation::Worktree(location) => {
let new_templates = new_templates.collect::<Vec<_>>();
@ -602,6 +609,18 @@ impl Inventory {
.or_default()
.insert(Arc::from(location.path), new_templates);
}
self.last_scheduled_tasks.retain(|(kind, _)| {
if let TaskSourceKind::Worktree {
directory_in_worktree,
id,
..
} = kind
{
*id != location.worktree_id || directory_in_worktree != location.path
} else {
true
}
});
}
}
@ -756,6 +775,27 @@ mod test_inventory {
});
}
pub(super) fn register_worktree_task_used(
inventory: &Entity<Inventory>,
worktree_id: WorktreeId,
task_name: &str,
cx: &mut TestAppContext,
) {
inventory.update(cx, |inventory, cx| {
let (task_source_kind, task) = inventory
.list_tasks(None, None, Some(worktree_id), cx)
.into_iter()
.find(|(_, task)| task.label == task_name)
.unwrap_or_else(|| panic!("Failed to find task with name {task_name}"));
let id_base = task_source_kind.to_id_base();
inventory.task_scheduled(
task_source_kind.clone(),
task.resolve_task(&id_base, &TaskContext::default())
.unwrap_or_else(|| panic!("Failed to resolve task with name {task_name}")),
);
});
}
pub(super) async fn list_tasks(
inventory: &Entity<Inventory>,
worktree: Option<WorktreeId>,
@ -997,6 +1037,53 @@ mod tests {
"2_task".to_string(),
"1_a_task".to_string(),
],
"Most recently used task should be at the top"
);
let worktree_id = WorktreeId::from_usize(0);
let local_worktree_location = SettingsLocation {
worktree_id,
path: Path::new("foo"),
};
inventory.update(cx, |inventory, _| {
inventory
.update_file_based_tasks(
TaskSettingsLocation::Worktree(local_worktree_location),
Some(&mock_tasks_from_names(["worktree_task_1"])),
)
.unwrap();
});
assert_eq!(
resolved_task_names(&inventory, None, cx),
vec![
"3_task".to_string(),
"1_task".to_string(),
"2_task".to_string(),
"1_a_task".to_string(),
],
"Most recently used task should be at the top"
);
assert_eq!(
resolved_task_names(&inventory, Some(worktree_id), cx),
vec![
"3_task".to_string(),
"1_task".to_string(),
"2_task".to_string(),
"worktree_task_1".to_string(),
"1_a_task".to_string(),
],
);
register_worktree_task_used(&inventory, worktree_id, "worktree_task_1", cx);
assert_eq!(
resolved_task_names(&inventory, Some(worktree_id), cx),
vec![
"worktree_task_1".to_string(),
"3_task".to_string(),
"1_task".to_string(),
"2_task".to_string(),
"1_a_task".to_string(),
],
"Most recently used worktree task should be at the top"
);
inventory.update(cx, |inventory, _| {
@ -1027,13 +1114,15 @@ mod tests {
assert_eq!(
resolved_task_names(&inventory, None, cx),
vec![
"3_task".to_string(),
"worktree_task_1".to_string(),
"1_a_task".to_string(),
"1_task".to_string(),
"2_task".to_string(),
"1_a_task".to_string(),
"3_task".to_string(),
"10_hello".to_string(),
"11_hello".to_string(),
],
"After global tasks update, worktree task usage is not erased and it's the first still; global task is back to regular order as its file was updated"
);
register_task_used(&inventory, "11_hello", cx);
@ -1045,10 +1134,11 @@ mod tests {
resolved_task_names(&inventory, None, cx),
vec![
"11_hello".to_string(),
"3_task".to_string(),
"worktree_task_1".to_string(),
"1_a_task".to_string(),
"1_task".to_string(),
"2_task".to_string(),
"1_a_task".to_string(),
"3_task".to_string(),
"10_hello".to_string(),
],
);
@ -1227,9 +1317,10 @@ mod tests {
})
}
fn mock_tasks_from_names<'a>(task_names: impl Iterator<Item = &'a str> + 'a) -> String {
fn mock_tasks_from_names<'a>(task_names: impl IntoIterator<Item = &'a str> + 'a) -> String {
serde_json::to_string(&serde_json::Value::Array(
task_names
.into_iter()
.map(|task_name| {
json!({
"label": task_name,