1//! Core of cargo-remove command
23use crate::core::Package;
4use crate::util::toml_mut::manifest::DepTable;
5use crate::util::toml_mut::manifest::LocalManifest;
6use crate::CargoResult;
7use crate::GlobalContext;
89/// Remove a dependency from a Cargo.toml manifest file.
10#[derive(Debug)]
11pub struct RemoveOptions<'a> {
12/// Configuration information for Cargo operations
13pub gctx: &'a GlobalContext,
14/// Package to remove dependencies from
15pub spec: &'a Package,
16/// Dependencies to remove
17pub dependencies: Vec<String>,
18/// Which dependency section to remove these from
19pub section: DepTable,
20/// Whether or not to actually write the manifest
21pub dry_run: bool,
22}
2324/// Remove dependencies from a manifest
25pub fn remove(options: &RemoveOptions<'_>) -> CargoResult<()> {
26let dep_table = options
27 .section
28 .to_table()
29 .into_iter()
30 .map(String::from)
31 .collect::<Vec<_>>();
3233let manifest_path = options.spec.manifest_path().to_path_buf();
34let mut manifest = LocalManifest::try_new(&manifest_path)?;
3536for dep in &options.dependencies {
37let section = if dep_table.len() >= 3 {
38format!("{} for target `{}`", &dep_table[2], &dep_table[1])
39 } else {
40 dep_table[0].clone()
41 };
42 options
43 .gctx
44 .shell()
45 .status("Removing", format!("{dep} from {section}"))?;
4647 manifest.remove_from_table(&dep_table, dep)?;
4849// Now that we have removed the crate, if that was the last reference to that
50 // crate, then we need to drop any explicitly activated features on
51 // that crate.
52manifest.gc_dep(dep);
53 }
5455if options.dry_run {
56 options
57 .gctx
58 .shell()
59 .warn("aborting remove due to dry run")?;
60 } else {
61 manifest.write()?;
62 }
6364Ok(())
65}