Get the test to failing,,, correctly

Mikayla Maki created

Change summary

Cargo.lock                           |  2 
crates/project/Cargo.toml            |  1 
crates/project/src/git_repository.rs | 10 ++++
crates/project/src/worktree.rs       | 68 +++++++++++++++--------------
crates/util/Cargo.toml               |  6 ++
crates/util/src/lib.rs               |  7 +++
crates/util/src/test.rs              |  8 +++
7 files changed, 68 insertions(+), 34 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -6359,6 +6359,8 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "futures",
+ "git2",
+ "lazy_static",
  "log",
  "rand 0.8.5",
  "serde_json",

crates/project/Cargo.toml 🔗

@@ -54,6 +54,7 @@ toml = "0.5"
 rocksdb = "0.18"
 git2 = { version = "0.15", default-features = false }
 
+
 [dev-dependencies]
 client = { path = "../client", features = ["test-support"] }
 collections = { path = "../collections", features = ["test-support"] }

crates/project/src/git_repository.rs 🔗

@@ -11,6 +11,7 @@ pub trait GitRepository: Send + Sync {
     fn git_dir_path(&self) -> &Path;
     fn last_scan_id(&self) -> usize;
     fn set_scan_id(&mut self, scan_id: usize);
+    fn with_repo(&mut self, f: Box<dyn FnOnce(&mut git2::Repository)>);
 }
 
 #[derive(Clone)]
@@ -70,6 +71,11 @@ impl GitRepository for RealGitRepository {
     fn set_scan_id(&mut self, scan_id: usize) {
         self.last_scan_id = scan_id;
     }
+
+    fn with_repo(&mut self, f: Box<dyn FnOnce(&mut git2::Repository)>) {
+        let mut git2 = self.libgit_repository.lock();
+        f(&mut git2)
+    }
 }
 
 impl PartialEq for &Box<dyn GitRepository> {
@@ -129,4 +135,8 @@ impl GitRepository for FakeGitRepository {
     fn set_scan_id(&mut self, scan_id: usize) {
         self.last_scan_id = scan_id;
     }
+
+    fn with_repo(&mut self, _: Box<dyn FnOnce(&mut git2::Repository)>) {
+        unimplemented!();
+    }
 }

crates/project/src/worktree.rs 🔗

@@ -26,7 +26,6 @@ use language::{
     proto::{deserialize_version, serialize_line_ending, serialize_version},
     Buffer, DiagnosticEntry, LineEnding, PointUtf16, Rope,
 };
-use lazy_static::lazy_static;
 use parking_lot::Mutex;
 use postage::{
     prelude::{Sink as _, Stream as _},
@@ -50,12 +49,7 @@ use std::{
     time::{Duration, SystemTime},
 };
 use sum_tree::{Bias, Edit, SeekTarget, SumTree, TreeMap, TreeSet};
-use util::{ResultExt, TryFutureExt};
-
-lazy_static! {
-    static ref DOT_GIT: &'static OsStr = OsStr::new(".git");
-    static ref GITIGNORE: &'static OsStr = OsStr::new(".gitignore");
-}
+use util::{ResultExt, TryFutureExt, DOT_GIT, GITIGNORE};
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)]
 pub struct WorktreeId(usize);
