From 45c86d2b42aea8056399d1f4b8aebaec2e6d55fa Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 16 Apr 2014 14:35:12 +0200 Subject: [PATCH] Further improvements: Added functionality to prepare a release: - Update the Spring Data Commons version a project relies on to the one included in the train iteration. - Switch to the correct Maven repository matching the current release iteration (milestone, release). - Update the BOM pom.xml in Spring Build project. Upgraded to XmlBeam 1.1.4 get the XML manipulation working properly. Fixed XmlBeam configuration to write XML headers to XML files. Fixed the AnnouncementOperations to render the appropriate version number for service releases. Added further Git commands to be able to reset the repositories in the workspace. Let the changelog render the full artifact version. Ignored integration tests for now. --- pom.xml | 2 +- .../announcement/AnnouncementOperations.java | 10 ++- .../data/release/cli/JiraCommands.java | 16 ++-- .../data/release/cli/ReleaseCommands.java | 12 ++- .../data/release/git/GiCommands.java | 14 ++++ .../data/release/git/GitOperations.java | 18 +++- .../data/release/jira/Changelog.java | 11 +-- .../data/release/jira/JiraConnector.java | 4 +- .../data/release/jira/JiraVersion.java | 8 ++ .../data/release/jira/JqlQuery.java | 15 +++- .../data/release/jira/RestJiraConnector.java | 19 +++-- .../data/release/maven/Artifact.java | 4 +- .../data/release/maven/MavenConfig.java | 31 +------ .../data/release/maven/MavenOperations.java | 71 +++++++++++++--- .../data/release/maven/Pom.java | 19 +++-- .../data/release/misc/ReleaseOperations.java | 83 +++++++++++++++++++ .../data/release/model/ArtifactVersion.java | 26 +++++- .../data/release/model/Module.java | 4 + .../data/release/model/ModuleIteration.java | 9 +- .../data/release/model/Train.java | 11 +++ .../cli/ReleaseCommandsIntegrationTests.java | 2 + .../git/GitOperationsIntegrationTests.java | 3 + .../release/jira/JiraVersionUnitTests.java | 12 +-- .../ArtifactVersionUnitTests.java} | 5 +- 24 files changed, 323 insertions(+), 86 deletions(-) create mode 100644 src/main/java/org/springframework/data/release/misc/ReleaseOperations.java rename src/test/java/org/springframework/data/release/{maven/MavenVersionUnitTests.java => model/ArtifactVersionUnitTests.java} (94%) diff --git a/pom.xml b/pom.xml index 086a4c8..70b5ec5 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ org.xmlbeam xmlprojector - 1.1.0 + 1.1.4 diff --git a/src/main/java/org/springframework/data/release/announcement/AnnouncementOperations.java b/src/main/java/org/springframework/data/release/announcement/AnnouncementOperations.java index d0975c4..651f8d0 100644 --- a/src/main/java/org/springframework/data/release/announcement/AnnouncementOperations.java +++ b/src/main/java/org/springframework/data/release/announcement/AnnouncementOperations.java @@ -17,6 +17,7 @@ package org.springframework.data.release.announcement; import org.springframework.data.release.cli.StaticResources; import org.springframework.data.release.maven.Artifact; +import org.springframework.data.release.model.ArtifactVersion; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Project; @@ -50,7 +51,12 @@ public class AnnouncementOperations { builder.append("* "); builder.append(project.getFullName()).append(" "); - builder.append(module.getVersion()).append(" ").append(module.getIteration().getName()); + builder.append(ArtifactVersion.from(module).toShortString()); + + if (!iteration.isServiceIteration()) { + builder.append(" ").append(module.getIteration().getName()); + } + builder.append(" - "); Artifact artifact = new Artifact(module); @@ -77,6 +83,6 @@ public class AnnouncementOperations { public static void main(String[] args) { AnnouncementOperations operations = new AnnouncementOperations(); - System.out.println(operations.getProjectBulletpoints(ReleaseTrains.DIJKSTRA, Iteration.M1)); + System.out.println(operations.getProjectBulletpoints(ReleaseTrains.CODD, Iteration.SR2)); } } diff --git a/src/main/java/org/springframework/data/release/cli/JiraCommands.java b/src/main/java/org/springframework/data/release/cli/JiraCommands.java index e357fdd..a764689 100644 --- a/src/main/java/org/springframework/data/release/cli/JiraCommands.java +++ b/src/main/java/org/springframework/data/release/cli/JiraCommands.java @@ -73,11 +73,17 @@ public class JiraCommands implements CommandMarker { } @CliCommand("changelog") - public String changelog(@CliOption(key = { "", "module" }, mandatory = true) String moduleName, @CliOption( - key = { "iteration" }, mandatory = true) String iterationName) { + public String changelog(@CliOption(key = { "", "train" }, mandatory = true) String trainName, // + @CliOption(key = { "iteration" }, mandatory = true) String iterationName, // + @CliOption(key = "module") String moduleName) { - Train dijkstra = ReleaseTrains.DIJKSTRA; - return connector.getChangelogFor(dijkstra, dijkstra.getModule(moduleName), - dijkstra.getIterations().getIterationByName(iterationName)).toString(); + Train train = ReleaseTrains.getTrainByName(trainName); + Iteration iteration = train.getIteration(iterationName); + + if (StringUtils.hasText(moduleName)) { + return connector.getChangelogFor(train.getModuleIteration(iteration, moduleName)).toString(); + } + + return ""; } } diff --git a/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java b/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java index 54eae2d..35f26e5 100644 --- a/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java +++ b/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java @@ -22,6 +22,7 @@ import org.springframework.data.release.git.GitOperations; import org.springframework.data.release.git.Tags; import org.springframework.data.release.maven.MavenOperations; import org.springframework.data.release.maven.Pom; +import org.springframework.data.release.misc.ReleaseOperations; import org.springframework.data.release.model.ArtifactVersion; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.Module; @@ -42,6 +43,7 @@ public class ReleaseCommands implements CommandMarker { private final MavenOperations maven; private final GitOperations git; + private final ReleaseOperations misc; @CliCommand("release predict") public String predictTrainAndIteration() throws Exception { @@ -86,7 +88,14 @@ public class ReleaseCommands implements CommandMarker { maven.triggerDistributionBuild(train, iteration); } - @CliCommand("release prepare") + /** + * Prepares the release of the given iteration of the given train. + * + * @param trainName the name of the release train (ignoring case). + * @param iterationName the name of the iteration. + * @throws Exception + */ + @CliCommand(value = "release prepare", help = "Prepares the release of the iteration of the given train.") public void prepare(@CliOption(key = { "", "train" }, mandatory = true) String trainName, @CliOption( key = "iteration", mandatory = true) String iterationName) throws Exception { @@ -94,6 +103,7 @@ public class ReleaseCommands implements CommandMarker { Iteration iteration = train.getIteration(iterationName); git.prepare(train, iteration); + misc.prepareChangelogs(train, iteration); for (Module module : train) { maven.prepareProject(train, iteration, module.getProject()); diff --git a/src/main/java/org/springframework/data/release/git/GiCommands.java b/src/main/java/org/springframework/data/release/git/GiCommands.java index 1eb786e..da7c504 100644 --- a/src/main/java/org/springframework/data/release/git/GiCommands.java +++ b/src/main/java/org/springframework/data/release/git/GiCommands.java @@ -61,4 +61,18 @@ public class GiCommands implements CommandMarker { return StringUtils.collectionToDelimitedString(git.getTags(project).asList(), "\n"); } + + @CliCommand("git reset") + public void reset(@CliOption(key = { "", "train" }, mandatory = true) String trainName, @CliOption(key = "iteration", + mandatory = true) String iterationName) throws Exception { + git.reset(ReleaseTrains.getTrainByName(trainName)); + } + + @CliCommand("git prepare") + public void prepare(@CliOption(key = { "", "train" }, mandatory = true) String trainName, @CliOption( + key = "iteration", mandatory = true) String iterationName) throws Exception { + + Train train = ReleaseTrains.getTrainByName(trainName); + git.prepare(train, train.getIteration(iterationName)); + } } diff --git a/src/main/java/org/springframework/data/release/git/GitOperations.java b/src/main/java/org/springframework/data/release/git/GitOperations.java index de4711f..03f026d 100644 --- a/src/main/java/org/springframework/data/release/git/GitOperations.java +++ b/src/main/java/org/springframework/data/release/git/GitOperations.java @@ -36,6 +36,7 @@ import org.springframework.data.release.model.Project; import org.springframework.data.release.model.Train; import org.springframework.shell.support.logging.HandlerUtils; import org.springframework.stereotype.Component; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -57,6 +58,21 @@ public class GitOperations { return new GitProject(project, server); } + /** + * Resets the repositories for all modules of the given {@link Train}. + * + * @param train must not be {@literal null}. + * @throws Exception + */ + public void reset(Train train) throws Exception { + + Assert.notNull(train, "Train must not be null!"); + + for (Module module : train) { + osCommandOperations.executeCommand("git reset --hard", module.getProject()).get(); + } + } + /** * Checks out all projects of the given {@link Train} at the tags for the given {@link Iteration}. * @@ -93,7 +109,7 @@ public class GitOperations { Branch branch = Branch.from(module); - update(module.getProject()); + update(module.getProject()).get(); String checkoutCommand = String.format("git checkout %s", branch); osCommandOperations.executeCommand(checkoutCommand, module.getProject()).get(); diff --git a/src/main/java/org/springframework/data/release/jira/Changelog.java b/src/main/java/org/springframework/data/release/jira/Changelog.java index e8f197f..8397c9a 100644 --- a/src/main/java/org/springframework/data/release/jira/Changelog.java +++ b/src/main/java/org/springframework/data/release/jira/Changelog.java @@ -22,8 +22,8 @@ import lombok.AccessLevel; import lombok.EqualsAndHashCode; import lombok.RequiredArgsConstructor; -import org.springframework.data.release.model.Iteration; -import org.springframework.data.release.model.Module; +import org.springframework.data.release.model.ArtifactVersion; +import org.springframework.data.release.model.ModuleIteration; import org.springframework.format.datetime.DateFormatter; import org.springframework.shell.support.util.OsUtils; @@ -34,8 +34,7 @@ import org.springframework.shell.support.util.OsUtils; @EqualsAndHashCode public class Changelog { - private final Module module; - private final Iteration iteration; + private final ModuleIteration module; private final Tickets tickets; /* @@ -45,7 +44,9 @@ public class Changelog { @Override public String toString() { - String headline = String.format("Changes in version %s (%s)", module.getVersion(), + ArtifactVersion version = ArtifactVersion.from(module); + + String headline = String.format("Changes in version %s (%s)", version, new DateFormatter("YYYY-MM-dd").print(new Date(), Locale.US)); StringBuilder builder = new StringBuilder(headline).append(OsUtils.LINE_SEPARATOR); diff --git a/src/main/java/org/springframework/data/release/jira/JiraConnector.java b/src/main/java/org/springframework/data/release/jira/JiraConnector.java index e30f8d5..22914a1 100644 --- a/src/main/java/org/springframework/data/release/jira/JiraConnector.java +++ b/src/main/java/org/springframework/data/release/jira/JiraConnector.java @@ -16,7 +16,7 @@ package org.springframework.data.release.jira; import org.springframework.data.release.model.Iteration; -import org.springframework.data.release.model.Module; +import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Train; /** @@ -39,5 +39,5 @@ public interface JiraConnector { void closeIteration(Train train, Iteration iteration, Credentials credentials); - Changelog getChangelogFor(Train train, Module module, Iteration iteration); + Changelog getChangelogFor(ModuleIteration iteration); } diff --git a/src/main/java/org/springframework/data/release/jira/JiraVersion.java b/src/main/java/org/springframework/data/release/jira/JiraVersion.java index b2fea87..64a622f 100644 --- a/src/main/java/org/springframework/data/release/jira/JiraVersion.java +++ b/src/main/java/org/springframework/data/release/jira/JiraVersion.java @@ -19,6 +19,7 @@ import lombok.Value; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.Module; +import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Train; /** @@ -31,6 +32,13 @@ class JiraVersion { private final Train train; private final Iteration iteration; + public JiraVersion(ModuleIteration moduleIteration) { + + this.module = moduleIteration.getModule(); + this.iteration = moduleIteration.getIteration(); + this.train = moduleIteration.getTrain(); + } + /* * (non-Javadoc) * @see java.lang.Object#toString() diff --git a/src/main/java/org/springframework/data/release/jira/JqlQuery.java b/src/main/java/org/springframework/data/release/jira/JqlQuery.java index bc71f64..b59806c 100644 --- a/src/main/java/org/springframework/data/release/jira/JqlQuery.java +++ b/src/main/java/org/springframework/data/release/jira/JqlQuery.java @@ -21,7 +21,7 @@ import java.util.List; import lombok.Value; import org.springframework.data.release.model.Iteration; -import org.springframework.data.release.model.Module; +import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.ReleaseTrains; import org.springframework.data.release.model.Train; import org.springframework.util.StringUtils; @@ -44,18 +44,25 @@ class JqlQuery { return new JqlQuery(String.format("%s ORDER BY %s", query, orderBy)); } + public static JqlQuery from(ModuleIteration iteration) { + + JiraVersion version = new JiraVersion(iteration); + + return new JqlQuery(String.format(PROJECT_VERSION_TEMPLATE, iteration.getProjectKey(), version)); + } + public static JqlQuery from(Train train, Iteration iteration) { List parts = new ArrayList<>(); - for (Module module : train) { + for (ModuleIteration module : train.getModuleIterations(iteration)) { if (ReleaseTrains.BUILD.equals(module.getProject())) { continue; } - JiraVersion version = new JiraVersion(module, train, iteration); - parts.add(String.format(PROJECT_VERSION_TEMPLATE, module.getProject().getKey(), version)); + JiraVersion version = new JiraVersion(module); + parts.add(String.format(PROJECT_VERSION_TEMPLATE, module.getProjectKey(), version)); } return new JqlQuery(StringUtils.collectionToDelimitedString(parts, " OR ")); diff --git a/src/main/java/org/springframework/data/release/jira/RestJiraConnector.java b/src/main/java/org/springframework/data/release/jira/RestJiraConnector.java index 11a74da..812fbb6 100644 --- a/src/main/java/org/springframework/data/release/jira/RestJiraConnector.java +++ b/src/main/java/org/springframework/data/release/jira/RestJiraConnector.java @@ -28,8 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.release.model.Iteration; -import org.springframework.data.release.model.Module; -import org.springframework.data.release.model.ReleaseTrains; +import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Train; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -153,10 +152,20 @@ class RestJiraConnector implements JiraConnector { * @see org.springframework.data.release.jira.JiraConnector#getChangelogFor(org.springframework.data.release.model.Module, org.springframework.data.release.model.Iteration) */ @Override - public Changelog getChangelogFor(Train train, Module module, Iteration iteration) { + public Changelog getChangelogFor(ModuleIteration module) { - Tickets tickets = getTicketsFor(ReleaseTrains.DIJKSTRA, iteration, null); + Map parameters = new HashMap<>(); + parameters.put("jql", JqlQuery.from(module)); + parameters.put("fields", "summary,fixVersions"); + parameters.put("startAt", 0); - return new Changelog(module, iteration, tickets); + JiraIssues issues = operations.getForObject(SEARCH_TEMPLATE, JiraIssues.class, parameters); + List tickets = new ArrayList<>(); + + for (JiraIssue issue : issues) { + tickets.add(new Ticket(issue.getKey(), issue.getFields().getSummary())); + } + + return new Changelog(module, new Tickets(tickets, tickets.size())); } } diff --git a/src/main/java/org/springframework/data/release/maven/Artifact.java b/src/main/java/org/springframework/data/release/maven/Artifact.java index cfc41a4..7727d42 100644 --- a/src/main/java/org/springframework/data/release/maven/Artifact.java +++ b/src/main/java/org/springframework/data/release/maven/Artifact.java @@ -15,6 +15,8 @@ */ package org.springframework.data.release.maven; +import lombok.Getter; + import org.springframework.data.release.model.ArtifactVersion; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.ReleaseTrains; @@ -31,7 +33,7 @@ public class Artifact { private final ModuleIteration module; private final Repository repository; - private final ArtifactVersion version; + private final @Getter ArtifactVersion version; /** * Creates a new {@link Artifact} for the given {@link ModuleIteration}. diff --git a/src/main/java/org/springframework/data/release/maven/MavenConfig.java b/src/main/java/org/springframework/data/release/maven/MavenConfig.java index ac38b82..7e10646 100644 --- a/src/main/java/org/springframework/data/release/maven/MavenConfig.java +++ b/src/main/java/org/springframework/data/release/maven/MavenConfig.java @@ -17,14 +17,11 @@ package org.springframework.data.release.maven; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.release.model.ArtifactVersion; import org.xmlbeam.ProjectionFactory; import org.xmlbeam.XBProjector; import org.xmlbeam.XBProjector.Flags; import org.xmlbeam.config.DefaultXMLFactoriesConfig; import org.xmlbeam.config.DefaultXMLFactoriesConfig.NamespacePhilosophy; -import org.xmlbeam.types.DefaultTypeConverter; -import org.xmlbeam.types.TypeConverter; /** * @author Oliver Gierke @@ -35,38 +32,12 @@ class MavenConfig { @Bean public ProjectionFactory projectionFactory() { - TypeConverter converter = new DefaultTypeConverter().setConversionForType(ArtifactVersion.class, - new ArtifactVersionConverter()); - DefaultXMLFactoriesConfig config = new DefaultXMLFactoriesConfig(); config.setNamespacePhilosophy(NamespacePhilosophy.AGNOSTIC); + config.setOmitXMLDeclaration(false); XBProjector projector = new XBProjector(config, Flags.TO_STRING_RENDERS_XML); - projector.config().setTypeConverter(converter); return projector; } - - /** - * Custom converter to be able to use {@link ArtifactVersion} directly from within an XmlBeam projection. - * - * @author Oliver Gierke - */ - private static class ArtifactVersionConverter extends DefaultTypeConverter.Conversion { - - private static final long serialVersionUID = 1L; - - public ArtifactVersionConverter() { - super(null); - } - - /* - * (non-Javadoc) - * @see org.xmlbeam.types.DefaultTypeConverter.Conversion#convert(java.lang.String) - */ - @Override - public ArtifactVersion convert(String data) { - return ArtifactVersion.parse(data); - } - } } diff --git a/src/main/java/org/springframework/data/release/maven/MavenOperations.java b/src/main/java/org/springframework/data/release/maven/MavenOperations.java index ad61b18..4098ad0 100644 --- a/src/main/java/org/springframework/data/release/maven/MavenOperations.java +++ b/src/main/java/org/springframework/data/release/maven/MavenOperations.java @@ -43,6 +43,7 @@ import org.xmlbeam.io.XBFileIO; @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class MavenOperations { + private static final String COMMONS_VERSION_PROPERTY = "springdata.commons"; private static final Logger LOGGER = HandlerUtils.getLogger(MavenOperations.class); private static final String POM_XML = "pom.xml"; @@ -56,29 +57,38 @@ public class MavenOperations { return projectionFactory.io().file(file).read(Pom.class); } - public void prepareProject(Train train, Iteration iteration, Project project) throws IOException { + public void prepareProject(Train train, Iteration iteration, final Project project) throws Exception { + + updateBomPom(train, iteration); if (ReleaseTrains.BUILD.equals(project)) { return; } - ArtifactVersion commonsVersion = train.getModuleVersion(ReleaseTrains.COMMONS, iteration); - ArtifactVersion buildVersion = train.getModuleVersion(ReleaseTrains.BUILD, iteration); - Repository repository = new Repository(iteration); + final ArtifactVersion commonsVersion = train.getModuleVersion(ReleaseTrains.COMMONS, iteration); + final ArtifactVersion buildVersion = train.getModuleVersion(ReleaseTrains.BUILD, iteration); + final Repository repository = new Repository(iteration); File file = workspace.getFile(POM_XML, project); - XBFileIO io = projectionFactory.io().file(file); - Pom pom = io.read(Pom.class); - if (!project.equals(ReleaseTrains.COMMONS)) { - pom.setProperty("spring.data.commons", commonsVersion); - } + execute(file, new PomCallback() { - pom.setParentVersion(buildVersion); - pom.setRepositoryId(repository.getSnapshotId(), repository.getId()); - pom.setRepositoryUrl(repository.getId(), repository.getUrl()); + @Override + public Pom doWith(Pom pom) { - io.write(pom); + if (!project.equals(ReleaseTrains.COMMONS)) { + + System.out.println(pom.getProperty(COMMONS_VERSION_PROPERTY)); + pom.setProperty(COMMONS_VERSION_PROPERTY, commonsVersion); + } + + pom.setParentVersion(buildVersion); + pom.setRepositoryId("spring-libs-snapshot", "spring-libs-release"); + pom.setRepositoryUrl(repository.getId(), repository.getUrl()); + + return pom; + } + }); } /** @@ -130,4 +140,39 @@ public class MavenOperations { private boolean isMavenProject(Project project) { return workspace.getFile(POM_XML, project).exists(); } + + private void updateBomPom(final Train train, final Iteration iteration) throws Exception { + + File bomPomFile = workspace.getFile("bom/pom.xml", ReleaseTrains.BUILD); + + execute(bomPomFile, new PomCallback() { + + @Override + public Pom doWith(Pom pom) { + + for (ModuleIteration module : train.getModuleIterations(iteration, ReleaseTrains.BUILD)) { + + Artifact artifact = new Artifact(module); + pom.setDependencyVersion(artifact.getArtifactId(), artifact.getVersion()); + } + + return pom; + } + }); + } + + private void execute(File file, PomCallback callback) throws Exception { + + XBFileIO io = projectionFactory.io().file(file); + Pom pom = io.read(Pom.class); + + pom = callback.doWith(pom); + + io.write(pom); + } + + private interface PomCallback { + + public Pom doWith(Pom pom); + } } diff --git a/src/main/java/org/springframework/data/release/maven/Pom.java b/src/main/java/org/springframework/data/release/maven/Pom.java index 7fe5471..f48b8d5 100644 --- a/src/main/java/org/springframework/data/release/maven/Pom.java +++ b/src/main/java/org/springframework/data/release/maven/Pom.java @@ -34,21 +34,30 @@ public interface Pom { @XBWrite("/project/version") void setVersion(String version); - @XBRead("/project/repositories/repository[id=\"spring-libs-snapshot\"]") - Repository getSpringRepository(); - @XBWrite("/project/parent/version") void setParentVersion(ArtifactVersion version); + @XBRead("/project/properties/{0}") + String getProperty(String property); + @XBWrite("/project/properties/{0}") void setProperty(String property, @XBValue ArtifactVersion value); - @XBWrite("/project/repositories/repository[id={0}]/id") + @XBWrite("/project/repositories/repository[id=''{0}'']/id") void setRepositoryId(String oldId, @XBValue String newId); - @XBWrite("/project/repositories/repository[id={0}]/url") + @XBWrite("/project/repositories/repository[id=''{0}'']/url") void setRepositoryUrl(String id, @XBValue String url); + /** + * Sets the version of the dependency with the given artifact identifier to the given {@link ArtifactVersion}. + * + * @param artifactId + * @param version + */ + @XBWrite("/project/dependencies/dependency[artifactId=''{0}'']/version") + Pom setDependencyVersion(String artifactId, @XBValue ArtifactVersion version); + public interface Repository { @XBRead("child::id") diff --git a/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java b/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java new file mode 100644 index 0000000..4053584 --- /dev/null +++ b/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java @@ -0,0 +1,83 @@ +/* + * Copyright 2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.release.misc; + +import java.io.File; +import java.nio.charset.Charset; +import java.util.Scanner; + +import lombok.RequiredArgsConstructor; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.release.io.Workspace; +import org.springframework.data.release.jira.Changelog; +import org.springframework.data.release.jira.JiraConnector; +import org.springframework.data.release.model.Iteration; +import org.springframework.data.release.model.ModuleIteration; +import org.springframework.data.release.model.ReleaseTrains; +import org.springframework.data.release.model.Train; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; + +import com.google.common.io.Files; + +/** + * @author Oliver Gierke + */ +@Component +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +public class ReleaseOperations { + + private final JiraConnector jira; + private final Workspace workspace; + + /** + * Creates {@link Changelog} instances for all modules of the given {@link Train} and {@link Iteration}. + * + * @param train must not be {@literal null}. + * @param iteration must not be {@literal null}. + * @throws Exception + */ + public void prepareChangelogs(Train train, Iteration iteration) throws Exception { + + Assert.notNull(train, "Release train must not be null!"); + Assert.notNull(iteration, "Iteration must not be null!"); + + for (ModuleIteration module : train.getModuleIterations(iteration, ReleaseTrains.BUILD)) { + + Changelog changelog = jira.getChangelogFor(module); + File file = workspace.getFile("src/main/resources/changelog.txt", module.getProject()); + StringBuilder builder = new StringBuilder(); + + try (Scanner scanner = new Scanner(file)) { + + // Copy headline + builder.append(scanner.nextLine()).append("\n"); + builder.append(scanner.nextLine()).append("\n"); + + // Add new changelog + builder.append(changelog.toString()); + + // Append existing + while (scanner.hasNextLine()) { + builder.append(scanner.nextLine()).append("\n"); + } + } + + Files.write(builder, file, Charset.forName("UTF-8")); + } + } +} diff --git a/src/main/java/org/springframework/data/release/model/ArtifactVersion.java b/src/main/java/org/springframework/data/release/model/ArtifactVersion.java index 85343c7..6034d0f 100644 --- a/src/main/java/org/springframework/data/release/model/ArtifactVersion.java +++ b/src/main/java/org/springframework/data/release/model/ArtifactVersion.java @@ -98,7 +98,7 @@ public class ArtifactVersion implements Comparable { } /** - * Returns the release version for the current a + * Returns the release version for the current one. * * @return */ @@ -106,14 +106,29 @@ public class ArtifactVersion implements Comparable { return new ArtifactVersion(version, RELEASE_SUFFIX); } + /** + * Returns the snapshot version of the current one. + * + * @return + */ public ArtifactVersion getSnapshotVersion() { return new ArtifactVersion(version, SNAPSHOT_SUFFIX); } + /** + * Returns whether the version is a release version. + * + * @return + */ public boolean isReleaseVersion() { return suffix.equals(RELEASE_SUFFIX); } + /** + * Returns whether the version is a milestone version. + * + * @return + */ public boolean isMilestoneVersion() { return suffix.matches(MILESTONE_SUFFIX); } @@ -148,4 +163,13 @@ public class ArtifactVersion implements Comparable { public String toString() { return String.format("%s.%s", version.toMajorMinorBugfix(), suffix); } + + /** + * Returns the {@link String} of the plain version (read: x.y.z, ommitting trailing bugfix zeros). + * + * @return + */ + public String toShortString() { + return version.toString(); + } } diff --git a/src/main/java/org/springframework/data/release/model/Module.java b/src/main/java/org/springframework/data/release/model/Module.java index 5f21ce9..e228bda 100644 --- a/src/main/java/org/springframework/data/release/model/Module.java +++ b/src/main/java/org/springframework/data/release/model/Module.java @@ -43,6 +43,10 @@ public class Module { : new Iteration(customFirstIteration, Iteration.RC1); } + public boolean hasName(String name) { + return project.getName().equalsIgnoreCase(name); + } + public boolean hasCustomFirstIteration() { return customFirstIteration != null; } diff --git a/src/main/java/org/springframework/data/release/model/ModuleIteration.java b/src/main/java/org/springframework/data/release/model/ModuleIteration.java index 190cbe5..62a8e09 100644 --- a/src/main/java/org/springframework/data/release/model/ModuleIteration.java +++ b/src/main/java/org/springframework/data/release/model/ModuleIteration.java @@ -16,6 +16,7 @@ package org.springframework.data.release.model; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.RequiredArgsConstructor; /** @@ -25,9 +26,9 @@ import lombok.RequiredArgsConstructor; @EqualsAndHashCode public class ModuleIteration implements IterationVersion { - private final Module module; + private final @Getter Module module; private final Iteration iteration; - private final Train train; + private final @Getter Train train; public ProjectKey getProjectKey() { return module.getProject().getKey(); @@ -46,6 +47,10 @@ public class ModuleIteration implements IterationVersion { return module.getVersion(); } + /* + * (non-Javadoc) + * @see org.springframework.data.release.model.IterationVersion#getIteration() + */ public Iteration getIteration() { return module.hasCustomFirstIteration() ? module.getCustomFirstIteration() : this.iteration; } diff --git a/src/main/java/org/springframework/data/release/model/Train.java b/src/main/java/org/springframework/data/release/model/Train.java index bef5df1..758df5b 100644 --- a/src/main/java/org/springframework/data/release/model/Train.java +++ b/src/main/java/org/springframework/data/release/model/Train.java @@ -92,6 +92,17 @@ public class Train implements Iterable { return new Train(name, nextModules); } + public ModuleIteration getModuleIteration(Iteration iteration, String moduleName) { + + for (Module module : this) { + if (module.hasName(moduleName)) { + return new ModuleIteration(module, iteration, this); + } + } + + return null; + } + public Iterable getModuleIterations(Iteration iteration) { return getModuleIterations(iteration, new Project[0]); } diff --git a/src/test/java/org/springframework/data/release/cli/ReleaseCommandsIntegrationTests.java b/src/test/java/org/springframework/data/release/cli/ReleaseCommandsIntegrationTests.java index 8097e67..9d0b696 100644 --- a/src/test/java/org/springframework/data/release/cli/ReleaseCommandsIntegrationTests.java +++ b/src/test/java/org/springframework/data/release/cli/ReleaseCommandsIntegrationTests.java @@ -18,6 +18,7 @@ package org.springframework.data.release.cli; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; +import org.junit.Ignore; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.release.AbstractIntegrationTests; @@ -33,6 +34,7 @@ public class ReleaseCommandsIntegrationTests extends AbstractIntegrationTests { @Autowired GitOperations git; @Test + @Ignore public void predictsReleasTrainCorrectly() throws Exception { git.update(ReleaseTrains.DIJKSTRA); diff --git a/src/test/java/org/springframework/data/release/git/GitOperationsIntegrationTests.java b/src/test/java/org/springframework/data/release/git/GitOperationsIntegrationTests.java index 5754b2a..1e9af7c 100644 --- a/src/test/java/org/springframework/data/release/git/GitOperationsIntegrationTests.java +++ b/src/test/java/org/springframework/data/release/git/GitOperationsIntegrationTests.java @@ -15,6 +15,7 @@ */ package org.springframework.data.release.git; +import org.junit.Ignore; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.release.AbstractIntegrationTests; @@ -29,11 +30,13 @@ public class GitOperationsIntegrationTests extends AbstractIntegrationTests { @Autowired GitOperations gitOperations; @Test + @Ignore public void testname() throws Exception { gitOperations.update(ReleaseTrains.CODD); } @Test + @Ignore public void showTags() throws Exception { Tags tags = gitOperations.getTags(ReleaseTrains.COMMONS); diff --git a/src/test/java/org/springframework/data/release/jira/JiraVersionUnitTests.java b/src/test/java/org/springframework/data/release/jira/JiraVersionUnitTests.java index 3ee1160..5f10ce0 100644 --- a/src/test/java/org/springframework/data/release/jira/JiraVersionUnitTests.java +++ b/src/test/java/org/springframework/data/release/jira/JiraVersionUnitTests.java @@ -20,10 +20,12 @@ import static org.junit.Assert.*; import org.junit.Test; import org.springframework.data.release.model.Iteration; -import org.springframework.data.release.model.Module; +import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.ReleaseTrains; /** + * Unit tests for {@link JiraVersion}. + * * @author Oliver Gierke */ public class JiraVersionUnitTests { @@ -44,17 +46,17 @@ public class JiraVersionUnitTests { @Test public void usesCustomModuleIterationStartVersion() { - Module commons = ReleaseTrains.DIJKSTRA.getModule("Elasticsearch"); + ModuleIteration module = ReleaseTrains.DIJKSTRA.getModuleIteration(Iteration.M1, "Elasticsearch"); - JiraVersion version = new JiraVersion(commons, ReleaseTrains.DIJKSTRA, Iteration.M1); + JiraVersion version = new JiraVersion(module); assertThat(version.toString(), is("1.0 M2 (Dijkstra)")); } private void assertIterationVersion(Iteration iteration, String expected) { - Module commons = ReleaseTrains.DIJKSTRA.getModule("Commons"); + ModuleIteration module = ReleaseTrains.DIJKSTRA.getModuleIteration(iteration, "Commons"); - JiraVersion version = new JiraVersion(commons, ReleaseTrains.DIJKSTRA, iteration); + JiraVersion version = new JiraVersion(module); assertThat(version.toString(), is(expected)); } } diff --git a/src/test/java/org/springframework/data/release/maven/MavenVersionUnitTests.java b/src/test/java/org/springframework/data/release/model/ArtifactVersionUnitTests.java similarity index 94% rename from src/test/java/org/springframework/data/release/maven/MavenVersionUnitTests.java rename to src/test/java/org/springframework/data/release/model/ArtifactVersionUnitTests.java index f13edfa..f910cea 100644 --- a/src/test/java/org/springframework/data/release/maven/MavenVersionUnitTests.java +++ b/src/test/java/org/springframework/data/release/model/ArtifactVersionUnitTests.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.maven; +package org.springframework.data.release.model; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @@ -22,13 +22,12 @@ import org.junit.Test; import org.springframework.data.release.model.ArtifactVersion; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.IterationVersion; -import org.springframework.data.release.model.SimpleIterationVersion; import org.springframework.data.release.model.Version; /** * @author Oliver Gierke */ -public class MavenVersionUnitTests { +public class ArtifactVersionUnitTests { @Test(expected = IllegalArgumentException.class) public void rejectsInvalidVersionSuffix() {