collab: Fix project sharing between Windows and Unix (#23680)
Closes #14258 Windows user(host) sharing a project to a guest(using macOS), and host follows guest: https://github.com/user-attachments/assets/ba306b6b-23f7-48b1-8ba8-fdc5992d8f00 macOS user(host) sharing a project to a guest(using Windows), and host follows guest: https://github.com/user-attachments/assets/c5ee5e78-870d-49e5-907d-8565977a01ae macOS user edits files in a windows project through collab: https://github.com/user-attachments/assets/581057cf-e7df-4e56-a0ce-ced74339906a Release Notes: - N/A
This commit is contained in:
parent
929c5e76b4
commit
c1f162abc6
14 changed files with 226 additions and 117 deletions
|
@ -1,3 +1,4 @@
|
|||
use ::proto::{FromProto, ToProto};
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use extension::ExtensionHostProxy;
|
||||
use extension_host::headless_host::HeadlessExtensionStore;
|
||||
|
@ -325,10 +326,8 @@ impl HeadlessProject {
|
|||
mut cx: AsyncApp,
|
||||
) -> Result<proto::AddWorktreeResponse> {
|
||||
use client::ErrorCodeExt;
|
||||
let path = shellexpand::tilde(&message.payload.path).to_string();
|
||||
|
||||
let fs = this.read_with(&mut cx, |this, _| this.fs.clone())?;
|
||||
let path = PathBuf::from(path);
|
||||
let path = PathBuf::from_proto(shellexpand::tilde(&message.payload.path).to_string());
|
||||
|
||||
let canonicalized = match fs.canonicalize(&path).await {
|
||||
Ok(path) => path,
|
||||
|
@ -363,7 +362,7 @@ impl HeadlessProject {
|
|||
let response = this.update(&mut cx, |_, cx| {
|
||||
worktree.update(cx, |worktree, _| proto::AddWorktreeResponse {
|
||||
worktree_id: worktree.id().to_proto(),
|
||||
canonicalized_path: canonicalized.to_string_lossy().to_string(),
|
||||
canonicalized_path: canonicalized.to_proto(),
|
||||
})
|
||||
})?;
|
||||
|
||||
|
@ -418,7 +417,7 @@ impl HeadlessProject {
|
|||
buffer_store.open_buffer(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: PathBuf::from(message.payload.path).into(),
|
||||
path: Arc::<Path>::from_proto(message.payload.path),
|
||||
},
|
||||
cx,
|
||||
)
|
||||
|
@ -559,11 +558,11 @@ impl HeadlessProject {
|
|||
envelope: TypedEnvelope<proto::ListRemoteDirectory>,
|
||||
cx: AsyncApp,
|
||||
) -> Result<proto::ListRemoteDirectoryResponse> {
|
||||
let expanded = shellexpand::tilde(&envelope.payload.path).to_string();
|
||||
let fs = cx.read_entity(&this, |this, _| this.fs.clone())?;
|
||||
let expanded = PathBuf::from_proto(shellexpand::tilde(&envelope.payload.path).to_string());
|
||||
|
||||
let mut entries = Vec::new();
|
||||
let mut response = fs.read_dir(Path::new(&expanded)).await?;
|
||||
let mut response = fs.read_dir(&expanded).await?;
|
||||
while let Some(path) = response.next().await {
|
||||
if let Some(file_name) = path?.file_name() {
|
||||
entries.push(file_name.to_string_lossy().to_string());
|
||||
|
@ -578,15 +577,15 @@ impl HeadlessProject {
|
|||
cx: AsyncApp,
|
||||
) -> Result<proto::GetPathMetadataResponse> {
|
||||
let fs = cx.read_entity(&this, |this, _| this.fs.clone())?;
|
||||
let expanded = shellexpand::tilde(&envelope.payload.path).to_string();
|
||||
let expanded = PathBuf::from_proto(shellexpand::tilde(&envelope.payload.path).to_string());
|
||||
|
||||
let metadata = fs.metadata(&PathBuf::from(expanded.clone())).await?;
|
||||
let metadata = fs.metadata(&expanded).await?;
|
||||
let is_dir = metadata.map(|metadata| metadata.is_dir).unwrap_or(false);
|
||||
|
||||
Ok(proto::GetPathMetadataResponse {
|
||||
exists: metadata.is_some(),
|
||||
is_dir,
|
||||
path: expanded,
|
||||
path: expanded.to_proto(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -859,7 +859,7 @@ async fn test_remote_resolve_path_in_buffer(
|
|||
async fn test_remote_resolve_abs_path(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
|
||||
let fs = FakeFs::new(server_cx.executor());
|
||||
fs.insert_tree(
|
||||
"/code",
|
||||
path!("/code"),
|
||||
json!({
|
||||
"project1": {
|
||||
".git": {},
|
||||
|
@ -876,7 +876,7 @@ async fn test_remote_resolve_abs_path(cx: &mut TestAppContext, server_cx: &mut T
|
|||
|
||||
let path = project
|
||||
.update(cx, |project, cx| {
|
||||
project.resolve_abs_path("/code/project1/README.md", cx)
|
||||
project.resolve_abs_path(path!("/code/project1/README.md"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -884,12 +884,12 @@ async fn test_remote_resolve_abs_path(cx: &mut TestAppContext, server_cx: &mut T
|
|||
assert!(path.is_file());
|
||||
assert_eq!(
|
||||
path.abs_path().unwrap().to_string_lossy(),
|
||||
"/code/project1/README.md"
|
||||
path!("/code/project1/README.md")
|
||||
);
|
||||
|
||||
let path = project
|
||||
.update(cx, |project, cx| {
|
||||
project.resolve_abs_path("/code/project1/src", cx)
|
||||
project.resolve_abs_path(path!("/code/project1/src"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -897,12 +897,12 @@ async fn test_remote_resolve_abs_path(cx: &mut TestAppContext, server_cx: &mut T
|
|||
assert!(path.is_dir());
|
||||
assert_eq!(
|
||||
path.abs_path().unwrap().to_string_lossy(),
|
||||
"/code/project1/src"
|
||||
path!("/code/project1/src")
|
||||
);
|
||||
|
||||
let path = project
|
||||
.update(cx, |project, cx| {
|
||||
project.resolve_abs_path("/code/project1/DOESNOTEXIST", cx)
|
||||
project.resolve_abs_path(path!("/code/project1/DOESNOTEXIST"), cx)
|
||||
})
|
||||
.await;
|
||||
assert!(path.is_none());
|
||||
|
@ -958,7 +958,7 @@ async fn test_adding_then_removing_then_adding_worktrees(
|
|||
) {
|
||||
let fs = FakeFs::new(server_cx.executor());
|
||||
fs.insert_tree(
|
||||
"/code",
|
||||
path!("/code"),
|
||||
json!({
|
||||
"project1": {
|
||||
".git": {},
|
||||
|
@ -977,14 +977,14 @@ async fn test_adding_then_removing_then_adding_worktrees(
|
|||
let (project, _headless) = init_test(&fs, cx, server_cx).await;
|
||||
let (_worktree, _) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/code/project1", true, cx)
|
||||
project.find_or_create_worktree(path!("/code/project1"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let (worktree_2, _) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/code/project2", true, cx)
|
||||
project.find_or_create_worktree(path!("/code/project2"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -994,7 +994,7 @@ async fn test_adding_then_removing_then_adding_worktrees(
|
|||
|
||||
let (worktree_2, _) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree("/code/project2", true, cx)
|
||||
project.find_or_create_worktree(path!("/code/project2"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue