Support find_project_path
being given absolute paths (#30283)
Sometimes models return absolute paths even though we ask them not to (including sometimes returning `/dev/null`). Currently we assume we're always given a relative path, which leads to a panic in debug builds. Now we just support being given absolute paths. Release Notes: - N/A --------- Co-authored-by: Agus Zubiaga <hi@aguz.me>
This commit is contained in:
parent
6827bf114a
commit
77945fc905
2 changed files with 115 additions and 16 deletions
|
@ -4163,6 +4163,18 @@ impl Project {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
let worktree_store = self.worktree_store.read(cx);
|
let worktree_store = self.worktree_store.read(cx);
|
||||||
|
|
||||||
|
if path.is_absolute() {
|
||||||
|
for worktree in worktree_store.visible_worktrees(cx) {
|
||||||
|
let worktree_abs_path = worktree.read(cx).abs_path();
|
||||||
|
|
||||||
|
if let Ok(relative_path) = path.strip_prefix(worktree_abs_path) {
|
||||||
|
return Some(ProjectPath {
|
||||||
|
worktree_id: worktree.read(cx).id(),
|
||||||
|
path: relative_path.into(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for worktree in worktree_store.visible_worktrees(cx) {
|
for worktree in worktree_store.visible_worktrees(cx) {
|
||||||
let worktree_root_name = worktree.read(cx).root_name();
|
let worktree_root_name = worktree.read(cx).root_name();
|
||||||
if let Ok(relative_path) = path.strip_prefix(worktree_root_name) {
|
if let Ok(relative_path) = path.strip_prefix(worktree_root_name) {
|
||||||
|
@ -4182,6 +4194,7 @@ impl Project {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -8766,3 +8766,89 @@ fn git_status(repo: &git2::Repository) -> collections::HashMap<String, git2::Sta
|
||||||
.map(|status| (status.path().unwrap().to_string(), status.status()))
|
.map(|status| (status.path().unwrap().to_string(), status.status()))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_find_project_path_abs(
|
||||||
|
background_executor: BackgroundExecutor,
|
||||||
|
cx: &mut gpui::TestAppContext,
|
||||||
|
) {
|
||||||
|
// find_project_path should work with absolute paths
|
||||||
|
init_test(cx);
|
||||||
|
|
||||||
|
let fs = FakeFs::new(background_executor);
|
||||||
|
fs.insert_tree(
|
||||||
|
path!("/root"),
|
||||||
|
json!({
|
||||||
|
"project1": {
|
||||||
|
"file1.txt": "content1",
|
||||||
|
"subdir": {
|
||||||
|
"file2.txt": "content2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"project2": {
|
||||||
|
"file3.txt": "content3"
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let project = Project::test(
|
||||||
|
fs.clone(),
|
||||||
|
[
|
||||||
|
path!("/root/project1").as_ref(),
|
||||||
|
path!("/root/project2").as_ref(),
|
||||||
|
],
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// Make sure the worktrees are fully initialized
|
||||||
|
for worktree in project.read_with(cx, |project, cx| project.worktrees(cx).collect::<Vec<_>>()) {
|
||||||
|
worktree
|
||||||
|
.read_with(cx, |tree, _| tree.as_local().unwrap().scan_complete())
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
cx.run_until_parked();
|
||||||
|
|
||||||
|
let (project1_abs_path, project1_id, project2_abs_path, project2_id) =
|
||||||
|
project.read_with(cx, |project, cx| {
|
||||||
|
let worktrees: Vec<_> = project.worktrees(cx).collect();
|
||||||
|
let abs_path1 = worktrees[0].read(cx).abs_path().to_path_buf();
|
||||||
|
let id1 = worktrees[0].read(cx).id();
|
||||||
|
let abs_path2 = worktrees[1].read(cx).abs_path().to_path_buf();
|
||||||
|
let id2 = worktrees[1].read(cx).id();
|
||||||
|
(abs_path1, id1, abs_path2, id2)
|
||||||
|
});
|
||||||
|
|
||||||
|
project.update(cx, |project, cx| {
|
||||||
|
let abs_path = project1_abs_path.join("file1.txt");
|
||||||
|
let found_path = project.find_project_path(abs_path, cx).unwrap();
|
||||||
|
assert_eq!(found_path.worktree_id, project1_id);
|
||||||
|
assert_eq!(found_path.path.as_ref(), Path::new("file1.txt"));
|
||||||
|
|
||||||
|
let abs_path = project1_abs_path.join("subdir").join("file2.txt");
|
||||||
|
let found_path = project.find_project_path(abs_path, cx).unwrap();
|
||||||
|
assert_eq!(found_path.worktree_id, project1_id);
|
||||||
|
assert_eq!(found_path.path.as_ref(), Path::new("subdir/file2.txt"));
|
||||||
|
|
||||||
|
let abs_path = project2_abs_path.join("file3.txt");
|
||||||
|
let found_path = project.find_project_path(abs_path, cx).unwrap();
|
||||||
|
assert_eq!(found_path.worktree_id, project2_id);
|
||||||
|
assert_eq!(found_path.path.as_ref(), Path::new("file3.txt"));
|
||||||
|
|
||||||
|
let abs_path = project1_abs_path.join("nonexistent.txt");
|
||||||
|
let found_path = project.find_project_path(abs_path, cx);
|
||||||
|
assert!(
|
||||||
|
found_path.is_some(),
|
||||||
|
"Should find project path for nonexistent file in worktree"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test with an absolute path outside any worktree
|
||||||
|
let abs_path = Path::new("/some/other/path");
|
||||||
|
let found_path = project.find_project_path(abs_path, cx);
|
||||||
|
assert!(
|
||||||
|
found_path.is_none(),
|
||||||
|
"Should not find project path for path outside any worktree"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue