Skip to content

Commit a6ee681

Browse files
committed
Merge branch '3.3.x' into 3.4.x
Closes gh-44898
2 parents d78a208 + 46a30e9 commit a6ee681

File tree

4 files changed

+68
-158
lines changed

4 files changed

+68
-158
lines changed

buildSrc/src/main/java/org/springframework/boot/build/bom/BomPlugin.java

+2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ public void apply(Project project) {
6565
TaskProvider<CreateResolvedBom> createResolvedBom = project.getTasks()
6666
.register("createResolvedBom", CreateResolvedBom.class, bom);
6767
TaskProvider<CheckBom> checkBom = project.getTasks().register("bomrCheck", CheckBom.class, bom);
68+
checkBom.configure(
69+
(task) -> task.getResolvedBomFile().set(createResolvedBom.flatMap(CreateResolvedBom::getOutputFile)));
6870
project.getTasks().named("check").configure((check) -> check.dependsOn(checkBom));
6971
project.getTasks().register("bomrUpgrade", UpgradeBom.class, bom);
7072
project.getTasks().register("moveToSnapshots", MoveToSnapshots.class, bom);

buildSrc/src/main/java/org/springframework/boot/build/bom/CheckBom.java

+64-30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,9 +16,9 @@
1616

1717
package org.springframework.boot.build.bom;
1818

19-
import java.io.File;
2019
import java.util.ArrayList;
2120
import java.util.List;
21+
import java.util.Optional;
2222
import java.util.Set;
2323
import java.util.TreeSet;
2424
import java.util.stream.Collectors;
@@ -32,15 +32,22 @@
3232
import org.gradle.api.DefaultTask;
3333
import org.gradle.api.GradleException;
3434
import org.gradle.api.artifacts.ConfigurationContainer;
35-
import org.gradle.api.artifacts.ResolvedArtifact;
3635
import org.gradle.api.artifacts.dsl.DependencyHandler;
36+
import org.gradle.api.file.RegularFile;
37+
import org.gradle.api.file.RegularFileProperty;
38+
import org.gradle.api.provider.Provider;
39+
import org.gradle.api.tasks.InputFile;
40+
import org.gradle.api.tasks.PathSensitive;
41+
import org.gradle.api.tasks.PathSensitivity;
3742
import org.gradle.api.tasks.TaskAction;
3843

3944
import org.springframework.boot.build.bom.Library.Group;
4045
import org.springframework.boot.build.bom.Library.Module;
4146
import org.springframework.boot.build.bom.Library.ProhibitedVersion;
4247
import org.springframework.boot.build.bom.Library.VersionAlignment;
43-
import org.springframework.boot.build.bom.ManagedDependencies.Difference;
48+
import org.springframework.boot.build.bom.ResolvedBom.Bom;
49+
import org.springframework.boot.build.bom.ResolvedBom.Id;
50+
import org.springframework.boot.build.bom.ResolvedBom.ResolvedLibrary;
4451
import org.springframework.boot.build.bom.bomr.version.DependencyVersion;
4552

4653
/**
@@ -51,19 +58,29 @@
5158
*/
5259
public abstract class CheckBom extends DefaultTask {
5360

61+
private final Provider<ResolvedBom> resolvedBom;
62+
5463
private final ConfigurationContainer configurations;
5564

5665
private final DependencyHandler dependencies;
5766

5867
private final BomExtension bom;
5968

69+
private final BomResolver bomResolver;
70+
6071
@Inject
6172
public CheckBom(BomExtension bom) {
62-
this.bom = bom;
6373
this.configurations = getProject().getConfigurations();
6474
this.dependencies = getProject().getDependencies();
75+
this.bom = bom;
76+
this.resolvedBom = getResolvedBomFile().map(RegularFile::getAsFile).map(ResolvedBom::readFrom);
77+
this.bomResolver = new BomResolver(this.configurations, this.dependencies);
6578
}
6679

80+
@InputFile
81+
@PathSensitive(PathSensitivity.RELATIVE)
82+
abstract RegularFileProperty getResolvedBomFile();
83+
6784
@TaskAction
6885
void checkBom() {
6986
List<String> errors = new ArrayList<>();
@@ -191,35 +208,52 @@ private void checkDependencyManagementAlignment(Library library, List<String> er
191208
if (alignsWithBom == null) {
192209
return;
193210
}
194-
File bom = resolveBom(library, alignsWithBom);
195-
ManagedDependencies managedByBom = ManagedDependencies.ofBom(bom);
196-
ManagedDependencies managedByLibrary = ManagedDependencies.ofLibrary(library);
197-
Difference diff = managedByBom.diff(managedByLibrary);
198-
if (!diff.isEmpty()) {
199-
String error = "Dependency management does not align with " + library.getAlignsWithBom() + ":";
200-
if (!diff.missing().isEmpty()) {
201-
error = error + "%n - Missing:%n %s"
202-
.formatted(String.join("\n ", diff.missing()));
203-
}
204-
if (!diff.unexpected().isEmpty()) {
205-
error = error + "%n - Unexpected:%n %s"
206-
.formatted(String.join("\n ", diff.unexpected()));
207-
}
208-
errors.add(error);
211+
Bom mavenBom = this.bomResolver.resolveMavenBom(alignsWithBom + ":" + library.getVersion().getVersion());
212+
ResolvedBom resolvedBom = this.resolvedBom.get();
213+
Optional<ResolvedLibrary> resolvedLibrary = resolvedBom.libraries()
214+
.stream()
215+
.filter((candidate) -> candidate.name().equals(library.getName()))
216+
.findFirst();
217+
if (!resolvedLibrary.isPresent()) {
218+
throw new RuntimeException("Library '%s' not found in resolved bom".formatted(library.getName()));
209219
}
220+
checkDependencyManagementAlignment(resolvedLibrary.get(), mavenBom, errors);
210221
}
211222

212-
private File resolveBom(Library library, String alignsWithBom) {
213-
String coordinates = alignsWithBom + ":" + library.getVersion().getVersion() + "@pom";
214-
Set<ResolvedArtifact> artifacts = this.configurations
215-
.detachedConfiguration(this.dependencies.create(coordinates))
216-
.getResolvedConfiguration()
217-
.getResolvedArtifacts();
218-
if (artifacts.size() != 1) {
219-
throw new IllegalStateException("Expected a single artifact but '%s' resolved to %d artifacts"
220-
.formatted(coordinates, artifacts.size()));
223+
private void checkDependencyManagementAlignment(ResolvedLibrary library, Bom mavenBom, List<String> errors) {
224+
List<Id> managedByLibrary = library.managedDependencies();
225+
List<Id> managedByBom = managedDependenciesOf(mavenBom);
226+
227+
List<Id> missing = new ArrayList<>(managedByBom);
228+
missing.removeAll(managedByLibrary);
229+
230+
List<Id> unexpected = new ArrayList<>(managedByLibrary);
231+
unexpected.removeAll(managedByBom);
232+
if (missing.isEmpty() && unexpected.isEmpty()) {
233+
return;
234+
}
235+
String error = "Dependency management does not align with " + mavenBom.id() + ":";
236+
if (!missing.isEmpty()) {
237+
error = error + "%n - Missing:%n %s".formatted(String.join("\n ",
238+
missing.stream().map((dependency) -> dependency.toString()).toList()));
239+
}
240+
if (!unexpected.isEmpty()) {
241+
error = error + "%n - Unexpected:%n %s".formatted(String.join("\n ",
242+
unexpected.stream().map((dependency) -> dependency.toString()).toList()));
243+
}
244+
errors.add(error);
245+
}
246+
247+
private List<Id> managedDependenciesOf(Bom mavenBom) {
248+
List<Id> managedDependencies = new ArrayList<>();
249+
managedDependencies.addAll(mavenBom.managedDependencies());
250+
if (mavenBom.parent() != null) {
251+
managedDependencies.addAll(managedDependenciesOf(mavenBom.parent()));
252+
}
253+
for (Bom importedBom : mavenBom.importedBoms()) {
254+
managedDependencies.addAll(managedDependenciesOf(importedBom));
221255
}
222-
return artifacts.iterator().next().getFile();
256+
return managedDependencies;
223257
}
224258

225259
}

buildSrc/src/main/java/org/springframework/boot/build/bom/CreateResolvedBom.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2025 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -40,6 +40,7 @@ public abstract class CreateResolvedBom extends DefaultTask {
4040

4141
@Inject
4242
public CreateResolvedBom(BomExtension bomExtension) {
43+
getOutputs().upToDateWhen((spec) -> false);
4344
this.bomExtension = bomExtension;
4445
this.bomResolver = new BomResolver(getProject().getConfigurations(), getProject().getDependencies());
4546
getOutputFile().convention(getProject().getLayout().getBuildDirectory().file(getName() + "/resolved-bom.json"));

buildSrc/src/main/java/org/springframework/boot/build/bom/ManagedDependencies.java

-127
This file was deleted.

0 commit comments

Comments
 (0)