use clap::Parser;
use ingredients::{Crate, ReportOptions};
#[derive(Debug, clap::Parser)]
#[command(disable_help_subcommand(true))]
struct Args {
#[command(subcommand)]
command: Command,
}
#[derive(Debug, clap::Args)]
struct ReportArgs {
name: String,
version: String,
#[clap(long)]
json: bool,
#[clap(long, short = 'v')]
verbose: bool,
#[clap(long, short = 'f')]
file: Option<String>,
#[clap(long, short = 'u')]
with_repository: Option<String>,
#[clap(long, short = 'p')]
with_path_in_vcs: Option<String>,
#[clap(long, short = 'r')]
with_vcs_ref: Option<String>,
}
#[derive(Debug, clap::Args)]
struct DiffArgs {
name: String,
old_version: String,
new_version: String,
#[clap(long)]
json: bool,
#[clap(long, short = 'v')]
verbose: bool,
#[clap(long)]
old_file: Option<String>,
#[clap(long)]
new_file: Option<String>,
}
#[derive(Debug, clap::Subcommand)]
enum Command {
Report(ReportArgs),
Diff(DiffArgs),
}
#[allow(clippy::print_stdout)]
async fn report(args: ReportArgs) -> anyhow::Result<()> {
let mut options = ReportOptions::default();
options.repository = args.with_repository;
options.path_in_vcs = args.with_path_in_vcs;
options.vcs_ref = args.with_vcs_ref;
let krate = if let Some(path) = args.file {
Crate::local(&args.name, &args.version, &path)?
} else {
Crate::download(&args.name, &args.version).await?
};
let report = if options.is_empty() {
krate.report().await?
} else {
krate.report_with_options(options).await?
};
if args.json {
println!("{}", report.to_json());
} else if args.verbose {
println!("{report:#}");
} else {
println!("{report}");
}
Ok(())
}
#[allow(clippy::print_stdout)]
async fn diff(args: DiffArgs) -> anyhow::Result<()> {
let old_crate = if let Some(old_file) = args.old_file {
Crate::local(&args.name, &args.old_version, &old_file)?
} else {
Crate::download(&args.name, &args.old_version).await?
};
let new_crate = if let Some(new_file) = args.new_file {
Crate::local(&args.name, &args.new_version, &new_file)?
} else {
Crate::download(&args.name, &args.new_version).await?
};
let diff = old_crate.diff(&new_crate)?;
if args.json {
println!("{}", diff.to_json());
} else if args.verbose {
println!("{diff:#}");
} else {
println!("{diff}");
}
Ok(())
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
env_logger::init_from_env("INGREDIENTS_LOG");
let args = Args::parse();
match args.command {
Command::Report(args) => report(args).await?,
Command::Diff(args) => diff(args).await?,
}
Ok(())
}