blob: 62a3e223ddd92f6d15e068ca39b1979584c68d74 [file] [log] [blame]
use cargo::core::dependency::DepKind;
use cargo::ops::cargo_remove::remove;
use cargo::ops::cargo_remove::RemoveOptions;
use cargo::ops::resolve_ws;
use cargo::util::command_prelude::*;
use cargo::util::toml_mut::manifest::DepTable;
pub fn cli() -> clap::Command {
clap::Command::new("remove")
// Subcommand aliases are handled in `aliased_command()`.
// .alias("rm")
.about("Remove dependencies from a Cargo.toml manifest file")
.args([clap::Arg::new("dependencies")
.action(clap::ArgAction::Append)
.required(true)
.num_args(1..)
.value_name("DEP_ID")
.help("Dependencies to be removed")])
.arg_package("Package to remove from")
.arg_manifest_path()
.arg_quiet()
.arg_dry_run("Don't actually write the manifest")
.next_help_heading("Section")
.args([
clap::Arg::new("dev")
.long("dev")
.conflicts_with("build")
.action(clap::ArgAction::SetTrue)
.group("section")
.help("Remove as development dependency"),
clap::Arg::new("build")
.long("build")
.conflicts_with("dev")
.action(clap::ArgAction::SetTrue)
.group("section")
.help("Remove as build dependency"),
clap::Arg::new("target")
.long("target")
.num_args(1)
.value_name("TARGET")
.value_parser(clap::builder::NonEmptyStringValueParser::new())
.help("Remove as dependency from the given target platform"),
])
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let dry_run = args.dry_run();
let workspace = args.workspace(config)?;
let packages = args.packages_from_flags()?;
let packages = packages.get_packages(&workspace)?;
let spec = match packages.len() {
0 => {
return Err(CliError::new(
anyhow::format_err!("no packages selected. Please specify one with `-p <PKG_ID>`"),
101,
));
}
1 => packages[0],
len => {
return Err(CliError::new(
anyhow::format_err!(
"{len} packages selected. Please specify one with `-p <PKG_ID>`",
),
101,
));
}
};
let dependencies = args
.get_many::<String>("dependencies")
.expect("required(true)")
.cloned()
.collect();
let section = parse_section(args);
let options = RemoveOptions {
config,
spec,
dependencies,
section,
dry_run,
};
remove(&options)?;
if !dry_run {
// Reload the workspace since we've changed dependencies
let ws = args.workspace(config)?;
resolve_ws(&ws)?;
}
Ok(())
}
fn parse_section(args: &ArgMatches) -> DepTable {
let dev = args.flag("dev");
let build = args.flag("build");
let kind = if dev {
DepKind::Development
} else if build {
DepKind::Build
} else {
DepKind::Normal
};
let mut table = DepTable::new().set_kind(kind);
if let Some(target) = args.get_one::<String>("target") {
assert!(!target.is_empty(), "Target specification may not be empty");
table = table.set_target(target);
}
table
}