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 57a16796ca..0c63ba882a 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 @@ -113,7 +113,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() { @@ -213,6 +214,8 @@ public class BomExtension { private final List prohibitedVersions = new ArrayList<>(); + private boolean considerSnapshots = false; + private String version; @Inject @@ -224,6 +227,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 6332700a25..612dc3e7fe 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 @@ -211,25 +211,27 @@ 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(); - List matchingLibraries = this.bom.getLibraries() - .stream() - .filter((library) -> libraryPredicate.test(library.getName())) - .toList(); + private List matchingLibraries() { + List matchingLibraries = this.bom.getLibraries().stream().filter(this::eligible).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 6c96ab74ef..64235849dc 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 @@ -51,9 +51,9 @@ class UpgradeApplicatorTests { String originalContents = Files.readString(bom.toPath()); 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 = Files.readString(bom.toPath()); assertThat(bomContents).hasSize(originalContents.length() - 3); } @@ -64,9 +64,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 5f7c95835e..4ac587b924 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -977,6 +977,7 @@ bom { } } library("Micrometer", "1.11.3") { + considerSnapshots() group("io.micrometer") { modules = [ "micrometer-registry-stackdriver" { @@ -989,6 +990,7 @@ bom { } } library("Micrometer Tracing", "1.1.4") { + considerSnapshots() group("io.micrometer") { imports = [ "micrometer-tracing-bom" @@ -1130,6 +1132,7 @@ bom { } } library("R2DBC H2", "1.0.0.RELEASE") { + considerSnapshots() group("io.r2dbc") { modules = [ "r2dbc-h2" @@ -1158,6 +1161,7 @@ bom { } } library("R2DBC Pool", "1.0.1.RELEASE") { + considerSnapshots() group("io.r2dbc") { modules = [ "r2dbc-pool" @@ -1165,6 +1169,7 @@ bom { } } library("R2DBC Postgresql", "1.0.2.RELEASE") { + considerSnapshots() group("org.postgresql") { modules = [ "r2dbc-postgresql" @@ -1172,6 +1177,7 @@ bom { } } library("R2DBC Proxy", "1.1.2.RELEASE") { + considerSnapshots() group("io.r2dbc") { modules = [ "r2dbc-proxy" @@ -1179,6 +1185,7 @@ bom { } } library("R2DBC SPI", "1.0.0.RELEASE") { + considerSnapshots() group("io.r2dbc") { modules = [ "r2dbc-spi" @@ -1207,6 +1214,7 @@ bom { } } library("Reactor Bom", "2022.0.10") { + considerSnapshots() group("io.projectreactor") { imports = [ "reactor-bom" @@ -1370,6 +1378,7 @@ bom { } } library("Spring AMQP", "3.0.8") { + considerSnapshots() group("org.springframework.amqp") { imports = [ "spring-amqp-bom" @@ -1377,6 +1386,7 @@ bom { } } library("Spring Authorization Server", "1.1.2") { + considerSnapshots() group("org.springframework.security") { modules = [ "spring-security-oauth2-authorization-server" @@ -1384,6 +1394,7 @@ bom { } } library("Spring Batch", "5.0.3") { + considerSnapshots() group("org.springframework.batch") { imports = [ "spring-batch-bom" @@ -1391,6 +1402,7 @@ bom { } } library("Spring Data Bom", "2023.0.3") { + considerSnapshots() group("org.springframework.data") { imports = [ "spring-data-bom" @@ -1398,6 +1410,7 @@ bom { } } library("Spring Framework", "${springFrameworkVersion}") { + considerSnapshots() group("org.springframework") { imports = [ "spring-framework-bom" @@ -1405,6 +1418,7 @@ bom { } } library("Spring GraphQL", "1.2.2") { + considerSnapshots() group("org.springframework.graphql") { modules = [ "spring-graphql", @@ -1413,6 +1427,7 @@ bom { } } library("Spring HATEOAS", "2.1.2") { + considerSnapshots() group("org.springframework.hateoas") { modules = [ "spring-hateoas" @@ -1420,6 +1435,7 @@ bom { } } library("Spring Integration", "6.1.2") { + considerSnapshots() group("org.springframework.integration") { imports = [ "spring-integration-bom" @@ -1427,6 +1443,7 @@ bom { } } library("Spring Kafka", "3.0.10") { + considerSnapshots() group("org.springframework.kafka") { modules = [ "spring-kafka", @@ -1435,6 +1452,7 @@ bom { } } library("Spring LDAP", "3.1.1") { + considerSnapshots() group("org.springframework.ldap") { modules = [ "spring-ldap-core", @@ -1445,6 +1463,7 @@ bom { } } library("Spring RESTDocs", "3.0.0") { + considerSnapshots() group("org.springframework.restdocs") { imports = [ "spring-restdocs-bom" @@ -1452,6 +1471,7 @@ bom { } } library("Spring Retry", "2.0.2") { + considerSnapshots() group("org.springframework.retry") { modules = [ "spring-retry" @@ -1459,6 +1479,7 @@ bom { } } library("Spring Security", "6.1.3") { + considerSnapshots() group("org.springframework.security") { imports = [ "spring-security-bom" @@ -1466,6 +1487,7 @@ bom { } } library("Spring Session", "3.1.2") { + considerSnapshots() prohibit { startsWith(["Apple-", "Bean-", "Corn-", "Dragonfruit-"]) because "Spring Session switched to numeric version numbers" @@ -1477,6 +1499,7 @@ bom { } } library("Spring WS", "4.0.5") { + considerSnapshots() group("org.springframework.ws") { imports = [ "spring-ws-bom"