From a00d16fc8d23cf6e02a06b61557a71a648b62ff0 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Sat, 24 Oct 2020 14:00:16 +0530 Subject: [PATCH] src: switch to clap for argument parsing Signed-off-by: Harsh Shandilya --- src/main.rs | 70 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/src/main.rs b/src/main.rs index 523a7ec..a96d4b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +use anyhow::anyhow; +use clap::{crate_version, App, AppSettings, Arg}; use git2::Repository; use serde::{Deserialize, Serialize}; use std::{ @@ -15,26 +17,54 @@ struct PersistableRepo { } fn main() -> anyhow::Result<()> { - let dir = match std::env::args().nth(2) { - Some(d) => d, - None => { - println!("Usage:\n gitice \n"); - return Ok(()); - } - }; + let matches = App::new("hcctl") + .about("Command-line tool for backing up and restoring multiple Git repositories from a directory") + .version(crate_version!()) + .setting(AppSettings::ColoredHelp) + .setting(AppSettings::DeriveDisplayOrder) + .setting(AppSettings::SubcommandRequiredElseHelp) + .subcommand( + App::new("freeze") + .about("Generate a gitice.lock file with all the repositories in the given directory") + .args(&[Arg::with_name("directory") + .help("Directory to look for Git repos in") + .required(true) + .index(1)]), + ) + .subcommand( + App::new("thaw") + .about("Given a gitice.lock and a directory, clones back all the repositories from the lockfile in the directory") + .args(&[ + Arg::with_name("directory") + .help("Directory to restore repositories in") + .required(true) + .index(1), + Arg::with_name("lockfile") + .help("The lockfile to restore repositories from") + .short("l") + .long("lockfile") + .required(false) + .default_value("gitice.lock") + ]), + ) + .get_matches(); - // temporary solution to support both freezing and thawing - match std::env::args().nth(1).as_ref().map(|s| &s[..]) { - Some("freeze") => freeze_repos(dir), - Some("thaw") => thaw_repos(dir), - _ => { - println!("Usage:\n gitice \n"); - Ok(()) + match matches.subcommand() { + ("freeze", m) => freeze_repos(m.unwrap().value_of("directory").unwrap())?, + ("thaw", m) => { + let m = m.unwrap(); + thaw_repos( + m.value_of("directory").unwrap(), + m.value_of("lockfile").unwrap(), + )? } + (cmd, _) => return Err(anyhow!("unknown subcommand: {}", cmd)), } + + Ok(()) } -fn freeze_repos(dir: String) -> anyhow::Result<()> { +fn freeze_repos(dir: &str) -> anyhow::Result<()> { let mut repos: HashMap = HashMap::new(); for entry in WalkDir::new(dir.clone()).into_iter().filter_map(|e| e.ok()) { if entry.file_type().is_dir() { @@ -75,14 +105,20 @@ fn freeze_repos(dir: String) -> anyhow::Result<()> { }; } fs::write("gitice.lock", toml::to_string(&repos)?).expect("could not write to lockfile!"); + println!( + "Successfully generated lockfile with {} repos", + &repos.len() + ); Ok(()) } -fn thaw_repos(dir: String) -> anyhow::Result<()> { - let lockfile = fs::read_to_string("gitice.lock").expect("unable to read lockfile!"); +fn thaw_repos(dir: &str, lockfile: &str) -> anyhow::Result<()> { + let lockfile = + fs::read_to_string(lockfile).expect(&format!("unable to read lockfile from {}", lockfile)); let repos: HashMap = toml::from_str(&lockfile)?; for (name, repo) in repos { + println!("Cloning {} from {}", &name, &repo.remote_url); let output = Command::new("git") .args(&[ "clone",