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 )), } } }