From ae13cbecdbeca984e0d389732356c2785eab66d9 Mon Sep 17 00:00:00 2001 From: Max Audron Date: Tue, 7 Jun 2022 12:28:18 +0200 Subject: implement cloning of new repos --- src/local/sync.rs | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/local/sync.rs (limited to 'src/local/sync.rs') diff --git a/src/local/sync.rs b/src/local/sync.rs new file mode 100644 index 0000000..0ee1b59 --- /dev/null +++ b/src/local/sync.rs @@ -0,0 +1,115 @@ +use std::fmt::{Debug, Display}; + +use git2::{AnnotatedCommit, Branch, BranchType, Remote, Repository}; +use tracing::{debug, debug_span}; + +use super::{Repo, RepoError}; + +impl Repo { + /// Clone repos from forge and push new repos to forge + #[tracing::instrument(level = "trace")] + pub fn sync(&mut self) -> Result { + let repo_name = self.name.clone(); + + if self.repo.is_some() + && !self + .is_clean() + .map_err(|err| SyncResult::err(repo_name.clone(), err))? + { + return Ok(SyncResult::dirty(repo_name)); + }; + + if self.repo.is_some() && self.forge.is_some() { + Ok(SyncResult::no_changes(repo_name)) + } else if self.repo.is_some() { + // do push stuff + Ok(SyncResult::pushed(repo_name)) + } else if self.forge.is_some() { + let url = self + .forge + .as_ref() + .unwrap() + .ssh_clone_url + .as_ref() + .ok_or(SyncResult::err(self.name.clone(), RepoError::NoRemoteFound))?; + + let repo = self + .clone(&url) + .map_err(|err| SyncResult::err(repo_name.clone(), err))?; + + self.repo = Some(repo); + Ok(SyncResult::cloned(repo_name)) + } else { + Ok(SyncResult::no_changes(repo_name)) + } + } +} + +#[derive(Debug)] +pub enum SyncResult { + NoChanges { + name: String, + }, + Dirty { + name: String, + }, + Cloned { + name: String, + }, + Pushed { + name: String, + }, + Error { + name: String, + error: super::RepoError, + }, +} + +impl SyncResult { + pub fn err(name: String, error: super::RepoError) -> SyncResult { + SyncResult::Error { name, error } + } + + pub fn cloned(name: String) -> SyncResult { + SyncResult::Cloned { name } + } + + pub fn pushed(name: String) -> SyncResult { + SyncResult::Pushed { name } + } + + pub fn dirty(name: String) -> SyncResult { + SyncResult::Dirty { name } + } + + pub fn no_changes(name: String) -> SyncResult { + SyncResult::NoChanges { name } + } +} + +impl Display for SyncResult { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use ansi_term::Colour::{Blue, Green, Red, Yellow}; + + match self { + SyncResult::NoChanges { name } => { + f.write_fmt(format_args!("{} {}", Blue.paint("NOCHANGE"), name)) + } + SyncResult::Dirty { name } => { + f.write_fmt(format_args!("{} {}", Yellow.paint("DIRTY "), name)) + } + SyncResult::Cloned { name } => { + f.write_fmt(format_args!("{} {}", Green.paint("CLONED "), name)) + } + SyncResult::Pushed { name } => { + f.write_fmt(format_args!("{} {}", Green.paint("PUSHED "), name)) + } + SyncResult::Error { name, error } => f.write_fmt(format_args!( + "{} {} [{}]", + Red.paint("ERROR "), + name, + error + )), + } + } +} -- cgit v1.2.3