Merge pull request #8 from msfjarvis/switch-to-clap

This commit is contained in:
Harsh Shandilya 2020-10-24 14:20:15 +05:30 committed by GitHub
commit fa7fea0df4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,3 +1,5 @@
use anyhow::anyhow;
use clap::{crate_version, App, AppSettings, Arg};
use git2::Repository; use git2::Repository;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ use std::{
@ -15,28 +17,56 @@ struct PersistableRepo {
} }
fn main() -> anyhow::Result<()> { fn main() -> anyhow::Result<()> {
let dir = match std::env::args().nth(2) { let matches = App::new("gitice")
Some(d) => d, .about("Command-line tool for backing up and restoring multiple Git repositories from a directory")
None => { .version(crate_version!())
println!("Usage:\n gitice <command> <dir>\n"); .setting(AppSettings::ColoredHelp)
return Ok(()); .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 matches.subcommand() {
match std::env::args().nth(1).as_ref().map(|s| &s[..]) { ("freeze", m) => freeze_repos(m.unwrap().value_of("directory").unwrap())?,
Some("freeze") => freeze_repos(dir), ("thaw", m) => {
Some("thaw") => thaw_repos(dir), let m = m.unwrap();
_ => { thaw_repos(
println!("Usage:\n gitice <command> <dir>\n"); m.value_of("directory").unwrap(),
Ok(()) 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<String, PersistableRepo> = HashMap::new(); let mut repos: HashMap<String, PersistableRepo> = HashMap::new();
for entry in WalkDir::new(dir.clone()).into_iter().filter_map(|e| e.ok()) { for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) {
if entry.file_type().is_dir() { if entry.file_type().is_dir() {
let path = format!("{}/.git", entry.path().display()); let path = format!("{}/.git", entry.path().display());
let git_dir = Path::new(&path); let git_dir = Path::new(&path);
@ -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!"); fs::write("gitice.lock", toml::to_string(&repos)?).expect("could not write to lockfile!");
println!(
"Successfully generated lockfile with {} repos",
&repos.len()
);
Ok(()) Ok(())
} }
fn thaw_repos(dir: String) -> anyhow::Result<()> { fn thaw_repos(dir: &str, lockfile: &str) -> anyhow::Result<()> {
let lockfile = fs::read_to_string("gitice.lock").expect("unable to read lockfile!"); let lockfile = fs::read_to_string(lockfile)
.unwrap_or_else(|_| panic!("unable to read lockfile from {}", lockfile));
let repos: HashMap<String, PersistableRepo> = toml::from_str(&lockfile)?; let repos: HashMap<String, PersistableRepo> = toml::from_str(&lockfile)?;
for (name, repo) in repos { for (name, repo) in repos {
println!("Cloning {} from {}", &name, &repo.remote_url);
let output = Command::new("git") let output = Command::new("git")
.args(&[ .args(&[
"clone", "clone",