aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..3b9caea
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,91 @@
+mod git_tools;
+
+use std::env;
+use std::fs;
+use std::io::{Result, Error, ErrorKind};
+use std::path::Path;
+use std::process::exit;
+
+use git_tools::*;
+
+fn main() -> Result<()> {
+ if let Ok(cwd) = env::current_dir() {
+ if let Err(e) = scan_directories_to_synchronize(&cwd) {
+ eprintln!("Could not check directory for git repositories: {}", e);
+ exit(1);
+ }
+ } else {
+ eprintln!("Could not find current directory.");
+ exit(1);
+ }
+ Ok(())
+}
+
+fn scan_directories_to_synchronize(path: &Path) -> Result<()> {
+ let sync_ignore_file = path.join(".syncignore");
+ if sync_ignore_file.exists() {
+ return Ok(())
+ }
+ let git_directory = path.join(".git");
+ if git_directory.exists() {
+ if let Err(e) = synchronize_directory(&path) {
+ let relative_path = get_relative_path(path).unwrap();
+ eprintln!("Sync failed for {:?}. {}", relative_path, e);
+ }
+ } else {
+ for entry in fs::read_dir(path)? {
+ let path = entry?.path();
+ if path.is_dir() {
+ scan_directories_to_synchronize(&path)?;
+ }
+ }
+ }
+ Ok(())
+}
+
+fn synchronize_directory(path: &Path) -> Result<()> {
+ let previous_branch = git_save_previous_branch(path)?;
+ git_checkout(path, "main")?;
+ let result = attempt_synchronization(path);
+ git_checkout(path, &previous_branch)?;
+ result
+}
+
+fn attempt_synchronization(path: &Path) -> Result<()> {
+ let relative_path = get_relative_path(path).unwrap();
+ eprint!("{:?}. ", relative_path);
+ let previous_commit = get_commit(path, "HEAD")?;
+ git_fetch(path)?;
+ let remote_commit = get_commit(path, "origin/main")?;
+ if previous_commit == remote_commit {
+ eprintln!("Already up to date.");
+ return Ok(());
+ }
+ match git_check_for_conflicts(path) {
+ Ok(conflicts) => {
+ if !conflicts {
+ git_merge(path)?;
+ let new_commit = get_commit(path, "HEAD")?;
+ eprint!("Merged origin {:?}->{:?}. ", previous_commit, new_commit);
+ git_push(path)?;
+ eprintln!("Pushed.");
+ } else {
+ return Err(Error::new(ErrorKind::Other, "Conflicts detected"));
+ }
+ },
+ Err(e) => {
+ return Err(e);
+ }
+ }
+ Ok(())
+}
+
+// Path Helpers
+
+fn get_relative_path(path: &Path) -> Option<String> {
+ let cwd = env::current_dir().unwrap();
+ path.strip_prefix(cwd)
+ .ok()
+ .and_then(|p| p.to_str())
+ .map(|s| s.to_string())
+}