Skip to content

Commit aa1f91d

Browse files
committed
Fix accidental exclusion of a platform's dependencies
Closes gh-368
1 parent f8c80a1 commit aa1f91d

File tree

5 files changed

+114
-36
lines changed

5 files changed

+114
-36
lines changed

src/main/java/io/spring/gradle/dependencymanagement/internal/ExclusionConfiguringAction.java

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.HashMap;
2121
import java.util.HashSet;
2222
import java.util.LinkedList;
23-
import java.util.List;
2423
import java.util.Map;
2524
import java.util.Set;
2625

@@ -39,11 +38,7 @@
3938
import org.gradle.api.artifacts.result.ResolutionResult;
4039
import org.gradle.api.artifacts.result.ResolvedComponentResult;
4140
import org.gradle.api.artifacts.result.ResolvedDependencyResult;
42-
import org.gradle.api.artifacts.result.ResolvedVariantResult;
4341
import org.gradle.api.artifacts.result.UnresolvedDependencyResult;
44-
import org.gradle.api.attributes.Attribute;
45-
import org.gradle.api.attributes.AttributeContainer;
46-
import org.gradle.api.attributes.Category;
4742
import org.slf4j.Logger;
4843
import org.slf4j.LoggerFactory;
4944

@@ -107,7 +102,7 @@ private Set<DependencyCandidate> findExcludedDependencies() {
107102
resolutionResult.allDependencies((dependencyResult) -> {
108103
if (dependencyResult instanceof ResolvedDependencyResult) {
109104
ResolvedDependencyResult resolved = (ResolvedDependencyResult) dependencyResult;
110-
if (!isPlatform(resolved.getSelected())) {
105+
if (!resolved.isConstraint()) {
111106
excludedDependencies.add(new DependencyCandidate(resolved.getSelected().getModuleVersion()));
112107
}
113108
}
@@ -137,21 +132,19 @@ private Configuration copyConfiguration() {
137132
private Set<DependencyCandidate> determineIncludedComponents(ResolvedComponentResult root,
138133
Map<String, Exclusions> pomExclusionsById) {
139134
LinkedList<Node> queue = new LinkedList<>();
140-
queue.add(new Node(root, getId(root), new HashSet<>(), false));
135+
queue.add(new Node(root, getId(root), new HashSet<>()));
141136
Set<ResolvedComponentResult> seen = new HashSet<>();
142137
Set<DependencyCandidate> includedComponents = new HashSet<>();
143138
while (!queue.isEmpty()) {
144139
Node node = queue.remove();
145140
includedComponents.add(new DependencyCandidate(node.component.getModuleVersion()));
146-
if (!node.platform) {
147-
for (DependencyResult dependency : node.component.getDependencies()) {
148-
if (dependency instanceof ResolvedDependencyResult) {
149-
handleResolvedDependency((ResolvedDependencyResult) dependency, node, pomExclusionsById, queue,
150-
seen);
151-
}
152-
else if (dependency instanceof UnresolvedDependencyResult) {
153-
handleUnresolvedDependency((UnresolvedDependencyResult) dependency, node, includedComponents);
154-
}
141+
for (DependencyResult dependency : node.component.getDependencies()) {
142+
if (dependency instanceof ResolvedDependencyResult) {
143+
handleResolvedDependency((ResolvedDependencyResult) dependency, node, pomExclusionsById, queue,
144+
seen);
145+
}
146+
else if (dependency instanceof UnresolvedDependencyResult) {
147+
handleUnresolvedDependency((UnresolvedDependencyResult) dependency, node, includedComponents);
155148
}
156149
}
157150
}
@@ -162,25 +155,11 @@ private void handleResolvedDependency(ResolvedDependencyResult dependency, Node
162155
Map<String, Exclusions> pomExclusionsById, LinkedList<Node> queue, Set<ResolvedComponentResult> seen) {
163156
ResolvedComponentResult child = dependency.getSelected();
164157
String childId = getId(child);
165-
if (!node.excluded(childId) && seen.add(child)) {
166-
boolean platform = isPlatform(child);
167-
queue.add(new Node(child, childId, getChildExclusions(node, childId, pomExclusionsById), platform));
158+
if (!node.excluded(childId) && seen.add(child) && !dependency.isConstraint()) {
159+
queue.add(new Node(child, childId, getChildExclusions(node, childId, pomExclusionsById)));
168160
}
169161
}
170162

171-
private boolean isPlatform(ResolvedComponentResult component) {
172-
List<ResolvedVariantResult> variants = component.getVariants();
173-
for (ResolvedVariantResult variant : variants) {
174-
AttributeContainer attributes = variant.getAttributes();
175-
String category = attributes.getAttribute(Attribute.of("org.gradle.category", String.class));
176-
if (category == null
177-
|| (!Category.REGULAR_PLATFORM.equals(category) && !Category.ENFORCED_PLATFORM.equals(category))) {
178-
return false;
179-
}
180-
}
181-
return true;
182-
}
183-
184163
private void handleUnresolvedDependency(UnresolvedDependencyResult dependency, Node node,
185164
Set<DependencyCandidate> includedComponents) {
186165
DependencyCandidate dependencyCandidate = toDependencyCandidate(dependency);
@@ -227,13 +206,10 @@ private static final class Node {
227206

228207
private final Set<Exclusion> exclusions;
229208

230-
private final boolean platform;
231-
232-
private Node(ResolvedComponentResult component, String id, Set<Exclusion> exclusions, boolean platform) {
209+
private Node(ResolvedComponentResult component, String id, Set<Exclusion> exclusions) {
233210
this.component = component;
234211
this.id = id;
235212
this.exclusions = exclusions;
236-
this.platform = platform;
237213
}
238214

239215
private boolean excluded(String id) {

src/test/java/io/spring/gradle/dependencymanagement/DependencyManagementPluginIntegrationTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,12 @@ void resolutionSucceedsWhenDependencyHasAnInvalidPom() {
510510
.contains("Building this project requires a newer version of Maven");
511511
}
512512

513+
@Test
514+
void dependenciesDeclaredInAPlatformAreNotAccidentallyExcluded() {
515+
this.gradleBuild.runner().withArguments("resolve").build();
516+
assertThat(readLines("resolved.txt")).containsExactly("spring-core-5.3.27.jar", "spring-jcl-5.3.27.jar");
517+
}
518+
513519
private void writeLines(Path path, String... lines) {
514520
try {
515521
Path resolvedPath = this.gradleBuild.runner().getProjectDir().toPath().resolve(path);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
plugins {
2+
id "java"
3+
id "io.spring.dependency-management"
4+
}
5+
6+
repositories {
7+
maven {
8+
url file("maven-repo")
9+
}
10+
mavenCentral()
11+
}
12+
13+
dependencies {
14+
implementation(platform("test:platform-with-dependencies:1.0"))
15+
}
16+
17+
tasks.register("resolve") {
18+
doFirst {
19+
def files = project.configurations.compileClasspath.resolve()
20+
def output = new File("${buildDir}/resolved.txt")
21+
output.parentFile.mkdirs()
22+
files.collect { it.name }.each { output << "${it}\n" }
23+
}
24+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"formatVersion": "1.1",
3+
"component": {
4+
"group": "test",
5+
"module": "platform-with-dependencies",
6+
"version": "1.0",
7+
"attributes": {
8+
"org.gradle.status": "release"
9+
}
10+
},
11+
"createdBy": {
12+
"gradle": {
13+
"version": "8.1.1"
14+
}
15+
},
16+
"variants": [
17+
{
18+
"name": "apiElements",
19+
"attributes": {
20+
"org.gradle.category": "platform",
21+
"org.gradle.usage": "java-api"
22+
},
23+
"dependencies": [
24+
{
25+
"group": "org.springframework",
26+
"module": "spring-core",
27+
"version": {
28+
"requires": "5.3.27"
29+
}
30+
}
31+
]
32+
},
33+
{
34+
"name": "runtimeElements",
35+
"attributes": {
36+
"org.gradle.category": "platform",
37+
"org.gradle.usage": "java-runtime"
38+
},
39+
"dependencies": [
40+
{
41+
"group": "org.springframework",
42+
"module": "spring-core",
43+
"version": {
44+
"requires": "6.0.12"
45+
}
46+
}
47+
]
48+
}
49+
]
50+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4+
<!-- This module was also published with a richer model, Gradle metadata, -->
5+
<!-- which should be used instead. Do not delete the following line which -->
6+
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
7+
<!-- that they should prefer consuming it instead. -->
8+
<!-- do_not_remove: published-with-gradle-metadata -->
9+
<modelVersion>4.0.0</modelVersion>
10+
<groupId>test</groupId>
11+
<artifactId>platform-with-dependencies</artifactId>
12+
<version>1.0</version>
13+
<packaging>pom</packaging>
14+
<dependencies>
15+
<dependency>
16+
<groupId>org.springframework</groupId>
17+
<artifactId>spring-core</artifactId>
18+
<version>5.3.27</version>
19+
<scope>compile</scope>
20+
</dependency>
21+
</dependencies>
22+
</project>

0 commit comments

Comments
 (0)