Skip to content

Commit 058064e

Browse files
committed
cargo-rbmt: helpful error if package doesn't exist
1 parent 32c0c8d commit 058064e

File tree

1 file changed

+40
-6
lines changed

1 file changed

+40
-6
lines changed

cargo-rbmt/src/environment.rs

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,18 @@ pub fn change_to_repo_root(sh: &Shell) {
6464
/// # Arguments
6565
///
6666
/// * `packages` - Optional filter for specific package names. If empty, returns all packages.
67+
///
68+
/// # Errors
69+
///
70+
/// Returns an error if any requested package name doesn't exist in the workspace.
6771
pub fn get_packages(
6872
sh: &Shell,
6973
packages: &[String],
7074
) -> Result<Vec<(String, PathBuf)>, Box<dyn std::error::Error>> {
7175
let metadata = quiet_cmd!(sh, "cargo metadata --no-deps --format-version 1").read()?;
7276
let json: serde_json::Value = serde_json::from_str(&metadata)?;
7377

74-
let package_info: Vec<(String, PathBuf)> = json["packages"]
78+
let all_packages: Vec<(String, PathBuf)> = json["packages"]
7579
.as_array()
7680
.ok_or("Missing 'packages' field in cargo metadata")?
7781
.iter()
@@ -82,15 +86,45 @@ pub fn get_packages(
8286
// e.g., "/path/to/repo/releases/Cargo.toml" -> "/path/to/repo/releases".
8387
let dir_path = manifest_path.trim_end_matches("/Cargo.toml");
8488

85-
// Filter by package name if specified.
86-
if !packages.is_empty() && !packages.iter().any(|p| p == package_name) {
87-
return None;
88-
}
89-
9089
Some((package_name.to_owned(), PathBuf::from(dir_path)))
9190
})
9291
.collect();
9392

93+
// If no package filter specified, return all packages.
94+
if packages.is_empty() {
95+
return Ok(all_packages);
96+
}
97+
98+
// Validate that all requested packages exist in the workspace.
99+
let available_names: Vec<&str> = all_packages.iter().map(|(name, _)| name.as_str()).collect();
100+
let mut invalid_packages = Vec::new();
101+
102+
for requested_package in packages {
103+
if !available_names.contains(&requested_package.as_str()) {
104+
invalid_packages.push(requested_package.clone());
105+
}
106+
}
107+
108+
if !invalid_packages.is_empty() {
109+
let mut error_msg = format!(
110+
"Package not found in workspace: {}",
111+
invalid_packages.join(", ")
112+
);
113+
114+
error_msg.push_str("\n\nAvailable packages:");
115+
for name in &available_names {
116+
error_msg.push_str(&format!("\n - {}", name));
117+
}
118+
119+
return Err(error_msg.into());
120+
}
121+
122+
// Filter to only requested packages.
123+
let package_info: Vec<(String, PathBuf)> = all_packages
124+
.into_iter()
125+
.filter(|(name, _)| packages.iter().any(|p| p == name))
126+
.collect();
127+
94128
Ok(package_info)
95129
}
96130

0 commit comments

Comments
 (0)