diff options
| author | Bond_009 <bond.009@outlook.com> | 2020-11-14 23:19:47 +0100 |
|---|---|---|
| committer | Bond_009 <bond.009@outlook.com> | 2020-11-14 23:19:47 +0100 |
| commit | c45490ed54bcc1e42f2a723234e7baf12de55c32 (patch) | |
| tree | c5452e556a4239bc482c0c897534733841b6ebba /src/main.rs | |
First
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..42f37dc --- /dev/null +++ b/src/main.rs @@ -0,0 +1,131 @@ +mod config; + +use std::{ + env, + fs::File, + io::Read, + path::{Path, PathBuf}, +}; + +use clap::*; +use git2::{build::CheckoutBuilder, AutotagOption, Direction, FetchOptions, Repository}; + +use config::*; + +fn main() { + let matches = App::new(crate_name!()) + .version(crate_version!()) + .author(crate_authors!()) + .about(crate_description!()) + .subcommand(SubCommand::with_name("init")) + .subcommand(SubCommand::with_name("update")) + .get_matches(); + + if matches.subcommand_matches("init").is_some() { + init(); + } else if matches.subcommand_matches("update").is_some() { + update(); + } +} + +fn get_config() -> Config { + let config_path = match env::var("GIT_MIRROR_CONFIG") { + Ok(c) => c, + _ => panic!("GIT_MIRROR_CONFIG isn't set."), + }; + + let mut config_file = match File::open(Path::new(&config_path)) { + Ok(c) => c, + _ => panic!("Error opening config file."), + }; + + let mut buf = String::new(); + if config_file.read_to_string(&mut buf).is_err() { + panic!("Error reading config file.") + } + + let config: Config = match toml::from_str(&buf) { + Ok(c) => c, + Err(e) => panic!("Error parsing config file. {}", e), + }; + + config +} + +fn init() { + let config = get_config(); + + let projects = match config.projects { + Some(p) => p, + _ => return, + }; + + for project in projects { + let mut path = PathBuf::new(); + path.push(Path::new( + project.path.as_ref().unwrap_or(&config.default_path), + )); + path.push(project.name); + if path.exists() { + println!("{:#?} already exists, skipping.", path); + continue; + } + + let _repo = match Repository::clone(&project.url, path) { + Ok(r) => r, + Err(e) => { + eprintln!("{}", e); + continue; + } + }; + } +} + +fn update() { + let config = get_config(); + + let projects = match config.projects { + Some(p) => p, + _ => return, + }; + + for project in projects { + let mut path = PathBuf::new(); + path.push(Path::new( + project.path.as_ref().unwrap_or(&config.default_path), + )); + path.push(project.name); + if !path.exists() { + println!("{:#?} doesn't exist, skipping.", &path); + continue; + } + + let repo = match Repository::open(&path) { + Ok(r) => r, + Err(e) => { + eprintln!("{}", e); + continue; + } + }; + + let mut fo = FetchOptions::new(); + fo.download_tags(AutotagOption::All); + let mut remote = repo.find_remote("origin").unwrap(); + remote.connect(Direction::Fetch).unwrap(); + let branch_buf = remote.default_branch().unwrap(); + let branch = branch_buf.as_str().unwrap(); + if remote.fetch(&[branch], Some(&mut fo), None).is_err() { + eprintln!("Failed fetching branch {} for {:#?}", branch, &path); + continue; + } + + let fetch_head = repo.find_reference("FETCH_HEAD").unwrap(); + let com = repo.reference_to_annotated_commit(&fetch_head).unwrap(); + + let mut branch_ref = repo.find_reference(&branch).unwrap(); + branch_ref.set_target(com.id(), "IDK").unwrap(); + repo.set_head(&branch).unwrap(); + repo.checkout_head(Some(CheckoutBuilder::default().force())) + .unwrap(); + } +} |
