| 73 | } |
| 74 | |
| 75 | pub fn add(path: &Path, pkgs: &[String]) -> Result<()> { |
| 76 | if pkgs.is_empty() { |
| 77 | bail!("nothing to add: pass one or more package names"); |
| 78 | } |
| 79 | // Validate every spec first so a single unknown name aborts before any write or print. |
| 80 | let resolved: Vec<(&str, Kind, String)> = pkgs |
| 81 | .iter() |
| 82 | .map(|spec| { |
| 83 | let (name, url_override) = parse_spec(spec); |
| 84 | let (kind, url) = match url_override { |
| 85 | Some(u) => (kind_from_url(&u), u), |
| 86 | None => registry(name) |
| 87 | .ok_or_else(|| anyhow!("unknown package '{name}'; give a url with {name}=<url>"))?, |
| 88 | }; |
| 89 | Ok::<_, anyhow::Error>((name, kind, url)) |
| 90 | }) |
| 91 | .collect::<Result<_>>()?; |
| 92 | |
| 93 | let mut m = Manifest::load(path)?; |
| 94 | for (name, kind, url) in resolved { |
| 95 | match kind { |
| 96 | Kind::Std => { |
| 97 | m.imports.insert(name.to_string(), url); |
| 98 | ui::added(name, "std"); |
| 99 | } |
| 100 | Kind::Host => { |
| 101 | m.host.insert(name.to_string(), url); |
| 102 | ui::added(name, "host"); |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | m.save(path)?; |
| 107 | ui::note("updated packages.json"); |
| 108 | Ok(()) |
| 109 | } |
| 110 | |
| 111 | pub fn remove(path: &Path, pkgs: &[String]) -> Result<()> { |
| 112 | if pkgs.is_empty() { |