use std::ops::{Deref, DerefMut};
use std::path::PathBuf;
use std::process::Command;
use clap::{ArgAction, Parser};
use crate::common::CommonOptions;
use crate::heading;
#[derive(Clone, Debug, Default, Parser)]
#[command(
display_order = 1,
after_help = "Run `cargo help install` for more detailed information."
)]
#[group(skip)]
pub struct Install {
#[command(flatten)]
pub common: CommonOptions,
#[arg(long, value_name = "VERSION", alias = "vers", requires = "crates")]
pub version: Option<String>,
#[arg(long, value_name = "URL", conflicts_with_all = ["path", "index", "registry"])]
pub git: Option<String>,
#[arg(long, value_name = "BRANCH", requires = "git")]
pub branch: Option<String>,
#[arg(long, value_name = "TAG", requires = "git")]
pub tag: Option<String>,
#[arg(long, value_name = "SHA", requires = "git")]
pub rev: Option<String>,
#[arg(long, value_name = "PATH", conflicts_with_all = ["git", "index", "registry"])]
pub path: Option<PathBuf>,
#[arg(long)]
pub list: bool,
#[arg(short, long)]
pub force: bool,
#[arg(long)]
pub no_track: bool,
#[arg(long)]
pub debug: bool,
#[arg(long, value_name = "DIR")]
pub root: Option<PathBuf>,
#[arg(
long,
value_name = "INDEX",
conflicts_with_all = ["git", "path", "registry"],
requires = "crates",
)]
pub index: Option<String>,
#[arg(
long,
value_name = "REGISTRY",
conflicts_with_all = ["git", "path", "index"],
requires = "crates",
)]
pub registry: Option<String>,
#[arg(
long,
value_name = "NAME",
action = ArgAction::Append,
num_args=0..=1,
help_heading = heading::TARGET_SELECTION,
)]
pub bin: Vec<String>,
#[arg(long, help_heading = heading::TARGET_SELECTION)]
pub bins: bool,
#[arg(
long,
value_name = "NAME",
action = ArgAction::Append,
num_args=0..=1,
help_heading = heading::TARGET_SELECTION,
)]
pub example: Vec<String>,
#[arg(long, help_heading = heading::TARGET_SELECTION)]
pub examples: bool,
#[arg(value_name = "crate", action = ArgAction::Append, num_args = 0..)]
pub crates: Vec<String>,
}
impl Install {
pub fn command(&self) -> Command {
let mut cmd = CommonOptions::cargo_command();
cmd.arg("install");
self.common.apply(&mut cmd);
if let Some(version) = self.version.as_ref() {
cmd.arg("--version").arg(version);
}
if let Some(git) = self.git.as_ref() {
cmd.arg("--git").arg(git);
}
if let Some(branch) = self.branch.as_ref() {
cmd.arg("--branch").arg(branch);
}
if let Some(tag) = self.tag.as_ref() {
cmd.arg("--tag").arg(tag);
}
if let Some(rev) = self.rev.as_ref() {
cmd.arg("--rev").arg(rev);
}
if let Some(path) = self.path.as_ref() {
cmd.arg("--path").arg(path);
}
if self.list {
cmd.arg("--list");
}
if self.force {
cmd.arg("--force");
}
if self.no_track {
cmd.arg("--no-track");
}
if self.debug {
cmd.arg("--debug");
}
if let Some(root) = self.root.as_ref() {
cmd.arg("--root").arg(root);
}
if let Some(index) = self.index.as_ref() {
cmd.arg("--index").arg(index);
}
if let Some(registry) = self.registry.as_ref() {
cmd.arg("--registry").arg(registry);
}
for bin in &self.bin {
cmd.arg("--bin").arg(bin);
}
if self.bins {
cmd.arg("--bins");
}
for example in &self.example {
cmd.arg("--example").arg(example);
}
if self.examples {
cmd.arg("--examples");
}
cmd.args(&self.crates);
cmd
}
}
impl Deref for Install {
type Target = CommonOptions;
fn deref(&self) -> &Self::Target {
&self.common
}
}
impl DerefMut for Install {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.common
}
}
#[cfg(test)]
mod test {
use super::Install;
use clap::CommandFactory;
#[test]
fn verify_cli() {
<Install as CommandFactory>::command().debug_assert()
}
}