From a82546b70303000b4fc053a1ee21d3d8c7d6ad66 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Fri, 28 Jun 2024 15:16:43 +0100 Subject: feat(login): login with nip46 remote signer and save details in git config --- src/git.rs | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 12 deletions(-) (limited to 'src/git.rs') diff --git a/src/git.rs b/src/git.rs index 46687ae..bb943a9 100644 --- a/src/git.rs +++ b/src/git.rs @@ -76,8 +76,9 @@ pub trait RepoActions { ) -> Result>; fn parse_starting_commits(&self, starting_commits: &str) -> Result>; fn ancestor_of(&self, decendant: &Sha1Hash, ancestor: &Sha1Hash) -> Result; - fn get_git_config_item(&self, item: &str, global: bool) -> Result>; + fn get_git_config_item(&self, item: &str, global: Option) -> Result>; fn save_git_config_item(&self, item: &str, value: &str, global: bool) -> Result<()>; + fn remove_git_config_item(&self, item: &str, global: bool) -> Result; } impl RepoActions for Repo { @@ -581,8 +582,15 @@ impl RepoActions for Repo { } } - fn get_git_config_item(&self, item: &str, global: bool) -> Result> { - match if global { + /// setting global to None will suppliment local config with global items + /// not in local + fn get_git_config_item(&self, item: &str, global: Option) -> Result> { + let just_global = if let Some(just_global) = global { + just_global + } else { + false + }; + match if just_global { self.git_repo .config() .context("cannot open git config")? @@ -593,11 +601,22 @@ impl RepoActions for Repo { } .get_entry(item) { - Ok(item) => Ok(Some( - item.value() - .context("cannot find git config item")? - .to_string(), - )), + Ok(item) => { + if let Some(global) = global { + if item.level().eq(&git2::ConfigLevel::Local) { + if global { + bail!("only local repository login available") + } + } else if !global { + bail!("only global repository login available") + } + } + Ok(Some( + item.value() + .context("cannot find git config item")? + .to_string(), + )) + } Err(_) => Ok(None), } } @@ -613,9 +632,33 @@ impl RepoActions for Repo { self.git_repo.config().context("cannot open git config")? } .set_str(item, value) - .context("cannot set git config value")?; + .context(format!( + "cannot set {} git config item {}", + if global { "global" } else { "local" }, + item + ))?; Ok(()) } + + /// returns false if item doesn't exist + fn remove_git_config_item(&self, item: &str, global: bool) -> Result { + if self.get_git_config_item(item, Some(global))?.is_none() { + Ok(false) + } else { + if global { + self.git_repo + .config() + .context("cannot open git config")? + .open_global() + .context("cannot open global git config")? + } else { + self.git_repo.config().context("cannot open git config")? + } + .remove(item) + .context("cannot remove existing git config item")?; + Ok(true) + } + } } fn oid_to_u8_20_bytes(oid: &Oid) -> [u8; 20] { @@ -849,7 +892,9 @@ mod tests { let git_repo = Repo::from_path(&test_repo.dir)?; git_repo.save_git_config_item("test.item", "testvalue", false)?; assert_eq!( - git_repo.get_git_config_item("test.item", false)?.unwrap(), + git_repo + .get_git_config_item("test.item", Some(false))? + .unwrap(), "testvalue", ); Ok(()) @@ -859,7 +904,10 @@ mod tests { fn get_git_config_item_returns_none_if_not_present() -> Result<()> { let test_repo = GitTestRepo::default(); let git_repo = Repo::from_path(&test_repo.dir)?; - assert_eq!(git_repo.get_git_config_item("test.item", false)?, None); + assert_eq!( + git_repo.get_git_config_item("test.item", Some(false))?, + None + ); Ok(()) } @@ -869,11 +917,32 @@ mod tests { let git_repo = Repo::from_path(&test_repo.dir)?; git_repo.save_git_config_item("test.item", "", false)?; assert_eq!( - git_repo.get_git_config_item("test.item", false)?, + git_repo.get_git_config_item("test.item", Some(false))?, Some("".to_string()), ); Ok(()) } + + #[test] + fn remove_local_git_config_item() -> Result<()> { + let test_repo = GitTestRepo::default(); + let git_repo = Repo::from_path(&test_repo.dir)?; + git_repo.save_git_config_item("test.item", "testvalue", false)?; + assert!(git_repo.remove_git_config_item("test.item", false)?); + assert_eq!( + git_repo.get_git_config_item("test.item", Some(false))?, + None, + ); + Ok(()) + } + + #[test] + fn remove_git_config_item_returns_false_if_item_wasnt_set() -> Result<()> { + let test_repo = GitTestRepo::default(); + let git_repo = Repo::from_path(&test_repo.dir)?; + assert!(!(git_repo.remove_git_config_item("test.item", false)?)); + Ok(()) + } } #[test] -- cgit v1.2.3