|
| 1 | +use cargo::core::dependency::DepKind; |
| 2 | +use cargo::ops::cargo_remove::remove; |
| 3 | +use cargo::ops::cargo_remove::RemoveOptions; |
| 4 | +use cargo::ops::resolve_ws; |
| 5 | +use cargo::util::command_prelude::*; |
| 6 | +use cargo::util::toml_mut::manifest::DepTable; |
| 7 | + |
| 8 | +pub fn cli() -> clap::Command { |
| 9 | + clap::Command::new("remove") |
| 10 | + // Subcommand aliases are handled in `aliased_command()`. |
| 11 | + // .alias("rm") |
| 12 | + .about("Remove dependencies from a Cargo.toml manifest file") |
| 13 | + .args([clap::Arg::new("dependencies") |
| 14 | + .action(clap::ArgAction::Append) |
| 15 | + .required(true) |
| 16 | + .num_args(1..) |
| 17 | + .value_name("DEP_ID") |
| 18 | + .help("Dependencies to be removed")]) |
| 19 | + .arg_package("Package to remove from") |
| 20 | + .arg_manifest_path() |
| 21 | + .arg_quiet() |
| 22 | + .arg_dry_run("Don't actually write the manifest") |
| 23 | + .next_help_heading("SECTION") |
| 24 | + .args([ |
| 25 | + clap::Arg::new("dev") |
| 26 | + .long("dev") |
| 27 | + .conflicts_with("build") |
| 28 | + .action(clap::ArgAction::SetTrue) |
| 29 | + .group("section") |
| 30 | + .help("Remove as development dependency"), |
| 31 | + clap::Arg::new("build") |
| 32 | + .long("build") |
| 33 | + .conflicts_with("dev") |
| 34 | + .action(clap::ArgAction::SetTrue) |
| 35 | + .group("section") |
| 36 | + .help("Remove as build dependency"), |
| 37 | + clap::Arg::new("target") |
| 38 | + .long("target") |
| 39 | + .num_args(1) |
| 40 | + .value_name("TARGET") |
| 41 | + .value_parser(clap::builder::NonEmptyStringValueParser::new()) |
| 42 | + .help("Remove as dependency from the given target platform"), |
| 43 | + ]) |
| 44 | +} |
| 45 | + |
| 46 | +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { |
| 47 | + let dry_run = args.dry_run(); |
| 48 | + |
| 49 | + let workspace = args.workspace(config)?; |
| 50 | + let packages = args.packages_from_flags()?; |
| 51 | + let packages = packages.get_packages(&workspace)?; |
| 52 | + let spec = match packages.len() { |
| 53 | + 0 => { |
| 54 | + return Err(CliError::new( |
| 55 | + anyhow::format_err!("no packages selected. Please specify one with `-p <PKG_ID>`"), |
| 56 | + 101, |
| 57 | + )); |
| 58 | + } |
| 59 | + 1 => packages[0], |
| 60 | + len => { |
| 61 | + return Err(CliError::new( |
| 62 | + anyhow::format_err!( |
| 63 | + "{len} packages selected. Please specify one with `-p <PKG_ID>`", |
| 64 | + ), |
| 65 | + 101, |
| 66 | + )); |
| 67 | + } |
| 68 | + }; |
| 69 | + |
| 70 | + let dependencies = args |
| 71 | + .get_many::<String>("dependencies") |
| 72 | + .expect("required(true)") |
| 73 | + .cloned() |
| 74 | + .collect(); |
| 75 | + |
| 76 | + let section = parse_section(args); |
| 77 | + |
| 78 | + let options = RemoveOptions { |
| 79 | + config, |
| 80 | + spec, |
| 81 | + dependencies, |
| 82 | + section, |
| 83 | + dry_run, |
| 84 | + }; |
| 85 | + remove(&options)?; |
| 86 | + |
| 87 | + if !dry_run { |
| 88 | + // Reload the workspace since we've changed dependencies |
| 89 | + let ws = args.workspace(config)?; |
| 90 | + resolve_ws(&ws)?; |
| 91 | + } |
| 92 | + |
| 93 | + Ok(()) |
| 94 | +} |
| 95 | + |
| 96 | +fn parse_section(args: &ArgMatches) -> DepTable { |
| 97 | + let dev = args.flag("dev"); |
| 98 | + let build = args.flag("build"); |
| 99 | + |
| 100 | + let kind = if dev { |
| 101 | + DepKind::Development |
| 102 | + } else if build { |
| 103 | + DepKind::Build |
| 104 | + } else { |
| 105 | + DepKind::Normal |
| 106 | + }; |
| 107 | + |
| 108 | + let mut table = DepTable::new().set_kind(kind); |
| 109 | + |
| 110 | + if let Some(target) = args.get_one::<String>("target") { |
| 111 | + assert!(!target.is_empty(), "Target specification may not be empty"); |
| 112 | + table = table.set_target(target); |
| 113 | + } |
| 114 | + |
| 115 | + table |
| 116 | +} |
0 commit comments