| 109 | } |
| 110 | |
| 111 | pub fn remove(path: &Path, pkgs: &[String]) -> Result<()> { |
| 112 | if pkgs.is_empty() { |
| 113 | bail!("nothing to remove: pass one or more package names"); |
| 114 | } |
| 115 | let mut m = Manifest::load(path)?; |
| 116 | let names: Vec<&str> = pkgs.iter().map(|s| parse_spec(s).0).collect(); |
| 117 | // Validate every name exists first so a single bad one aborts before any write or print. |
| 118 | for name in &names { |
| 119 | if !m.imports.contains_key(*name) && !m.host.contains_key(*name) { |
| 120 | bail!("'{name}' is not in {}", path.display()); |
| 121 | } |
| 122 | } |
| 123 | for name in names { |
| 124 | let _ = m.imports.remove(name).is_some() | m.host.remove(name).is_some(); |
| 125 | ui::removed(name); |
| 126 | } |
| 127 | m.save(path)?; |
| 128 | ui::note("updated packages.json"); |
| 129 | Ok(()) |
| 130 | } |
| 131 | |
| 132 | /// Parse `name` or `name=url`. |
| 133 | fn parse_spec(spec: &str) -> (&str, Option<String>) { |