From 265ad900344c2cd21cf5f2abc9a6b8efc4f1fa31 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 20 Apr 2021 10:39:14 -0700 Subject: [PATCH] Stop processing events if root path is deleted Co-Authored-By: Antonio Scandurra --- zed/src/worktree.rs | 127 +++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/zed/src/worktree.rs b/zed/src/worktree.rs index 749390bf83..27abd4510a 100644 --- a/zed/src/worktree.rs +++ b/zed/src/worktree.rs @@ -523,7 +523,9 @@ impl BackgroundScanner { return false; } - self.process_events(events); + if !self.process_events(events) { + return false; + } if smol::block_on(self.notify.send(ScanState::Idle)).is_err() { return false; @@ -701,12 +703,13 @@ impl BackgroundScanner { Ok(()) } - fn process_events(&self, mut events: Vec) { + fn process_events(&self, mut events: Vec) -> bool { let mut snapshot = self.snapshot(); - let root_path = snapshot - .path - .canonicalize() - .unwrap_or_else(|_| snapshot.path.to_path_buf()); + let root_path = if let Ok(path) = snapshot.path.canonicalize() { + path + } else { + return false; + }; events.sort_unstable_by(|a, b| a.path.cmp(&b.path)); let mut paths = events.into_iter().map(|e| e.path).peekable(); @@ -769,68 +772,68 @@ impl BackgroundScanner { }); } }); + + true } fn fs_entry_for_path(&self, root_path: &Path, path: &Path) -> Result> { - match fs::metadata(&path) { - Ok(metadata) => { - let mut ignore = IgnoreBuilder::new().build().add_parents(&path).unwrap(); - if metadata.is_dir() { - ignore = ignore.add_child(&path).unwrap(); - } - let is_ignored = ignore.matched(&path, metadata.is_dir()).is_ignore(); - - let inode = metadata.ino(); - let is_symlink = fs::symlink_metadata(&path) - .context("failed to read symlink metadata")? - .file_type() - .is_symlink(); - let parent = if path == root_path { - None - } else { - Some( - fs::metadata(path.parent().unwrap()) - .context("failed to read parent inode")? - .ino(), - ) - }; - if metadata.file_type().is_dir() { - Ok(Some(( - Entry::Dir { - parent, - inode, - is_symlink, - is_ignored, - children: Arc::from([]), - pending: true, - }, - ignore, - ))) - } else { - Ok(Some(( - Entry::File { - parent, - path: PathEntry::new( - inode, - root_path - .parent() - .map_or(path, |parent| path.strip_prefix(parent).unwrap()), - is_ignored, - ), - inode, - is_symlink, - is_ignored, - }, - ignore, - ))) + let metadata = match fs::metadata(&path) { + Err(err) => { + return match (err.kind(), err.raw_os_error()) { + (io::ErrorKind::NotFound, _) => Ok(None), + (io::ErrorKind::Other, Some(libc::ENOTDIR)) => Ok(None), + _ => Err(anyhow::Error::new(err)), } } - Err(err) => match (err.kind(), err.raw_os_error()) { - (io::ErrorKind::NotFound, _) => Ok(None), - (io::ErrorKind::Other, Some(libc::ENOTDIR)) => Ok(None), - _ => Err(anyhow::Error::new(err)), - }, + Ok(metadata) => metadata, + }; + + let mut ignore = IgnoreBuilder::new().build().add_parents(&path).unwrap(); + if metadata.is_dir() { + ignore = ignore.add_child(&path).unwrap(); } + let is_ignored = ignore.matched(&path, metadata.is_dir()).is_ignore(); + let inode = metadata.ino(); + let is_symlink = fs::symlink_metadata(&path) + .context("failed to read symlink metadata")? + .file_type() + .is_symlink(); + let parent = if path == root_path { + None + } else { + Some( + fs::metadata(path.parent().unwrap()) + .context("failed to read parent inode")? + .ino(), + ) + }; + + let entry = if metadata.file_type().is_dir() { + Entry::Dir { + inode, + parent, + is_symlink, + is_ignored, + pending: true, + children: Arc::from([]), + } + } else { + Entry::File { + inode, + parent, + is_symlink, + is_ignored, + path: PathEntry::new( + inode, + root_path + .parent() + .map_or(path, |parent| path.strip_prefix(parent).unwrap()), + is_ignored, + ), + } + }; + + Ok(Some((entry, ignore))) } fn insert_entries(&self, entries: impl IntoIterator) {