1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use super::errors::*;
use cargo_metadata::Package;
use std::convert::TryInto;
use std::path::Path;
pub fn manifest_from_pkgid(manifest_path: Option<&Path>, pkgid: &str) -> CargoResult<Package> {
let mut cmd = cargo_metadata::MetadataCommand::new();
cmd.no_deps();
if let Some(manifest_path) = manifest_path {
cmd.manifest_path(manifest_path);
}
let result = cmd.exec().with_context(|| "Invalid manifest")?;
let packages = result.packages;
let package = packages
.into_iter()
.find(|pkg| pkg.name == pkgid)
.with_context(|| {
"Found virtual manifest, but this command requires running against an \
actual package in this workspace. Try adding `--workspace`."
})?;
Ok(package)
}
pub fn workspace_members(manifest_path: Option<&Path>) -> CargoResult<Vec<Package>> {
let mut cmd = cargo_metadata::MetadataCommand::new();
cmd.no_deps();
if let Some(manifest_path) = manifest_path {
cmd.manifest_path(manifest_path);
}
let result = cmd.exec().with_context(|| "Invalid manifest")?;
let workspace_members: std::collections::BTreeSet<_> =
result.workspace_members.into_iter().collect();
let workspace_members: Vec<_> = result
.packages
.into_iter()
.filter(|p| workspace_members.contains(&p.id))
.map(|mut p| {
p.manifest_path = canonicalize_path(p.manifest_path);
for dep in p.dependencies.iter_mut() {
dep.path = dep.path.take().map(canonicalize_path);
}
p
})
.collect();
Ok(workspace_members)
}
fn canonicalize_path(
path: cargo_metadata::camino::Utf8PathBuf,
) -> cargo_metadata::camino::Utf8PathBuf {
if let Ok(path) = dunce::canonicalize(&path) {
if let Ok(path) = path.try_into() {
return path;
}
}
path
}