// Copyright (c) 2020 Teddy Wing
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
#![warn(rust_2018_idioms)]
use std::env;
use std::process;
use getopts::Options;
use git2::Repository;
use git_todo::Todos;
fn main() {
let args: Vec = env::args().collect();
let mut opts = Options::new();
opts.optflag("h", "help", "print this help menu");
opts.optflag("V", "version", "show the program version");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(e) => {
eprintln(&e);
process::exit(exitcode::NOINPUT);
},
};
if matches.opt_present("h") {
print_usage(&opts);
process::exit(exitcode::USAGE);
}
if matches.opt_present("V") {
println!("{}", env!("CARGO_PKG_VERSION"));
process::exit(exitcode::OK);
}
let repo = match Repository::open_from_env() {
Ok(r) => r,
Err(e) => {
eprintln(&format!("unable to open repository: {}", e));
process::exit(exitcode::NOINPUT);
},
};
let todos = Todos { repo: &repo };
let tree = if matches.free.is_empty() {
match todos.master_tree() {
Ok(t) => t,
Err(e) => {
eprintln(&e);
process::exit(exitcode::USAGE);
},
}
} else if matches.free.len() > 1 {
eprintln(&"too many ref arguments");
process::exit(exitcode::USAGE);
} else {
let refname = &matches.free[0];
let object = match repo.revparse_single(&refname) {
Ok(object) => object,
Err(e) => {
eprintln(&e);
process::exit(exitcode::USAGE);
},
};
match object.peel_to_tree() {
Ok(t) => t,
Err(e) => {
eprintln(&e);
process::exit(exitcode::USAGE);
},
}
};
match todos.write_since(tree, &mut std::io::stdout()) {
Err(e) => {
eprintln(&e);
process::exit(exitcode::UNAVAILABLE);
},
_ => (),
};
}
/// Print command line usage.
fn print_usage(opts: &Options) {
let brief = "usage: git todo []";
print!("{}", opts.usage(&brief));
}
/// Print to standard error with a program-specific prefix.
fn eprintln(error: &D) {
eprintln!("error: {}", error);
}