Get integration test passing. Wait for expand entry on remote projects.

This commit is contained in:
Max Brunsfeld 2023-06-21 13:38:30 -07:00
parent 400e3cda32
commit 5350164db9
6 changed files with 88 additions and 52 deletions

View file

@ -1266,6 +1266,27 @@ async fn test_share_project(
let client_b_collaborator = project.collaborators().get(&client_b_peer_id).unwrap(); let client_b_collaborator = project.collaborators().get(&client_b_peer_id).unwrap();
assert_eq!(client_b_collaborator.replica_id, replica_id_b); assert_eq!(client_b_collaborator.replica_id, replica_id_b);
}); });
project_b.read_with(cx_b, |project, cx| {
let worktree = project.worktrees(cx).next().unwrap().read(cx);
assert_eq!(
worktree.paths().map(AsRef::as_ref).collect::<Vec<_>>(),
[
Path::new(".gitignore"),
Path::new("a.txt"),
Path::new("b.txt"),
Path::new("ignored-dir"),
]
);
});
project_b
.update(cx_b, |project, cx| {
let worktree = project.worktrees(cx).next().unwrap();
let entry = worktree.read(cx).entry_for_path("ignored-dir").unwrap();
project.expand_entry(worktree_id, entry.id, cx).unwrap()
})
.await
.unwrap();
project_b.read_with(cx_b, |project, cx| { project_b.read_with(cx_b, |project, cx| {
let worktree = project.worktrees(cx).next().unwrap().read(cx); let worktree = project.worktrees(cx).next().unwrap().read(cx);
assert_eq!( assert_eq!(

View file

@ -1073,6 +1073,40 @@ impl Project {
} }
} }
pub fn expand_entry(
&mut self,
worktree_id: WorktreeId,
entry_id: ProjectEntryId,
cx: &mut ModelContext<Self>,
) -> Option<Task<Result<()>>> {
let worktree = self.worktree_for_id(worktree_id, cx)?;
if self.is_local() {
worktree.update(cx, |worktree, cx| {
worktree.as_local_mut().unwrap().expand_entry(entry_id, cx)
})
} else {
let worktree = worktree.downgrade();
let request = self.client.request(proto::ExpandProjectEntry {
project_id: self.remote_id().unwrap(),
entry_id: entry_id.to_proto(),
});
Some(cx.spawn_weak(|_, mut cx| async move {
let response = request.await?;
if let Some(worktree) = worktree.upgrade(&cx) {
worktree
.update(&mut cx, |worktree, _| {
worktree
.as_remote_mut()
.unwrap()
.wait_for_snapshot(response.worktree_scan_id as usize)
})
.await?;
}
Ok(())
}))
}
}
pub fn shared(&mut self, project_id: u64, cx: &mut ModelContext<Self>) -> Result<()> { pub fn shared(&mut self, project_id: u64, cx: &mut ModelContext<Self>) -> Result<()> {
if self.client_state.is_some() { if self.client_state.is_some() {
return Err(anyhow!("project was already shared")); return Err(anyhow!("project was already shared"));
@ -5404,31 +5438,6 @@ impl Project {
Some(ProjectPath { worktree_id, path }) Some(ProjectPath { worktree_id, path })
} }
pub fn mark_entry_expanded(
&mut self,
worktree_id: WorktreeId,
entry_id: ProjectEntryId,
cx: &mut ModelContext<Self>,
) -> Option<()> {
if self.is_local() {
let worktree = self.worktree_for_id(worktree_id, cx)?;
worktree.update(cx, |worktree, cx| {
worktree
.as_local_mut()
.unwrap()
.expand_entry_for_id(entry_id, cx);
});
} else if let Some(project_id) = self.remote_id() {
cx.background()
.spawn(self.client.request(proto::ExpandProjectEntry {
project_id,
entry_id: entry_id.to_proto(),
}))
.log_err();
}
Some(())
}
pub fn absolute_path(&self, project_path: &ProjectPath, cx: &AppContext) -> Option<PathBuf> { pub fn absolute_path(&self, project_path: &ProjectPath, cx: &AppContext) -> Option<PathBuf> {
let workspace_root = self let workspace_root = self
.worktree_for_id(project_path.worktree_id, cx)? .worktree_for_id(project_path.worktree_id, cx)?
@ -5736,18 +5745,22 @@ impl Project {
envelope: TypedEnvelope<proto::ExpandProjectEntry>, envelope: TypedEnvelope<proto::ExpandProjectEntry>,
_: Arc<Client>, _: Arc<Client>,
mut cx: AsyncAppContext, mut cx: AsyncAppContext,
) -> Result<proto::Ack> { ) -> Result<proto::ExpandProjectEntryResponse> {
let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id); let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
let worktree = this let worktree = this
.read_with(&cx, |this, cx| this.worktree_for_entry(entry_id, cx)) .read_with(&cx, |this, cx| this.worktree_for_entry(entry_id, cx))
.ok_or_else(|| anyhow!("invalid request"))?; .ok_or_else(|| anyhow!("invalid request"))?;
worktree.update(&mut cx, |worktree, cx| { worktree
.update(&mut cx, |worktree, cx| {
worktree worktree
.as_local_mut() .as_local_mut()
.unwrap() .unwrap()
.expand_entry_for_id(entry_id, cx) .expand_entry(entry_id, cx)
}); .ok_or_else(|| anyhow!("invalid entry"))
Ok(proto::Ack {}) })?
.await?;
let worktree_scan_id = worktree.read_with(&cx, |worktree, _| worktree.scan_id()) as u64;
Ok(proto::ExpandProjectEntryResponse { worktree_scan_id })
} }
async fn handle_update_diagnostic_summary( async fn handle_update_diagnostic_summary(

View file

@ -1127,21 +1127,17 @@ impl LocalWorktree {
})) }))
} }
pub fn expand_entry_for_id( pub fn expand_entry(
&mut self, &mut self,
entry_id: ProjectEntryId, entry_id: ProjectEntryId,
_cx: &mut ModelContext<Worktree>, cx: &mut ModelContext<Worktree>,
) -> barrier::Receiver { ) -> Option<Task<Result<()>>> {
let (tx, rx) = barrier::channel(); let path = self.entry_for_id(entry_id)?.path.clone();
if let Some(entry) = self.entry_for_id(entry_id) { let mut refresh = self.refresh_entries_for_paths(vec![path]);
self.scan_requests_tx Some(cx.background().spawn(async move {
.try_send(ScanRequest { refresh.next().await;
relative_paths: vec![entry.path.clone()], Ok(())
done: tx, }))
})
.ok();
}
rx
} }
pub fn refresh_entries_for_paths(&self, paths: Vec<Arc<Path>>) -> barrier::Receiver { pub fn refresh_entries_for_paths(&self, paths: Vec<Arc<Path>>) -> barrier::Receiver {
@ -1337,7 +1333,7 @@ impl RemoteWorktree {
self.completed_scan_id >= scan_id self.completed_scan_id >= scan_id
} }
fn wait_for_snapshot(&mut self, scan_id: usize) -> impl Future<Output = Result<()>> { pub(crate) fn wait_for_snapshot(&mut self, scan_id: usize) -> impl Future<Output = Result<()>> {
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
if self.observed_snapshot(scan_id) { if self.observed_snapshot(scan_id) {
let _ = tx.send(()); let _ = tx.send(());

View file

@ -423,7 +423,7 @@ impl ProjectPanel {
Ok(_) => self.select_next(&SelectNext, cx), Ok(_) => self.select_next(&SelectNext, cx),
Err(ix) => { Err(ix) => {
self.project.update(cx, |project, cx| { self.project.update(cx, |project, cx| {
project.mark_entry_expanded(worktree_id, entry_id, cx); project.expand_entry(worktree_id, entry_id, cx);
}); });
expanded_dir_ids.insert(ix, entry_id); expanded_dir_ids.insert(ix, entry_id);
@ -477,7 +477,7 @@ impl ProjectPanel {
expanded_dir_ids.remove(ix); expanded_dir_ids.remove(ix);
} }
Err(ix) => { Err(ix) => {
project.mark_entry_expanded(worktree_id, entry_id, cx); project.expand_entry(worktree_id, entry_id, cx);
expanded_dir_ids.insert(ix, entry_id); expanded_dir_ids.insert(ix, entry_id);
} }
} }
@ -1084,7 +1084,7 @@ impl ProjectPanel {
.worktree_for_id(worktree_id, cx) .worktree_for_id(worktree_id, cx)
.zip(self.expanded_dir_ids.get_mut(&worktree_id)) .zip(self.expanded_dir_ids.get_mut(&worktree_id))
{ {
project.mark_entry_expanded(worktree_id, entry_id, cx); project.expand_entry(worktree_id, entry_id, cx);
let worktree = worktree.read(cx); let worktree = worktree.read(cx);
if let Some(mut entry) = worktree.entry_for_id(entry_id) { if let Some(mut entry) = worktree.entry_for_id(entry_id) {

View file

@ -62,8 +62,9 @@ message Envelope {
RenameProjectEntry rename_project_entry = 46; RenameProjectEntry rename_project_entry = 46;
CopyProjectEntry copy_project_entry = 47; CopyProjectEntry copy_project_entry = 47;
DeleteProjectEntry delete_project_entry = 48; DeleteProjectEntry delete_project_entry = 48;
ExpandProjectEntry expand_project_entry = 114;
ProjectEntryResponse project_entry_response = 49; ProjectEntryResponse project_entry_response = 49;
ExpandProjectEntry expand_project_entry = 114;
ExpandProjectEntryResponse expand_project_entry_response = 115;
UpdateDiagnosticSummary update_diagnostic_summary = 50; UpdateDiagnosticSummary update_diagnostic_summary = 50;
StartLanguageServer start_language_server = 51; StartLanguageServer start_language_server = 51;
@ -378,6 +379,10 @@ message ExpandProjectEntry {
uint64 entry_id = 2; uint64 entry_id = 2;
} }
message ExpandProjectEntryResponse {
uint64 worktree_scan_id = 1;
}
message ProjectEntryResponse { message ProjectEntryResponse {
Entry entry = 1; Entry entry = 1;
uint64 worktree_scan_id = 2; uint64 worktree_scan_id = 2;

View file

@ -201,6 +201,7 @@ messages!(
(Ping, Foreground), (Ping, Foreground),
(PrepareRename, Background), (PrepareRename, Background),
(PrepareRenameResponse, Background), (PrepareRenameResponse, Background),
(ExpandProjectEntryResponse, Foreground),
(ProjectEntryResponse, Foreground), (ProjectEntryResponse, Foreground),
(RejoinRoom, Foreground), (RejoinRoom, Foreground),
(RejoinRoomResponse, Foreground), (RejoinRoomResponse, Foreground),
@ -256,7 +257,7 @@ request_messages!(
(CreateRoom, CreateRoomResponse), (CreateRoom, CreateRoomResponse),
(DeclineCall, Ack), (DeclineCall, Ack),
(DeleteProjectEntry, ProjectEntryResponse), (DeleteProjectEntry, ProjectEntryResponse),
(ExpandProjectEntry, Ack), (ExpandProjectEntry, ExpandProjectEntryResponse),
(Follow, FollowResponse), (Follow, FollowResponse),
(FormatBuffers, FormatBuffersResponse), (FormatBuffers, FormatBuffersResponse),
(GetChannelMessages, GetChannelMessagesResponse), (GetChannelMessages, GetChannelMessagesResponse),