From bca1d20e8337280906026a28f2f1bb3a10652ca4 Mon Sep 17 00:00:00 2001 From: Bryson Steck Date: Sun, 16 Mar 2025 16:01:20 -0600 Subject: [PATCH] config now runs error, ssh refactor --- src/common.rs | 4 ++- src/main.rs | 9 ++++--- src/refractr.rs | 70 +++++++++++++++++++++++++++---------------------- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/common.rs b/src/common.rs index 85b6f0a..aef15f4 100644 --- a/src/common.rs +++ b/src/common.rs @@ -5,7 +5,9 @@ pub enum ExitCode { FilesystemError = 3, RepositoryError = 4, RemoteError = 5, - PushError = 6 + PushError = 6, + FetchError = 7, + ConfigError = 8 } pub struct ReturnData { diff --git a/src/main.rs b/src/main.rs index 99f9b5c..d141f2c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,10 +90,12 @@ fn main() -> Result<(), String> { return Ok(()) } - let cfgs = match config::read_config(args.config, &refractr) { - Ok(cfgs) => cfgs, - Err(e) => return Err(e) + let mut cfgs = vec![]; + match config::read_config(args.config, &refractr) { + Ok(c) => cfgs = c, + Err(e) => common::error(format!("{}", e), common::ExitCode::ConfigError) }; + if refractr.verbose >= 2 { // no need to loop over configs if verbose is not at the correct level for i in &cfgs { @@ -108,5 +110,4 @@ fn main() -> Result<(), String> { }; Ok(()) - } diff --git a/src/refractr.rs b/src/refractr.rs index 3266580..bc24b23 100644 --- a/src/refractr.rs +++ b/src/refractr.rs @@ -60,35 +60,33 @@ impl Refractr { Ok(()) } - fn fetch(&self, repo: &Repository, branches: &Vec, ssh: Option<&String>) -> Result<(), Error> { - match ssh { - Some(key) => { - let mut cb = RemoteCallbacks::new(); - let mut fo = FetchOptions::new(); - cb.credentials(move |_,_,_| Cred::ssh_key( - "git", - None, - Path::new(&key), - None)); - cb.certificate_check(|cert, url| { - let mut sha256 = String::new(); - for i in cert.as_hostkey().unwrap().hash_sha256().unwrap().to_vec() { - sha256.push_str(&hex::encode(i.to_string())); - } - common::warning( - format!("implicitly trusting unknown host {} with sha256 host key {}", - url, - hex::encode(cert.as_hostkey().unwrap().hash_sha256().unwrap().to_vec()))); - common::warning( - format!("to ignore this error in the future, add this host to your known_hosts file")); - Ok(CertificateCheckStatus::CertificateOk) - }); - fo.download_tags(git2::AutotagOption::All); - fo.remote_callbacks(cb); - repo.find_remote("origin")?.fetch(&branches, Some(&mut fo), None)?; - }, - None => repo.find_remote("origin")?.fetch(&branches, None, None)? - }; + fn fetch(&self, repo: &Repository, branches: &Vec, ssh: bool, ssh_key: &String) -> Result<(), Error> { + let mut cb = RemoteCallbacks::new(); + let mut fo = FetchOptions::new(); + if ssh { + let key_string: String = ssh_key.clone(); + cb.credentials(move |_,_,_| Cred::ssh_key( + "git", + None, + Path::new(&key_string), + None)); + cb.certificate_check(|cert, url| { + let mut sha256 = String::new(); + for i in cert.as_hostkey().unwrap().hash_sha256().unwrap().to_vec() { + sha256.push_str(&hex::encode(i.to_string())); + } + common::warning( + format!("implicitly trusting unknown host {} with sha256 host key {}", + url, + hex::encode(cert.as_hostkey().unwrap().hash_sha256().unwrap().to_vec()))); + common::warning( + format!("to ignore this error in the future, add this host to your known_hosts file")); + Ok(CertificateCheckStatus::CertificateOk) + }); + } + fo.download_tags(git2::AutotagOption::All); + fo.remote_callbacks(cb); + repo.find_remote("origin")?.fetch(&branches, Some(&mut fo), None)?; Ok(()) } @@ -273,12 +271,13 @@ impl Refractr { }) }; + let ssh = cfg.config.from.starts_with("ssh://"); let mut builder = RepoBuilder::new(); let mut cb = RemoteCallbacks::new(); let mut fo = FetchOptions::new(); // make initial clone - if cfg.config.from.starts_with("ssh://") { + if ssh { let key_string = cfg.config.git.ssh_identity_file.clone(); cb.credentials(move |_,_,_| Cred::ssh_key( "git", @@ -311,7 +310,9 @@ impl Refractr { let repo = match builder.clone(&cfg.config.from, Path::new(&repo_dir)) { Ok(repo) => repo, Err(e) => { - println!("{}", e); + if e.code() != ErrorCode::Exists { + common::error(format!("failed to clone repo to {}: {}", repo_dir, e), ExitCode::FilesystemError); + } common::warning(format!("found existing repo at {}, attempting to use", repo_dir)); match self.fast_forward(&repo_dir, &cfg.config.branches) { Ok(_) => if let Ok(repo) = Repository::open(Path::new(&repo_dir)) { @@ -331,7 +332,12 @@ impl Refractr { }; self.set_up_refs(&repo, &cfg.config.branches).unwrap(); - self.fetch(&repo, &cfg.config.branches, Some(&cfg.config.git.ssh_identity_file)).unwrap(); + if let Err(e) = self.fetch(&repo, + &cfg.config.branches, + ssh, + &cfg.config.git.ssh_identity_file) { + common::error(format!("failed to fetch repo {}: {}", cfg.config.from, e), ExitCode::FetchError); + } let remotes = match self.make_remotes(&repo, &cfg) { Ok(v) => v,