1use super::errors::{CargoResult, Context};
2use cargo_metadata::Package;
3use std::path::Path;
4
5pub fn manifest_from_pkgid(manifest_path: Option<&Path>, pkgid: &str) -> CargoResult<Package> {
7 let mut cmd = cargo_metadata::MetadataCommand::new();
8 cmd.no_deps();
9 if let Some(manifest_path) = manifest_path {
10 cmd.manifest_path(manifest_path);
11 }
12 let result = cmd.exec().with_context(|| "Invalid manifest")?;
13 let packages = result.packages;
14 let package = packages
15 .into_iter()
16 .find(|pkg| pkg.name.as_ref() == pkgid)
17 .with_context(|| {
18 "Found virtual manifest, but this command requires running against an \
19 actual package in this workspace. Try adding `--workspace`."
20 })?;
21 Ok(package)
22}
23
24pub(crate) fn find_manifest_path(dir: &Path) -> CargoResult<std::path::PathBuf> {
26 const MANIFEST_FILENAME: &str = "Cargo.toml";
27 for path in dir.ancestors() {
28 let manifest = path.join(MANIFEST_FILENAME);
29 if std::fs::metadata(&manifest).is_ok() {
30 return Ok(manifest);
31 }
32 }
33 anyhow::bail!("Unable to find Cargo.toml for {}", dir.display());
34}