diff --git a/release-tools/src/main/java/org/springframework/data/release/model/Projects.java b/release-tools/src/main/java/org/springframework/data/release/model/Projects.java index ecb2eb7..09ed96d 100644 --- a/release-tools/src/main/java/org/springframework/data/release/model/Projects.java +++ b/release-tools/src/main/java/org/springframework/data/release/model/Projects.java @@ -39,7 +39,8 @@ import org.jgrapht.traverse.TopologicalOrderIterator; */ public class Projects { - public static final Project BOM, COMMONS, BUILD, REST, JDBC, JPA, MONGO_DB, NEO4J, SOLR, COUCHBASE, CASSANDRA, + public static final Project BOM, COMMONS, BUILD, REST, JDBC, RELATIONAL, JPA, MONGO_DB, NEO4J, SOLR, COUCHBASE, + CASSANDRA, ELASTICSEARCH, R2DBC, REDIS, GEMFIRE, KEY_VALUE, ENVERS, LDAP, GEODE; public static final List PROJECTS; @@ -82,8 +83,13 @@ public class Projects { REDIS = new Project("DATAREDIS", "Redis", Tracker.GITHUB).withDependencies(KEY_VALUE); - JDBC = new Project("DATAJDBC", "JDBC", Tracker.GITHUB) - .withAdditionalArtifacts(ArtifactCoordinates.SPRING_DATA.artifacts("spring-data-relational")) + JDBC = new Project("DATAJDBC", "Relational", Tracker.GITHUB) + .withAdditionalArtifacts( + ArtifactCoordinates.SPRING_DATA.artifacts("spring-data-relational", "spring-data-jdbc")) + .withDependencies(COMMONS); + + RELATIONAL = new Project("DATAJDBC", "Relational", Tracker.GITHUB).withAdditionalArtifacts( + ArtifactCoordinates.SPRING_DATA.artifacts("spring-data-relational", "spring-data-jdbc", "spring-data-r2dbc")) .withDependencies(COMMONS); R2DBC = new Project("DATAR2DBC", "R2DBC", Tracker.GITHUB).withDependencies(COMMONS, JDBC); @@ -109,7 +115,8 @@ public class Projects { LDAP = new Project("DATALDAP", "LDAP", Tracker.GITHUB).withDependencies(COMMONS); // Specify build order to avoid maven dependency errors during build. - List projects = Arrays.asList(BUILD, COMMONS, JPA, JDBC, MONGO_DB, NEO4J, SOLR, COUCHBASE, CASSANDRA, + List projects = Arrays.asList(BUILD, COMMONS, JPA, JDBC, RELATIONAL, MONGO_DB, NEO4J, SOLR, COUCHBASE, + CASSANDRA, ELASTICSEARCH, REDIS, GEMFIRE, REST, KEY_VALUE, ENVERS, LDAP, GEODE, R2DBC); DefaultDirectedGraph graph = new DefaultDirectedGraph<>(DefaultEdge.class); diff --git a/release-tools/src/main/java/org/springframework/data/release/model/ReleaseTrains.java b/release-tools/src/main/java/org/springframework/data/release/model/ReleaseTrains.java index 4d996fb..a79e795 100644 --- a/release-tools/src/main/java/org/springframework/data/release/model/ReleaseTrains.java +++ b/release-tools/src/main/java/org/springframework/data/release/model/ReleaseTrains.java @@ -75,9 +75,11 @@ public class ReleaseTrains { .withIterations(new Train.Iterations(M1, M2, M3, M4, M5, RC1, RC2, GA, SR1, SR2, SR3, SR4, SR5)); TURING = PASCAL.next("Turing", Transition.MAJOR, // - new Module(R2DBC, "3.0")) // + new Module(RELATIONAL, "3.0")) // .withCalver("2022.0") // .filterModules(module -> !module.getProject().equals(ENVERS)) + .filterModules(module -> !module.getProject().equals(R2DBC)) + .filterModules(module -> !module.getProject().equals(JDBC)) // filter "old" JDBC without R2DBC submodule .withAlwaysUseBranch(true) .withIterations(new Train.Iterations(M1, M2, M3, M4, M5, RC1, RC2, GA, SR1, SR2, SR3, SR4, SR5)); diff --git a/release-tools/src/main/java/org/springframework/data/release/sagan/MaintainedVersion.java b/release-tools/src/main/java/org/springframework/data/release/sagan/MaintainedVersion.java index b5f0e15..a38000b 100644 --- a/release-tools/src/main/java/org/springframework/data/release/sagan/MaintainedVersion.java +++ b/release-tools/src/main/java/org/springframework/data/release/sagan/MaintainedVersion.java @@ -16,6 +16,7 @@ package org.springframework.data.release.sagan; import lombok.Value; +import lombok.With; import java.time.LocalDate; import java.util.Comparator; @@ -37,7 +38,7 @@ import org.springframework.util.Assert; @Value(staticConstructor = "of") class MaintainedVersion implements Comparable { - Project project; + @With Project project; ArtifactVersion version; Train train; @Nullable LocalDate releaseDate; diff --git a/release-tools/src/main/java/org/springframework/data/release/sagan/SaganCommands.java b/release-tools/src/main/java/org/springframework/data/release/sagan/SaganCommands.java index 9499acf..80df756 100644 --- a/release-tools/src/main/java/org/springframework/data/release/sagan/SaganCommands.java +++ b/release-tools/src/main/java/org/springframework/data/release/sagan/SaganCommands.java @@ -19,12 +19,15 @@ import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.experimental.FieldDefaults; +import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import org.springframework.data.release.CliComponent; import org.springframework.data.release.TimedCommand; +import org.springframework.data.release.git.GitOperations; import org.springframework.data.release.model.ReleaseTrains; +import org.springframework.data.release.model.Train; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; import org.springframework.stereotype.Component; @@ -42,12 +45,18 @@ import org.springframework.stereotype.Component; class SaganCommands extends TimedCommand { SaganOperations sagan; + GitOperations git; @CliCommand("sagan update") - public void updateProjectInformation(@CliOption(key = "", mandatory = true) String trains) { + public void updateProjectInformation(@CliOption(key = "", mandatory = true) String trainNames) { - sagan.updateProjectMetadata(Stream.of(trains.split(","))// + List trains = Stream.of(trainNames.split(","))// .map(ReleaseTrains::getTrainByName) // - .collect(Collectors.toList())); + .collect(Collectors.toList()); + + // ensure we have all git repositories available + trains.forEach(git::checkout); + + sagan.updateProjectMetadata(trains); } } diff --git a/release-tools/src/main/java/org/springframework/data/release/sagan/SaganOperations.java b/release-tools/src/main/java/org/springframework/data/release/sagan/SaganOperations.java index b1ff794..1687119 100644 --- a/release-tools/src/main/java/org/springframework/data/release/sagan/SaganOperations.java +++ b/release-tools/src/main/java/org/springframework/data/release/sagan/SaganOperations.java @@ -20,6 +20,7 @@ import lombok.RequiredArgsConstructor; import lombok.experimental.FieldDefaults; import java.time.LocalDate; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -76,15 +77,14 @@ class SaganOperations { Map versions = findVersions(trains); - ExecutionUtils.run(executor, Streamable.of(versions.entrySet()), - entry -> { + ExecutionUtils.run(executor, Streamable.of(versions.entrySet()), entry -> { - if (entry.getKey() == Projects.BOM) { - return; - } + if (entry.getKey() == Projects.BOM) { + return; + } - client.updateProjectMetadata(entry.getKey(), entry.getValue()); - }); + client.updateProjectMetadata(entry.getKey(), entry.getValue()); + }); } /** @@ -104,13 +104,66 @@ class SaganOperations { Assert.notNull(trains, "Trains must not be null!"); - return ExecutionUtils.runAndReturn(executor, Streamable.of(trains), train -> { + Map versions = ExecutionUtils.runAndReturn(executor, Streamable.of(trains), train -> { return ExecutionUtils.runAndReturn(executor, Streamable.of(() -> train.stream().filter(module -> !TO_FILTER.contains(module.getProject()))), module -> { return getLatestVersion(module, train); }); }).stream().flatMap(Collection::stream).flatMap(Collection::stream).collect( Collectors.groupingBy(MaintainedVersion::getProject, ListWrapperCollector.collectInto(MaintainedVersions::of))); + + // Migration because of the R2DBC merge into Spring Data Relational and project rename to Relational + versions.put(Projects.R2DBC, MaintainedVersions.of(getR2dbcVersions(versions))); + versions.put(Projects.RELATIONAL, MaintainedVersions.of(getRelationalVersions(versions))); + + versions.remove(Projects.JDBC); + + return versions; + } + + /** + * Copy Relational versions into R2DBC as we feed two projects (JDBC, R2DBC) from {@link Projects#RELATIONAL}. + * + * @param versions + * @return + */ + private List getR2dbcVersions(Map versions) { + + List r2dbcVersions = new ArrayList<>( + versions.getOrDefault(Projects.R2DBC, MaintainedVersions.of()).toList()); + + MaintainedVersions relationalVersions = versions.get(Projects.RELATIONAL); + + for (MaintainedVersion relationalVersion : relationalVersions) { + if (relationalVersion.getVersion().getVersion().getMajor() >= 3) { + r2dbcVersions.add(relationalVersion.withProject(Projects.R2DBC)); + } + } + return r2dbcVersions; + } + + /** + * Merge JDBC versions into Relational to avoid having two projects mapping to Spring Data JDBC in Sagan. + * + * @param versions + * @return + */ + private List getRelationalVersions(Map versions) { + + List relationalVersions = new ArrayList<>( + versions.getOrDefault(Projects.RELATIONAL, MaintainedVersions.of()).toList()); + + if (versions.containsKey(Projects.JDBC)) { + + MaintainedVersions jdbcVersions = versions.get(Projects.JDBC); + + for (MaintainedVersion jdbcVersion : jdbcVersions) { + if (jdbcVersion.getVersion().getVersion().getMajor() < 3) { + relationalVersions.add(jdbcVersion.withProject(Projects.RELATIONAL)); + } + } + } + return relationalVersions; } private List getLatestVersion(Module module, Train train) { diff --git a/release-tools/src/main/java/org/springframework/data/release/sagan/SaganProperties.java b/release-tools/src/main/java/org/springframework/data/release/sagan/SaganProperties.java index 7019f1e..9cca21a 100644 --- a/release-tools/src/main/java/org/springframework/data/release/sagan/SaganProperties.java +++ b/release-tools/src/main/java/org/springframework/data/release/sagan/SaganProperties.java @@ -95,6 +95,15 @@ class SaganProperties { } private static String getProjectPathSegment(Project project) { - return Projects.BUILD.equals(project) ? "spring-data" : project.getFolderName(); + + if (Projects.BUILD.equals(project)) { + return "spring-data"; + } + + if (Projects.RELATIONAL.equals(project) || Projects.JDBC.equals(project)) { + return "spring-data-jdbc"; + } + + return project.getFolderName(); } }