@@ -1317,6 +1311,13 @@ impl LocalSnapshot {
         &self,
         path: &Path,
     ) -> Option<Box<dyn GitRepository>> {
+        let repos = self
+            .git_repositories
+            .iter()
+            .map(|repo| repo.content_path().to_str().unwrap().to_string())
+            .collect::<Vec<String>>();
+        dbg!(repos);
+
         self.git_repositories
             .iter()
             .rev() //git_repository is ordered lexicographically
@@ -1437,6 +1438,7 @@ impl LocalSnapshot {
     }
 
     fn insert_entry(&mut self, mut entry: Entry, fs: &dyn Fs) -> Entry {
+        dbg!(&entry.path);
         if entry.is_file() && entry.path.file_name() == Some(&GITIGNORE) {
             let abs_path = self.abs_path.join(&entry.path);
             match smol::block_on(build_gitignore(&abs_path, fs)) {
@@ -1455,6 +1457,8 @@ impl LocalSnapshot {
                 }
             }
         } else if entry.path.file_name() == Some(&DOT_GIT) {
+            dbg!(&entry.path);
+
             let abs_path = self.abs_path.join(&entry.path);
             let content_path: Arc<Path> = entry.path.parent().unwrap().into();
             if let Err(ix) = self
@@ -2223,6 +2227,7 @@ impl BackgroundScanner {
             if ignore_stack.is_all() {
                 if let Some(mut root_entry) = snapshot.root_entry().cloned() {
                     root_entry.is_ignored = true;
+                    dbg!("scan dirs entry");
                     snapshot.insert_entry(root_entry, self.fs.as_ref());
                 }
             }
@@ -2445,6 +2450,7 @@ impl BackgroundScanner {
                             snapshot.root_char_bag,
                         );
                         fs_entry.is_ignored = ignore_stack.is_all();
+                        dbg!("process_events entry");
                         snapshot.insert_entry(fs_entry, self.fs.as_ref());
 
                         let mut ancestor_inodes = snapshot.ancestor_inodes_for_path(&path);
@@ -3145,50 +3151,46 @@ mod tests {
 
     #[gpui::test]
     async fn test_git_repository_for_path(cx: &mut TestAppContext) {
-        let fs = FakeFs::new(cx.background());
-
-        fs.insert_tree(
-            "/root",
-            json!({
-                "dir1": {
-                    ".git": {
-                        "HEAD": "abc"
-                    },
-                    "deps": {
-                        "dep1": {
-                            ".git": {},
-                            "src": {
-                                "a.txt": ""
-                            }
+        let root = temp_tree(json!({
+            "dir1": {
+                ".git": {},
+                "deps": {
+                    "dep1": {
+                        ".git": {},
+                        "src": {
+                            "a.txt": ""
                         }
-                    },
-                    "src": {
-                        "b.txt": ""
                     }
                 },
-                "c.txt": ""
-            }),
-        )
-        .await;
+                "src": {
+                    "b.txt": ""
+                }
+            },
+            "c.txt": ""
+        }));
 
         let http_client = FakeHttpClient::with_404_response();
         let client = Client::new(http_client);
         let tree = Worktree::local(
             client,
-            Arc::from(Path::new("/root")),
+            root.path(),
             true,
-            fs.clone(),
+            Arc::new(RealFs),
             Default::default(),
             &mut cx.to_async(),
         )
         .await
         .unwrap();
 
-        cx.foreground().run_until_parked();
+        cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
+            .await;
+        tree.flush_fs_events(cx).await;
 
-        tree.read_with(cx, |tree, cx| {
+        tree.read_with(cx, |tree, _cx| {
             let tree = tree.as_local().unwrap();
 
+            dbg!(tree);
+
             assert!(tree
                 .git_repository_for_file_path("c.txt".as_ref())
                 .is_none());

crates/util/Cargo.toml 🔗

@@ -7,17 +7,21 @@ edition = "2021"
 doctest = false
 
 [features]
-test-support = ["rand", "serde_json", "tempdir"]
+test-support = ["rand", "serde_json", "tempdir", "git2"]
 
 [dependencies]
 anyhow = "1.0.38"
 futures = "0.3"
 log = { version = "0.4.16", features = ["kv_unstable_serde"] }
+lazy_static = "1.4.0"
 rand = { version = "0.8", optional = true }
 tempdir = { version = "0.3.7", optional = true }
 serde_json = { version = "1.0", features = ["preserve_order"], optional = true }
+git2 = { version = "0.15", default-features = false, optional = true }
+
 
 [dev-dependencies]
 rand = { version = "0.8" }
 tempdir = { version = "0.3.7" }
 serde_json = { version = "1.0", features = ["preserve_order"] }
+git2 = { version = "0.15", default-features = false }

crates/util/src/lib.rs 🔗

@@ -2,13 +2,20 @@
 pub mod test;
 
 use futures::Future;
+use lazy_static::lazy_static;
 use std::{
     cmp::Ordering,
+    ffi::OsStr,
     ops::AddAssign,
     pin::Pin,
     task::{Context, Poll},
 };
 
+lazy_static! {
+    pub static ref DOT_GIT: &'static OsStr = OsStr::new(".git");
+    pub static ref GITIGNORE: &'static OsStr = OsStr::new(".gitignore");
+}
+
 pub fn truncate(s: &str, max_chars: usize) -> &str {
     match s.char_indices().nth(max_chars) {
         None => s,

crates/util/src/test.rs 🔗

@@ -1,12 +1,15 @@
 mod assertions;
 mod marked_text;
 
+use git2;
 use std::path::{Path, PathBuf};
 use tempdir::TempDir;
 
 pub use assertions::*;
 pub use marked_text::*;
 
+use crate::DOT_GIT;
+
 pub fn temp_tree(tree: serde_json::Value) -> TempDir {
     let dir = TempDir::new("").unwrap();
     write_tree(dir.path(), tree);
@@ -24,6 +27,11 @@ fn write_tree(path: &Path, tree: serde_json::Value) {
             match contents {
                 Value::Object(_) => {
                     fs::create_dir(&path).unwrap();
+
+                    if path.file_name() == Some(&DOT_GIT) {
+                        git2::Repository::init(&path.parent().unwrap()).unwrap();
+                    }
+
                     write_tree(&path, contents);
                 }
                 Value::Null => {