use clap::{ArgAction, Parser};
use crossterm::style::Stylize;
use scoop_rs::{operation, QueryOption, Session};
use crate::Result;
#[derive(Debug, Parser)]
pub struct Args {
#[arg(action = ArgAction::Append)]
query: Vec<String>,
#[arg(short = 'e', long, action = ArgAction::SetTrue)]
explicit: bool,
#[arg(short = 'u', long, action = ArgAction::SetTrue)]
upgradable: bool,
#[arg(short = 'H', long, action = ArgAction::SetTrue)]
held: bool,
}
pub fn execute(args: Args, session: &Session) -> Result<()> {
let queries = args.query.iter().map(|s| s.as_str()).collect::<Vec<_>>();
let mut options = vec![];
if args.explicit {
options.push(QueryOption::Explicit);
}
if args.upgradable {
options.push(QueryOption::Upgradable);
}
match operation::package_query(session, queries, options, true) {
Err(e) => Err(e.into()),
Ok(packages) => {
let mut packages = packages;
let stale = if args.upgradable {
operation::stale_nightlies(session).unwrap_or_default()
} else {
Vec::new()
};
if !stale.is_empty() {
let names: Vec<&str> = stale.iter().map(String::as_str).collect();
if let Ok(extra) = operation::package_query(session, names, vec![], true) {
for pkg in extra {
if !packages.iter().any(|p| p.name() == pkg.name()) {
packages.push(pkg);
}
}
packages.sort_by_key(|p| p.name().to_owned());
}
}
for pkg in packages {
let mut output = String::new();
output.push_str(
format!("{}/{} {}", pkg.name(), pkg.bucket().green(), pkg.version()).as_str(),
);
let held = pkg.is_held();
if args.held && !held {
continue;
}
let upgradable = pkg.upgradable_version();
if args.upgradable {
if let Some(version) = upgradable {
output.push_str(format!(" -> {}", version.blue()).as_str());
} else if stale.iter().any(|n| n == pkg.name()) {
output.push_str(
format!(" -> {}", operation::nightly_stamp().blue()).as_str(),
);
}
}
if held {
output.push_str(format!(" [{}]", "held".magenta()).as_str());
}
println!("{}", output);
}
Ok(())
}
}
}