use std::error::Error;
use clap::Parser;
use env_logger::Target;
use log::warn;
use protofetch::{LockMode, Protofetch};
#[derive(Debug, Parser)]
#[clap(version)]
pub struct CliArgs {
#[clap(subcommand)]
pub cmd: Command,
#[clap(short, long, default_value = "protofetch.toml")]
pub module_location: String,
#[clap(short, long, default_value = "protofetch.lock")]
pub lockfile_location: String,
#[clap(short, long)]
pub cache_directory: Option<String>,
#[clap(short, long)]
pub output_proto_directory: Option<String>,
#[clap(long)]
pub jobs: Option<usize>,
#[clap(long)]
pub copy_jobs: Option<usize>,
}
#[derive(Debug, Parser)]
pub enum Command {
Fetch {
#[clap(long)]
locked: bool,
#[clap(short, long, hide(true))]
force_lock: bool,
},
Lock,
Update,
Init {
#[clap(default_value = ".")]
directory: String,
#[clap(short, long)]
name: Option<String>,
},
Migrate {
#[clap(default_value = ".")]
directory: String,
#[clap(short, long)]
name: Option<String>,
},
Clean,
ClearCache,
}
fn main() {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
.target(Target::Stdout)
.format(move |buf, record| {
use std::io::Write;
let at_least_debug_log = log::log_enabled!(log::Level::Debug);
let level = record.level();
let style = buf.default_level_style(level);
write!(buf, "{style}{}{style:#}", level)?;
if at_least_debug_log {
write!(
buf,
" [{}:{}]",
record.file().unwrap_or("unknown"),
record.line().unwrap_or(0),
)?;
}
writeln!(buf, " {}", record.args())
})
.init();
if let Err(e) = run() {
log::error!("{}", e);
std::process::exit(1);
}
}
fn run() -> Result<(), Box<dyn Error>> {
let cli_args: CliArgs = CliArgs::parse();
let mut protofetch = Protofetch::builder()
.module_file_name(&cli_args.module_location)
.lock_file_name(&cli_args.lockfile_location);
if let Some(output_directory_name) = &cli_args.output_proto_directory {
protofetch = protofetch.output_directory_name(output_directory_name)
}
if let Some(cache_directory) = &cli_args.cache_directory {
protofetch = protofetch.cache_directory(cache_directory);
}
if let Some(jobs) = cli_args.jobs {
if jobs == 0 {
return Err("--jobs must be at least 1".into());
}
protofetch = protofetch.jobs(jobs);
}
if let Some(copy_jobs) = cli_args.copy_jobs {
if copy_jobs == 0 {
return Err("--copy-jobs must be at least 1".into());
}
protofetch = protofetch.copy_jobs(copy_jobs);
}
match cli_args.cmd {
Command::Fetch { locked, force_lock } => {
let lock_mode = if force_lock {
warn!("Specifying --force-lock is deprecated, please use \"protofetch update\" instead.");
LockMode::Recreate
} else if locked {
LockMode::Locked
} else {
LockMode::Update
};
protofetch.try_build()?.fetch(lock_mode)
}
Command::Lock => protofetch.try_build()?.lock(LockMode::Update),
Command::Update => protofetch.try_build()?.lock(LockMode::Recreate),
Command::Init { directory, name } => protofetch.root(directory).try_build()?.init(name),
Command::Migrate { directory, name } => protofetch
.root(&directory)
.try_build()?
.migrate(name, directory),
Command::Clean => protofetch.try_build()?.clean(),
Command::ClearCache => protofetch.try_build()?.clear_cache(),
}
}