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 ---------
Unified · Split
| @@ -4163,23 +4163,36 @@ impl Project { · 4162 unmodified lines | |||
| 4163 | let path = path.as_ref(); | 4163 | let path = path.as_ref(); |
| 4164 | let worktree_store = self.worktree_store.read(cx); | 4164 | let worktree_store = self.worktree_store.read(cx); |
| 4165 | 4165 | ||
| 4166 | for worktree in worktree_store.visible_worktrees(cx) { | 4166 | if path.is_absolute() { |
| 4167 | let worktree_root_name = worktree.read(cx).root_name(); | 4167 | for worktree in worktree_store.visible_worktrees(cx) { |
| 4168 | if let Ok(relative_path) = path.strip_prefix(worktree_root_name) { | 4168 | let worktree_abs_path = worktree.read(cx).abs_path(); |
| 4169 | return Some(ProjectPath { | 4169 | |
| 4170 | worktree_id: worktree.read(cx).id(), | 4170 | if let Ok(relative_path) = path.strip_prefix(worktree_abs_path) { |
| 4171 | path: relative_path.into(), | 4171 | return Some(ProjectPath { |
| 4172 | }); | 4172 | worktree_id: worktree.read(cx).id(), |
| 4173 | path: relative_path.into(), | ||
| 4174 | }); | ||
| 4175 | } | ||
| 4176 | } | ||
| 4177 | } else { | ||
| 4178 | for worktree in worktree_store.visible_worktrees(cx) { | ||
| 4179 | let worktree_root_name = worktree.read(cx).root_name(); | ||
| 4180 | if let Ok(relative_path) = path.strip_prefix(worktree_root_name) { | ||
| 4181 | return Some(ProjectPath { | ||
| 4182 | worktree_id: worktree.read(cx).id(), | ||
| 4183 | path: relative_path.into(), | ||
| 4184 | }); | ||
| 4185 | } | ||
| 4173 | } | 4186 | } |
| 4174 | } | ||
| 4175 | 4187 | ||
| 4176 | for worktree in worktree_store.visible_worktrees(cx) { | 4188 | for worktree in worktree_store.visible_worktrees(cx) { |
| 4177 | let worktree = worktree.read(cx); | 4189 | let worktree = worktree.read(cx); |
| 4178 | if let Some(entry) = worktree.entry_for_path(path) { | 4190 | if let Some(entry) = worktree.entry_for_path(path) { |
| 4179 | return Some(ProjectPath { | 4191 | return Some(ProjectPath { |
| 4180 | worktree_id: worktree.id(), | 4192 | worktree_id: worktree.id(), |
| 4181 | path: entry.path.clone(), | 4193 | path: entry.path.clone(), |
| 4182 | }); | 4194 | }); |
| 4195 | } | ||
| 4183 | } | 4196 | } |
| 4184 | } | 4197 | } |
| 4185 | 4198 | ||
| @@ -8766,3 +8766,89 @@ fn git_status(repo: &git2::Repository) -> collections::HashMap<String, git2::Sta · 8765 unmodified lines | |||
| 8766 | .map(|status| (status.path().unwrap().to_string(), status.status())) | 8766 | .map(|status| (status.path().unwrap().to_string(), status.status())) |
| 8767 | .collect() | 8767 | .collect() |
| 8768 | } | 8768 | } |
| 8769 | |||
| 8770 | #[gpui::test] | ||
| 8771 | async fn test_find_project_path_abs( | ||
| 8772 | background_executor: BackgroundExecutor, | ||
| 8773 | cx: &mut gpui::TestAppContext, | ||
| 8774 | ) { | ||
| 8775 | // find_project_path should work with absolute paths | ||
| 8776 | init_test(cx); | ||
| 8777 | |||
| 8778 | let fs = FakeFs::new(background_executor); | ||
| 8779 | fs.insert_tree( | ||
| 8780 | path!("/root"), | ||
| 8781 | json!({ | ||
| 8782 | "project1": { | ||
| 8783 | "file1.txt": "content1", | ||
| 8784 | "subdir": { | ||
| 8785 | "file2.txt": "content2" | ||
| 8786 | } | ||
| 8787 | }, | ||
| 8788 | "project2": { | ||
| 8789 | "file3.txt": "content3" | ||
| 8790 | } | ||
| 8791 | }), | ||
| 8792 | ) | ||
| 8793 | .await; | ||
| 8794 | |||
| 8795 | let project = Project::test( | ||
| 8796 | fs.clone(), | ||
| 8797 | [ | ||
| 8798 | path!("/root/project1").as_ref(), | ||
| 8799 | path!("/root/project2").as_ref(), | ||
| 8800 | ], | ||
| 8801 | cx, | ||
| 8802 | ) | ||
| 8803 | .await; | ||
| 8804 | |||
| 8805 | // Make sure the worktrees are fully initialized | ||
| 8806 | for worktree in project.read_with(cx, |project, cx| project.worktrees(cx).collect::<Vec<_>>()) { | ||
| 8807 | worktree | ||
| 8808 | .read_with(cx, |tree, _| tree.as_local().unwrap().scan_complete()) | ||
| 8809 | .await; | ||
| 8810 | } | ||
| 8811 | cx.run_until_parked(); | ||
| 8812 | |||
| 8813 | let (project1_abs_path, project1_id, project2_abs_path, project2_id) = | ||
| 8814 | project.read_with(cx, |project, cx| { | ||
| 8815 | let worktrees: Vec<_> = project.worktrees(cx).collect(); | ||
| 8816 | let abs_path1 = worktrees[0].read(cx).abs_path().to_path_buf(); | ||
| 8817 | let id1 = worktrees[0].read(cx).id(); | ||
| 8818 | let abs_path2 = worktrees[1].read(cx).abs_path().to_path_buf(); | ||
| 8819 | let id2 = worktrees[1].read(cx).id(); | ||
| 8820 | (abs_path1, id1, abs_path2, id2) | ||
| 8821 | }); | ||
| 8822 | |||
| 8823 | project.update(cx, |project, cx| { | ||
| 8824 | let abs_path = project1_abs_path.join("file1.txt"); | ||
| 8825 | let found_path = project.find_project_path(abs_path, cx).unwrap(); | ||
| 8826 | assert_eq!(found_path.worktree_id, project1_id); | ||
| 8827 | assert_eq!(found_path.path.as_ref(), Path::new("file1.txt")); | ||
| 8828 | |||
| 8829 | let abs_path = project1_abs_path.join("subdir").join("file2.txt"); | ||
| 8830 | let found_path = project.find_project_path(abs_path, cx).unwrap(); | ||
| 8831 | assert_eq!(found_path.worktree_id, project1_id); | ||
| 8832 | assert_eq!(found_path.path.as_ref(), Path::new("subdir/file2.txt")); | ||
| 8833 | |||
| 8834 | let abs_path = project2_abs_path.join("file3.txt"); | ||
| 8835 | let found_path = project.find_project_path(abs_path, cx).unwrap(); | ||
| 8836 | assert_eq!(found_path.worktree_id, project2_id); | ||
| 8837 | assert_eq!(found_path.path.as_ref(), Path::new("file3.txt")); | ||
| 8838 | |||
| 8839 | let abs_path = project1_abs_path.join("nonexistent.txt"); | ||
| 8840 | let found_path = project.find_project_path(abs_path, cx); | ||
| 8841 | assert!( | ||
| 8842 | found_path.is_some(), | ||
| 8843 | "Should find project path for nonexistent file in worktree" | ||
| 8844 | ); | ||
| 8845 | |||
| 8846 | // Test with an absolute path outside any worktree | ||
| 8847 | let abs_path = Path::new("/some/other/path"); | ||
| 8848 | let found_path = project.find_project_path(abs_path, cx); | ||
| 8849 | assert!( | ||
| 8850 | found_path.is_none(), | ||
| 8851 | "Should not find project path for path outside any worktree" | ||
| 8852 | ); | ||
| 8853 | }); | ||
| 8854 | } | ||