From ced32f075117113093104038ec238bc240fe4458 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 5 Sep 2023 10:40:31 +0100 Subject: [PATCH] Require libraries to opt in to moving to snapshots Closes gh-37190 --- .../boot/build/bom/BomExtension.java | 9 +++++++- .../boot/build/bom/Library.java | 12 +++++++++-- .../boot/build/bom/bomr/MoveToSnapshots.java | 6 ++++++ .../build/bom/bomr/UpgradeDependencies.java | 21 ++++++++++++------- .../bom/bomr/UpgradeApplicatorTests.java | 12 +++++------ .../spring-boot-dependencies/build.gradle | 17 +++++++++++++++ 6 files changed, 60 insertions(+), 17 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java index 6949fc1340..fc93cb3485 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java @@ -114,7 +114,8 @@ public class BomExtension { LibraryHandler libraryHandler = objects.newInstance(LibraryHandler.class, (version != null) ? version : ""); action.execute(libraryHandler); LibraryVersion libraryVersion = new LibraryVersion(DependencyVersion.parse(libraryHandler.version)); - addLibrary(new Library(name, libraryVersion, libraryHandler.groups, libraryHandler.prohibitedVersions)); + addLibrary(new Library(name, libraryVersion, libraryHandler.groups, libraryHandler.prohibitedVersions, + libraryHandler.considerSnapshots)); } public void effectiveBomArtifact() { @@ -214,6 +215,8 @@ public class BomExtension { private final List prohibitedVersions = new ArrayList<>(); + private boolean considerSnapshots = false; + private String version; @Inject @@ -225,6 +228,10 @@ public class BomExtension { this.version = version; } + public void considerSnapshots() { + this.considerSnapshots = true; + } + public void group(String id, Action action) { GroupHandler groupHandler = new GroupHandler(id); action.execute(groupHandler); diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java index b51cd42dd5..9ab51896ff 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java @@ -42,6 +42,8 @@ public class Library { private final List prohibitedVersions; + private final boolean considerSnapshots; + /** * Create a new {@code Library} with the given {@code name}, {@code version}, and * {@code groups}. @@ -49,15 +51,17 @@ public class Library { * @param version version of the library * @param groups groups in the library * @param prohibitedVersions version of the library that are prohibited + * @param considerSnapshots whether to consider snapshots */ - public Library(String name, LibraryVersion version, List groups, - List prohibitedVersions) { + public Library(String name, LibraryVersion version, List groups, List prohibitedVersions, + boolean considerSnapshots) { this.name = name; this.version = version; this.groups = groups; this.versionProperty = "Spring Boot".equals(name) ? null : name.toLowerCase(Locale.ENGLISH).replace(' ', '-') + ".version"; this.prohibitedVersions = prohibitedVersions; + this.considerSnapshots = considerSnapshots; } public String getName() { @@ -80,6 +84,10 @@ public class Library { return this.prohibitedVersions; } + public boolean isConsiderSnapshots() { + return this.considerSnapshots; + } + /** * A version or range of versions that are prohibited from being used in a bom. */ diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MoveToSnapshots.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MoveToSnapshots.java index 322ecd5011..e839c87125 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MoveToSnapshots.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MoveToSnapshots.java @@ -23,6 +23,7 @@ import javax.inject.Inject; import org.gradle.api.Task; import org.springframework.boot.build.bom.BomExtension; +import org.springframework.boot.build.bom.Library; /** * A {@link Task} to move to snapshot dependencies. @@ -57,4 +58,9 @@ public abstract class MoveToSnapshots extends UpgradeDependencies { return snapshotVersion.substring(0, snapshotVersion.length() - "-SNAPSHOT".length()); } + @Override + protected boolean eligible(Library library) { + return library.isConsiderSnapshots() && super.eligible(library); + } + } diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeDependencies.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeDependencies.java index 8d7f0e6ceb..e1a456f3ef 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeDependencies.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeDependencies.java @@ -212,25 +212,30 @@ public abstract class UpgradeDependencies extends DefaultTask { new MultithreadedLibraryUpdateResolver(getThreads().get(), new StandardLibraryUpdateResolver(new MavenMetadataVersionResolver(getRepositoryUris().get()), this.bom.getUpgrade().getPolicy()))) - .resolveUpgrades(matchingLibraries(getLibraries().getOrNull()), this.bom.getLibraries()); + .resolveUpgrades(matchingLibraries(), this.bom.getLibraries()); return upgrades; } - private List matchingLibraries(String pattern) { - if (pattern == null) { - return this.bom.getLibraries(); - } - Predicate libraryPredicate = Pattern.compile(pattern).asPredicate(); + private List matchingLibraries() { List matchingLibraries = this.bom.getLibraries() .stream() - .filter((library) -> libraryPredicate.test(library.getName())) + .filter(this::eligible) .collect(Collectors.toList()); if (matchingLibraries.isEmpty()) { - throw new InvalidUserDataException("No libraries matched '" + pattern + "'"); + throw new InvalidUserDataException("No libraries to upgrade"); } return matchingLibraries; } + protected boolean eligible(Library library) { + String pattern = getLibraries().getOrNull(); + if (pattern == null) { + return true; + } + Predicate libraryPredicate = Pattern.compile(pattern).asPredicate(); + return libraryPredicate.test(library.getName()); + } + protected abstract String issueTitle(Upgrade upgrade); protected abstract String commitMessage(Upgrade upgrade, int issueNumber); diff --git a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/UpgradeApplicatorTests.java b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/UpgradeApplicatorTests.java index 21e509a28f..cbf0334249 100644 --- a/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/UpgradeApplicatorTests.java +++ b/buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/UpgradeApplicatorTests.java @@ -52,9 +52,9 @@ class UpgradeApplicatorTests { String originalContents = new String(Files.readAllBytes(bom.toPath()), StandardCharsets.UTF_8); File gradleProperties = new File(this.temp, "gradle.properties"); FileCopyUtils.copy(new File("src/test/resources/gradle.properties"), gradleProperties); - new UpgradeApplicator(bom.toPath(), gradleProperties.toPath()).apply( - new Upgrade(new Library("ActiveMQ", new LibraryVersion(DependencyVersion.parse("5.15.11")), null, null), - DependencyVersion.parse("5.16"))); + new UpgradeApplicator(bom.toPath(), gradleProperties.toPath()).apply(new Upgrade( + new Library("ActiveMQ", new LibraryVersion(DependencyVersion.parse("5.15.11")), null, null, false), + DependencyVersion.parse("5.16"))); String bomContents = new String(Files.readAllBytes(bom.toPath()), StandardCharsets.UTF_8); assertThat(bomContents.length()).isEqualTo(originalContents.length() - 3); } @@ -65,9 +65,9 @@ class UpgradeApplicatorTests { FileCopyUtils.copy(new File("src/test/resources/bom.gradle"), bom); File gradleProperties = new File(this.temp, "gradle.properties"); FileCopyUtils.copy(new File("src/test/resources/gradle.properties"), gradleProperties); - new UpgradeApplicator(bom.toPath(), gradleProperties.toPath()) - .apply(new Upgrade(new Library("Kotlin", new LibraryVersion(DependencyVersion.parse("1.3.70")), null, null), - DependencyVersion.parse("1.4"))); + new UpgradeApplicator(bom.toPath(), gradleProperties.toPath()).apply(new Upgrade( + new Library("Kotlin", new LibraryVersion(DependencyVersion.parse("1.3.70")), null, null, false), + DependencyVersion.parse("1.4"))); Properties properties = new Properties(); try (InputStream in = new FileInputStream(gradleProperties)) { properties.load(in); diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index f70b13cf2a..6a4e8f2ff4 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1328,6 +1328,7 @@ bom { } } library("Micrometer", "1.9.14") { + considerSnapshots() group("io.micrometer") { modules = [ "micrometer-registry-stackdriver" { @@ -1459,6 +1460,7 @@ bom { } } library("R2DBC Bom", "Borca-SR2") { + considerSnapshots() group("io.r2dbc") { imports = [ "r2dbc-bom" @@ -1487,6 +1489,7 @@ bom { } } library("Reactor Bom", "2020.0.35") { + considerSnapshots() group("io.projectreactor") { imports = [ "reactor-bom" @@ -1715,6 +1718,7 @@ bom { } } library("Spring AMQP", "2.4.15") { + considerSnapshots() prohibit { versionRange "[3.0.0-M1,)" because "it uses Spring Framework 6" @@ -1730,6 +1734,7 @@ bom { } } library("Spring Batch", "4.3.9") { + considerSnapshots() prohibit { versionRange "[5.0.0-M1,)" because "it uses Spring Framework 6" @@ -1744,6 +1749,7 @@ bom { } } library("Spring Data Bom", "2021.2.15") { + considerSnapshots() prohibit { versionRange "[2022.0.0-M1,)" because "it uses Spring Framework 6" @@ -1755,6 +1761,7 @@ bom { } } library("Spring Framework", "${springFrameworkVersion}") { + considerSnapshots() prohibit { versionRange "[6.0.0-M1,)" because "we upgrade in Spring Boot 3.x" @@ -1766,6 +1773,7 @@ bom { } } library("Spring GraphQL", "1.0.4") { + considerSnapshots() group("org.springframework.graphql") { modules = [ "spring-graphql", @@ -1774,6 +1782,7 @@ bom { } } library("Spring HATEOAS", "1.5.5") { + considerSnapshots() prohibit { versionRange "[2.0.0-M1,)" because "it uses Spring Framework 6" @@ -1785,6 +1794,7 @@ bom { } } library("Spring Integration", "5.5.18") { + considerSnapshots() prohibit { versionRange "[6.0.0-M1,)" because "it uses Spring Framework 6" @@ -1796,6 +1806,7 @@ bom { } } library("Spring Kafka", "2.8.11") { + considerSnapshots() group("org.springframework.kafka") { modules = [ "spring-kafka", @@ -1804,6 +1815,7 @@ bom { } } library("Spring LDAP", "2.4.1") { + considerSnapshots() prohibit { versionRange "[3.0.0-M1,)" because "it uses Spring Framework 6" @@ -1819,6 +1831,7 @@ bom { } } library("Spring RESTDocs", "2.0.7.RELEASE") { + considerSnapshots() group("org.springframework.restdocs") { modules = [ "spring-restdocs-asciidoctor", @@ -1830,6 +1843,7 @@ bom { } } library("Spring Retry", "1.3.4") { + considerSnapshots() group("org.springframework.retry") { modules = [ "spring-retry" @@ -1837,6 +1851,7 @@ bom { } } library("Spring Security", "5.7.10") { + considerSnapshots() prohibit { versionRange "[6.0.0-M1,)" because "it uses Spring Framework 6" @@ -1848,6 +1863,7 @@ bom { } } library("Spring Session Bom", "2021.2.2") { + considerSnapshots() prohibit { versionRange "[2022.0.0-M1,)" because "it uses Spring Framework 6" @@ -1859,6 +1875,7 @@ bom { } } library("Spring WS", "3.1.6") { + considerSnapshots() prohibit { versionRange "[4.0.0-M1,)" because "it uses Spring Framework 6"