Skip to content

Commit d680d81

Browse files
Take into account DependencyKind when collecting package target dependencies (#2235)
When filtering out disabled dependencies for the Bazel targets, `collect_deps_selectable()` now takes into account the kind of dependency in question. Previously, if a disabled optional normal dependency was mandatory for a build script, it was erroneously filtered out. This change resolves #2059
1 parent 9341d1f commit d680d81

File tree

5 files changed

+5632
-8
lines changed

5 files changed

+5632
-8
lines changed

crate_universe/src/metadata/dependency.rs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
//! Gathering dependencies is the largest part of annotating.
22
33
use anyhow::{bail, Result};
4-
use cargo_metadata::{Metadata as CargoMetadata, Node, NodeDep, Package, PackageId};
4+
use cargo_metadata::{
5+
DependencyKind, Metadata as CargoMetadata, Node, NodeDep, Package, PackageId,
6+
};
57
use cargo_platform::Platform;
68
use serde::{Deserialize, Serialize};
79

@@ -47,8 +49,8 @@ impl DependencySet {
4749
.partition(|dep| is_dev_dependency(dep));
4850

4951
(
50-
collect_deps_selectable(node, dev, metadata),
51-
collect_deps_selectable(node, normal, metadata),
52+
collect_deps_selectable(node, dev, metadata, DependencyKind::Normal),
53+
collect_deps_selectable(node, normal, metadata, DependencyKind::Normal),
5254
)
5355
};
5456

@@ -63,8 +65,8 @@ impl DependencySet {
6365
.partition(|dep| is_dev_dependency(dep));
6466

6567
(
66-
collect_deps_selectable(node, dev, metadata),
67-
collect_deps_selectable(node, normal, metadata),
68+
collect_deps_selectable(node, dev, metadata, DependencyKind::Development),
69+
collect_deps_selectable(node, normal, metadata, DependencyKind::Development),
6870
)
6971
};
7072

@@ -81,8 +83,8 @@ impl DependencySet {
8183
.partition(|dep| is_proc_macro_package(&metadata[&dep.pkg]));
8284

8385
(
84-
collect_deps_selectable(node, proc_macro, metadata),
85-
collect_deps_selectable(node, normal, metadata),
86+
collect_deps_selectable(node, proc_macro, metadata, DependencyKind::Build),
87+
collect_deps_selectable(node, normal, metadata, DependencyKind::Build),
8688
)
8789
};
8890

@@ -126,6 +128,7 @@ fn is_optional_crate_enabled(
126128
dep: &NodeDep,
127129
target: Option<&Platform>,
128130
metadata: &CargoMetadata,
131+
kind: DependencyKind,
129132
) -> bool {
130133
let pkg = &metadata[&parent.id];
131134

@@ -141,6 +144,7 @@ fn is_optional_crate_enabled(
141144
if let Some(toml_dep) = pkg
142145
.dependencies
143146
.iter()
147+
.filter(|&d| d.kind == kind)
144148
.filter(|&d| d.target.as_ref() == target)
145149
.filter(|&d| d.optional)
146150
.find(|&d| sanitize_module_name(&d.name) == dep.name)
@@ -155,6 +159,7 @@ fn collect_deps_selectable(
155159
node: &Node,
156160
deps: Vec<&NodeDep>,
157161
metadata: &cargo_metadata::Metadata,
162+
kind: DependencyKind,
158163
) -> SelectList<Dependency> {
159164
let mut selectable = SelectList::default();
160165

@@ -165,7 +170,7 @@ fn collect_deps_selectable(
165170
let alias = get_target_alias(&dep.name, dep_pkg);
166171

167172
for kind_info in &dep.dep_kinds {
168-
if is_optional_crate_enabled(node, dep, kind_info.target.as_ref(), metadata) {
173+
if is_optional_crate_enabled(node, dep, kind_info.target.as_ref(), metadata, kind) {
169174
selectable.insert(
170175
Dependency {
171176
package_id: dep.pkg.clone(),
@@ -684,4 +689,24 @@ mod test {
684689
.expect("Iterating over known keys should never panic")
685690
.any(|dep| { dep.target_name == "mio" }));
686691
}
692+
693+
#[test]
694+
fn optional_deps_disabled_build_dep_enabled() {
695+
let metadata = metadata::optional_deps_disabled_build_dep_enabled();
696+
697+
let node = find_metadata_node("gherkin", &metadata);
698+
let dependencies = DependencySet::new_for_node(node, &metadata);
699+
700+
assert!(!dependencies
701+
.normal_deps
702+
.get_iter(None)
703+
.expect("Iterating over known keys should never panic")
704+
.any(|dep| dep.target_name == "serde"));
705+
706+
assert!(dependencies
707+
.build_deps
708+
.get_iter(None)
709+
.expect("Iterating over known keys should never panic")
710+
.any(|dep| dep.target_name == "serde"));
711+
}
687712
}

crate_universe/src/test.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ pub mod metadata {
9999
.unwrap()
100100
}
101101

102+
pub fn optional_deps_disabled_build_dep_enabled() -> cargo_metadata::Metadata {
103+
serde_json::from_str(include_str!(concat!(
104+
env!("CARGO_MANIFEST_DIR"),
105+
"/test_data/metadata/crate_optional_deps_disabled_build_dep_enabled/metadata.json"
106+
)))
107+
.unwrap()
108+
}
109+
102110
pub fn optional_deps_enabled() -> cargo_metadata::Metadata {
103111
serde_json::from_str(include_str!(concat!(
104112
env!("CARGO_MANIFEST_DIR"),

crate_universe/test_data/metadata/crate_optional_deps_disabled_build_dep_enabled/Cargo.lock

Lines changed: 209 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "crate-with-optional-deps"
3+
version = "0.1.0"
4+
edition = "2021" # make sure resolver=2 is enabled for this test
5+
6+
# Required to satisfy cargo but no `lib.rs` is expected to
7+
# exist within test data.
8+
[lib]
9+
path = "lib.rs"
10+
11+
[dependencies]
12+
gherkin = "=0.13.0"

0 commit comments

Comments
 (0)