upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/client.rs14
-rw-r--r--src/lib/git/mod.rs133
2 files changed, 140 insertions, 7 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs
index 01662cd..86e4097 100644
--- a/src/lib/client.rs
+++ b/src/lib/client.rs
@@ -1325,14 +1325,22 @@ fn pb_after_style(succeed: bool) -> indicatif::ProgressStyle {
1325} 1325}
1326 1326
1327async fn get_local_cache_database(git_repo_path: &Path) -> Result<NostrLMDB> { 1327async fn get_local_cache_database(git_repo_path: &Path) -> Result<NostrLMDB> {
1328 NostrLMDB::open(git_repo_path.join(".git/nostr-cache.lmdb")) 1328 let git_dir = git2::Repository::discover(git_repo_path)
1329 .context("failed to open or create nostr cache database at .git/nostr-cache.lmdb") 1329 .context("failed to discover git repository")?
1330 .commondir()
1331 .to_path_buf();
1332 NostrLMDB::open(git_dir.join("nostr-cache.lmdb"))
1333 .context("failed to open or create nostr cache database at <git-dir>/nostr-cache.lmdb")
1330} 1334}
1331 1335
1332async fn get_global_cache_database(git_repo_path: Option<&Path>) -> Result<NostrLMDB> { 1336async fn get_global_cache_database(git_repo_path: Option<&Path>) -> Result<NostrLMDB> {
1333 let path = if std::env::var("NGITTEST").is_ok() { 1337 let path = if std::env::var("NGITTEST").is_ok() {
1334 if let Some(git_repo_path) = git_repo_path { 1338 if let Some(git_repo_path) = git_repo_path {
1335 git_repo_path.join(".git/test-global-cache.lmdb") 1339 let git_dir = git2::Repository::discover(git_repo_path)
1340 .context("failed to discover git repository")?
1341 .commondir()
1342 .to_path_buf();
1343 git_dir.join("test-global-cache.lmdb")
1336 } else { 1344 } else {
1337 bail!("git_repo must be supplied to get_global_cache_database during integration tests") 1345 bail!("git_repo must be supplied to get_global_cache_database during integration tests")
1338 } 1346 }
diff --git a/src/lib/git/mod.rs b/src/lib/git/mod.rs
index 641349c..0001ca1 100644
--- a/src/lib/git/mod.rs
+++ b/src/lib/git/mod.rs
@@ -105,10 +105,9 @@ pub trait RepoActions {
105 105
106impl RepoActions for Repo { 106impl RepoActions for Repo {
107 fn get_path(&self) -> Result<&Path> { 107 fn get_path(&self) -> Result<&Path> {
108 self.git_repo 108 self.git_repo.workdir().context(
109 .path() 109 "failed to find repository working directory (bare repositories are not supported)",
110 .parent() 110 )
111 .context("failed to find repositiory path as .git has no parent")
112 } 111 }
113 112
114 fn get_origin_url(&self) -> Result<String> { 113 fn get_origin_url(&self) -> Result<String> {
@@ -2848,4 +2847,130 @@ index ce01362..a21e91c 100644\n\
2848 } 2847 }
2849 } 2848 }
2850 2849
2850 mod worktree {
2851 use super::*;
2852
2853 #[test]
2854 fn get_path_returns_worktree_working_dir() -> Result<()> {
2855 let test_repo = GitTestRepo::default();
2856 test_repo.populate()?;
2857
2858 let worktree_repo = test_repo.create_worktree("wt-branch")?;
2859 let git_repo = Repo::from_path(&worktree_repo.dir)?;
2860
2861 let path = git_repo.get_path()?;
2862 // get_path() should return the worktree's working directory, not
2863 // somewhere inside the main repo's .git/worktrees/
2864 assert_eq!(path.canonicalize()?, worktree_repo.dir.canonicalize()?,);
2865 Ok(())
2866 }
2867
2868 #[test]
2869 fn get_path_returns_normal_repo_working_dir() -> Result<()> {
2870 let test_repo = GitTestRepo::default();
2871 test_repo.populate()?;
2872
2873 let git_repo = Repo::from_path(&test_repo.dir)?;
2874 let path = git_repo.get_path()?;
2875 assert_eq!(path.canonicalize()?, test_repo.dir.canonicalize()?,);
2876 Ok(())
2877 }
2878
2879 #[test]
2880 fn from_path_works_with_worktree_dir() -> Result<()> {
2881 let test_repo = GitTestRepo::default();
2882 test_repo.populate()?;
2883
2884 let worktree_repo = test_repo.create_worktree("wt-open")?;
2885 // Opening from the worktree's working directory should succeed
2886 let git_repo = Repo::from_path(&worktree_repo.dir)?;
2887 // And get_path() should return the worktree dir
2888 assert_eq!(
2889 git_repo.get_path()?.canonicalize()?,
2890 worktree_repo.dir.canonicalize()?,
2891 );
2892 Ok(())
2893 }
2894
2895 #[test]
2896 fn worktree_can_read_branches() -> Result<()> {
2897 let test_repo = GitTestRepo::default();
2898 test_repo.populate()?;
2899
2900 let worktree_repo = test_repo.create_worktree("wt-branches")?;
2901 let git_repo = Repo::from_path(&worktree_repo.dir)?;
2902
2903 let branches = git_repo.get_local_branch_names()?;
2904 assert!(branches.contains(&"main".to_string()));
2905 assert!(branches.contains(&"wt-branches".to_string()));
2906 Ok(())
2907 }
2908
2909 #[test]
2910 fn worktree_can_read_git_config() -> Result<()> {
2911 let test_repo = GitTestRepo::default();
2912 test_repo.populate()?;
2913
2914 let worktree_repo = test_repo.create_worktree("wt-config")?;
2915 let git_repo = Repo::from_path(&worktree_repo.dir)?;
2916
2917 // nostr.repo is set by GitTestRepo::default() on the main repo
2918 // and should be readable from the worktree since config is shared
2919 let nostr_repo = git_repo.get_git_config_item("nostr.repo", None)?;
2920 assert!(nostr_repo.is_some());
2921 Ok(())
2922 }
2923
2924 #[test]
2925 fn worktree_get_head_commit_works() -> Result<()> {
2926 let test_repo = GitTestRepo::default();
2927 test_repo.populate()?;
2928
2929 let worktree_repo = test_repo.create_worktree("wt-head")?;
2930 let git_repo = Repo::from_path(&worktree_repo.dir)?;
2931
2932 // Should not error - worktree has its own HEAD
2933 let _head = git_repo.get_head_commit()?;
2934 Ok(())
2935 }
2936
2937 #[test]
2938 fn worktree_files_accessible_from_get_path() -> Result<()> {
2939 let test_repo = GitTestRepo::default();
2940 test_repo.populate()?;
2941
2942 let worktree_repo = test_repo.create_worktree("wt-files")?;
2943 let git_repo = Repo::from_path(&worktree_repo.dir)?;
2944
2945 // Create a file in the worktree
2946 let test_file = worktree_repo.dir.join("worktree-test.txt");
2947 fs::write(&test_file, "hello from worktree")?;
2948
2949 // get_path() should point to the worktree dir where the file lives
2950 let path = git_repo.get_path()?;
2951 assert!(path.join("worktree-test.txt").exists());
2952 Ok(())
2953 }
2954
2955 #[test]
2956 fn worktree_opened_via_git_dir_env_works() -> Result<()> {
2957 let test_repo = GitTestRepo::default();
2958 test_repo.populate()?;
2959
2960 let worktree_repo = test_repo.create_worktree("wt-gitdir")?;
2961
2962 // In a worktree, GIT_DIR points to the worktree-specific git dir
2963 // (e.g., .git/worktrees/<name>). Simulate what git does when
2964 // calling a remote helper.
2965 let git_dir = worktree_repo.git_repo.path().to_path_buf();
2966 let git_repo = Repo::from_path(&git_dir)?;
2967
2968 // get_path() should still return the worktree working directory
2969 assert_eq!(
2970 git_repo.get_path()?.canonicalize()?,
2971 worktree_repo.dir.canonicalize()?,
2972 );
2973 Ok(())
2974 }
2975 }
2851} 2976}