src: switch to clap for argument parsing

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2020-10-24 14:00:16 +05:30
parent 9e4abab5d2
commit a00d16fc8d
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80

View file

@ -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 <command> <dir>\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();
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)),
}
};
// 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 <command> <dir>\n");
Ok(())
}
}
}
fn freeze_repos(dir: String) -> anyhow::Result<()> {
fn freeze_repos(dir: &str) -> anyhow::Result<()> {
let mut repos: HashMap<String, PersistableRepo> = 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<String, PersistableRepo> = toml::from_str(&lockfile)?;
for (name, repo) in repos {
println!("Cloning {} from {}", &name, &repo.remote_url);
let output = Command::new("git")
.args(&[
"clone",