Detailed changes
@@ -18,7 +18,7 @@ use gpui::{
use postage::oneshot;
use rpc::{
proto::{self, SSH_PROJECT_ID},
- AnyProtoClient, TypedEnvelope,
+ AnyProtoClient, ErrorExt, TypedEnvelope,
};
use smol::{
channel::{Receiver, Sender},
@@ -207,7 +207,7 @@ impl WorktreeStore {
cx.background_executor().spawn(async move {
match task.await {
Ok(worktree) => Ok(worktree),
- Err(err) => Err(anyhow!("{}", err)),
+ Err(err) => Err((*err).cloned()),
}
})
}
@@ -22,6 +22,7 @@ test-support = ["fs/test-support"]
[dependencies]
anyhow.workspace = true
+client.workspace = true
env_logger.workspace = true
fs.workspace = true
futures.workspace = true
@@ -189,11 +189,34 @@ impl HeadlessProject {
message: TypedEnvelope<proto::AddWorktree>,
mut cx: AsyncAppContext,
) -> 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 canonicalized = match fs.canonicalize(&path).await {
+ Ok(path) => path,
+ Err(e) => {
+ let mut parent = path
+ .parent()
+ .ok_or(e)
+ .map_err(|_| anyhow!("{:?} does not exist", path))?;
+ if parent == Path::new("") {
+ parent = util::paths::home_dir();
+ }
+ let parent = fs.canonicalize(parent).await.map_err(|_| {
+ anyhow!(proto::ErrorCode::DevServerProjectPathDoesNotExist
+ .with_tag("path", &path.to_string_lossy().as_ref()))
+ })?;
+ parent.join(path.file_name().unwrap())
+ }
+ };
+
let worktree = this
.update(&mut cx.clone(), |this, _| {
Worktree::local(
- Path::new(&path),
+ Arc::from(canonicalized),
true,
this.fs.clone(),
this.next_entry_id.clone(),
@@ -5544,12 +5544,21 @@ pub fn open_ssh_project(
)
})?;
+ let mut project_paths_to_open = vec![];
+ let mut project_path_errors = vec![];
+
for path in paths {
- project
- .update(&mut cx, |project, cx| {
- project.find_or_create_worktree(&path, true, cx)
- })?
- .await?;
+ let result = cx
+ .update(|cx| Workspace::project_path_for_path(project.clone(), &path, true, cx))?
+ .await;
+ match result {
+ Ok((_, project_path)) => {
+ project_paths_to_open.push((path.clone(), Some(project_path)));
+ }
+ Err(error) => {
+ project_path_errors.push(error);
+ }
+ };
}
let serialized_workspace =
@@ -5576,11 +5585,21 @@ pub fn open_ssh_project(
.update(&mut cx, |_, cx| {
cx.activate_window();
- open_items(serialized_workspace, vec![], app_state, cx)
+ open_items(serialized_workspace, project_paths_to_open, app_state, cx)
})?
.await?;
- Ok(())
+ window.update(&mut cx, |workspace, cx| {
+ for error in project_path_errors {
+ if error.error_code() == proto::ErrorCode::DevServerProjectPathDoesNotExist {
+ if let Some(path) = error.error_tag("path") {
+ workspace.show_error(&anyhow!("'{path}' does not exist"), cx)
+ }
+ } else {
+ workspace.show_error(&error, cx)
+ }
+ }
+ })
})
}