aboutsummaryrefslogtreecommitdiff
path: root/src/local/sync.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/local/sync.rs')
-rw-r--r--src/local/sync.rs115
1 files changed, 115 insertions, 0 deletions
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<SyncResult, SyncResult> {
+ 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
+ )),
+ }
+ }
+}