]> git.r.bdr.sh - rbdr/git-sync-all/blob - src/main.rs
3b9caea0eaf23a21d71cad15cac939594176bfa2
[rbdr/git-sync-all] / src / main.rs
1 mod git_tools;
2
3 use std::env;
4 use std::fs;
5 use std::io::{Result, Error, ErrorKind};
6 use std::path::Path;
7 use std::process::exit;
8
9 use git_tools::*;
10
11 fn main() -> Result<()> {
12 if let Ok(cwd) = env::current_dir() {
13 if let Err(e) = scan_directories_to_synchronize(&cwd) {
14 eprintln!("Could not check directory for git repositories: {}", e);
15 exit(1);
16 }
17 } else {
18 eprintln!("Could not find current directory.");
19 exit(1);
20 }
21 Ok(())
22 }
23
24 fn scan_directories_to_synchronize(path: &Path) -> Result<()> {
25 let sync_ignore_file = path.join(".syncignore");
26 if sync_ignore_file.exists() {
27 return Ok(())
28 }
29 let git_directory = path.join(".git");
30 if git_directory.exists() {
31 if let Err(e) = synchronize_directory(&path) {
32 let relative_path = get_relative_path(path).unwrap();
33 eprintln!("Sync failed for {:?}. {}", relative_path, e);
34 }
35 } else {
36 for entry in fs::read_dir(path)? {
37 let path = entry?.path();
38 if path.is_dir() {
39 scan_directories_to_synchronize(&path)?;
40 }
41 }
42 }
43 Ok(())
44 }
45
46 fn synchronize_directory(path: &Path) -> Result<()> {
47 let previous_branch = git_save_previous_branch(path)?;
48 git_checkout(path, "main")?;
49 let result = attempt_synchronization(path);
50 git_checkout(path, &previous_branch)?;
51 result
52 }
53
54 fn attempt_synchronization(path: &Path) -> Result<()> {
55 let relative_path = get_relative_path(path).unwrap();
56 eprint!("{:?}. ", relative_path);
57 let previous_commit = get_commit(path, "HEAD")?;
58 git_fetch(path)?;
59 let remote_commit = get_commit(path, "origin/main")?;
60 if previous_commit == remote_commit {
61 eprintln!("Already up to date.");
62 return Ok(());
63 }
64 match git_check_for_conflicts(path) {
65 Ok(conflicts) => {
66 if !conflicts {
67 git_merge(path)?;
68 let new_commit = get_commit(path, "HEAD")?;
69 eprint!("Merged origin {:?}->{:?}. ", previous_commit, new_commit);
70 git_push(path)?;
71 eprintln!("Pushed.");
72 } else {
73 return Err(Error::new(ErrorKind::Other, "Conflicts detected"));
74 }
75 },
76 Err(e) => {
77 return Err(e);
78 }
79 }
80 Ok(())
81 }
82
83 // Path Helpers
84
85 fn get_relative_path(path: &Path) -> Option<String> {
86 let cwd = env::current_dir().unwrap();
87 path.strip_prefix(cwd)
88 .ok()
89 .and_then(|p| p.to_str())
90 .map(|s| s.to_string())
91 }