use std::env; use std::io::Write; extern crate clap; use clap::{arg, command, Command}; extern crate flate2; mod get; use get::get; mod changelog; use changelog::generate_entry; use log::{info, error}; use indicatif_log_bridge::LogWrapper; mod ui; fn main() { let rt = tokio::runtime::Runtime::new().unwrap(); let logger = env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")) .format_timestamp(None) .format(|buf, record| { writeln!(buf, "{}", record.args()) }) .build(); let multi = indicatif::MultiProgress::new(); LogWrapper::new(multi.clone(), logger) .try_init() .unwrap(); let matches = command!() .subcommand_required(true) .disable_version_flag(true) .subcommand( Command::new("get") .about("Get a source package from the archive or git") .arg( arg!(-s --series "Target package distribution series") .required(false) ) .arg( arg!(-d --dist "Target package distribution (debian, ubuntu)") .required(false) ) .arg( arg!(-v --version "Target package version") .required(false) ) .arg( arg!(--ppa "Download the package from a specific PPA") .required(false) ) .arg(arg!( "Target package")) ) .subcommand( Command::new("chlog") .about("Auto-generate changelog entry, editing it, committing it afterwards") .arg(arg!(-s --series "Target distribution series").required(false)) .arg(arg!(--backport "This changelog is for a backport entry").required(false)) .arg(arg!(-v --version "Target version").required(false)) ) .get_matches(); match matches.subcommand() { Some(("get", sub_matches)) => { let package = sub_matches.get_one::("package").expect("required"); let series = sub_matches.get_one::("series").map(|s| s.as_str()); let dist = sub_matches.get_one::("dist").map(|s| s.as_str()); let version = sub_matches.get_one::("version").map(|s| s.as_str()).unwrap_or(""); let ppa = sub_matches.get_one::("ppa").map(|s| s.as_str()).unwrap_or(""); // Since get is async, we need to block on it let (pb, mut progress_callback) = ui::create_progress_bar(&multi); if let Err(e) = rt.block_on(get(package, version, series, "", ppa, dist, None, Some(&mut progress_callback))) { pb.finish_and_clear(); error!("{}", e); std::process::exit(1); } pb.finish_and_clear(); multi.remove(&pb); info!("Done."); }, Some(("chlog", sub_matches)) => { let cwd = std::env::current_dir().unwrap(); let version = sub_matches.get_one::("version").map(|s| s.as_str()); if let Err(e) = generate_entry("debian/changelog", Some(&cwd), version) { error!("{}", e); std::process::exit(1); } let editor = std::env::var("EDITOR").unwrap(); let _status = std::process::Command::new(editor) .current_dir(&cwd) .args(&["debian/changelog"]) .status(); }, _ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"), } }