]>
Commit | Line | Data |
---|---|---|
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 | } |