use clap::{Arg, ArgAction, Command};
use color_eyre::Result;
pub struct ApkParams {
pub subcmd: String,
pub packages: Vec<String>,
pub assume_yes: bool,
pub quiet: bool,
#[allow(dead_code)]
pub no_cache: bool,
pub update_cache: bool,
#[allow(dead_code)]
pub virtual_pkg: Option<String>,
}
pub fn parse_options(matches: &clap::ArgMatches) -> Result<ApkParams> {
let (subcmd, sub_matches) = matches.subcommand().unwrap_or(("help", matches));
let packages: Vec<String> = sub_matches
.try_get_many::<String>("packages")
.unwrap_or_default()
.map(|vals| vals.cloned().collect())
.unwrap_or_default();
let common = super::apt::parse_common_options(matches);
Ok(ApkParams {
subcmd: subcmd.to_string(),
packages,
assume_yes: common.assume_yes,
quiet: common.quiet,
no_cache: matches.get_flag("no-cache"),
update_cache: matches.get_flag("update-cache"),
virtual_pkg: sub_matches
.try_get_one::<String>("virtual")
.unwrap_or_default()
.map(|s| s.to_string()),
})
}
pub fn command() -> Command {
super::apt::add_common_args(
Command::new("apk")
.about("Alpine package manager compatibility shim (epkg)")
.subcommand_required(true)
.arg_required_else_help(true)
.arg(
Arg::new("no-cache")
.long("no-cache")
.help("Do not cache downloaded packages (accepted)")
.global(true)
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("update-cache")
.short('U')
.long("update-cache")
.help("Update repository cache before operation")
.global(true)
.action(ArgAction::SetTrue),
))
.subcommand(
Command::new("add")
.about("Install package(s)")
.arg(Arg::new("packages")
.value_name("PACKAGES")
.help("Package names to install")
.num_args(1..)
.required(true))
.arg(
Arg::new("virtual")
.short('t')
.long("virtual")
.help("Group packages under a virtual name (accepted)")
.num_args(1),
),
)
.subcommand(
Command::new("del")
.about("Remove package(s)")
.arg(Arg::new("packages")
.value_name("PACKAGES")
.help("Package names to remove")
.num_args(1..)
.required(true)),
)
.subcommand(
Command::new("info")
.about("Show package information")
.arg(Arg::new("packages")
.value_name("PACKAGES")
.help("Package names to query")
.num_args(1..)),
)
.subcommand(
Command::new("list")
.about("List installed packages"),
)
.subcommand(
Command::new("search")
.about("Search for package(s)")
.arg(Arg::new("packages")
.value_name("PATTERNS")
.help("Search patterns")
.num_args(1..)
.required(true)),
)
.subcommand(
Command::new("update")
.about("Update repository index"),
)
.subcommand(
Command::new("upgrade")
.about("Upgrade installed packages")
.arg(Arg::new("packages")
.value_name("PACKAGES")
.help("Package names to upgrade (empty = all)")
.num_args(0..)),
)
}
pub fn run(params: ApkParams) -> Result<()> {
crate::init::try_light_init()?;
super::apt::apply_common_options(&super::apt::PmParams {
assume_yes: params.assume_yes,
quiet: params.quiet,
..Default::default()
});
if params.update_cache {
crate::repo::sync_channel_metadata()?;
}
match params.subcmd.as_str() {
"add" => {
crate::install::install_packages(params.packages)?;
}
"del" => {
crate::remove::remove_packages(params.packages)?;
}
"update" => {
crate::repo::sync_channel_metadata()?;
println!("OK: repository index updated");
}
"upgrade" => {
crate::upgrade::upgrade_packages(params.packages)?;
}
"search" => {
for pattern in ¶ms.packages {
let mut options = crate::search::SearchOptions {
origin_pattern: pattern.clone(),
..Default::default()
};
crate::search::search_repo_cache(&mut options)?;
}
}
"info" => {
crate::info::show_package_info(¶ms.packages, false, false, false)?;
}
"list" => {
crate::list::list_packages_with_scope(crate::list::ListScope::Installed, "")?;
}
_ => {
eprintln!("apk: unknown command '{}'", params.subcmd);
std::process::exit(1);
}
}
Ok(())
}