diff --git a/pom.xml b/pom.xml
index 70b5ec5..bfbff66 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,6 +61,12 @@
1.12.4
provided
+
+
+ org.springframework.plugin
+ spring-plugin-core
+ 1.0.0.RELEASE
+
org.springframework.boot
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 651f8d0..900d257 100644
--- a/src/main/java/org/springframework/data/release/announcement/AnnouncementOperations.java
+++ b/src/main/java/org/springframework/data/release/announcement/AnnouncementOperations.java
@@ -15,14 +15,16 @@
*/
package org.springframework.data.release.announcement;
+import static org.springframework.data.release.model.Projects.*;
+
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;
import org.springframework.data.release.model.ReleaseTrains;
import org.springframework.data.release.model.Train;
+import org.springframework.data.release.model.TrainIteration;
import org.springframework.util.Assert;
/**
@@ -38,25 +40,19 @@ public class AnnouncementOperations {
* @param iteration must not be {@literal null}.
* @return
*/
- public String getProjectBulletpoints(Train train, Iteration iteration) {
+ public String getProjectBulletpoints(TrainIteration iteration) {
- Assert.notNull(train, "Train must not be null!");
Assert.notNull(iteration, "Iteration must not be null!");
StringBuilder builder = new StringBuilder();
- for (ModuleIteration module : train.getModuleIterations(iteration, ReleaseTrains.BUILD)) {
+ for (ModuleIteration module : iteration.getModulesExcept(BUILD)) {
Project project = module.getProject();
builder.append("* ");
builder.append(project.getFullName()).append(" ");
- builder.append(ArtifactVersion.from(module).toShortString());
-
- if (!iteration.isServiceIteration()) {
- builder.append(" ").append(module.getIteration().getName());
- }
-
+ builder.append(module.getVersionString());
builder.append(" - ");
Artifact artifact = new Artifact(module);
@@ -83,6 +79,6 @@ public class AnnouncementOperations {
public static void main(String[] args) {
AnnouncementOperations operations = new AnnouncementOperations();
- System.out.println(operations.getProjectBulletpoints(ReleaseTrains.CODD, Iteration.SR2));
+ System.out.println(operations.getProjectBulletpoints(new TrainIteration(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/IssueTracerCommands.java
similarity index 60%
rename from src/main/java/org/springframework/data/release/cli/JiraCommands.java
rename to src/main/java/org/springframework/data/release/cli/IssueTracerCommands.java
index a764689..15268dc 100644
--- a/src/main/java/org/springframework/data/release/cli/JiraCommands.java
+++ b/src/main/java/org/springframework/data/release/cli/IssueTracerCommands.java
@@ -18,10 +18,12 @@ package org.springframework.data.release.cli;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.release.jira.Credentials;
+import org.springframework.data.release.jira.IssueTracker;
import org.springframework.data.release.jira.JiraConnector;
-import org.springframework.data.release.model.Iteration;
-import org.springframework.data.release.model.ReleaseTrains;
-import org.springframework.data.release.model.Train;
+import org.springframework.data.release.model.ModuleIteration;
+import org.springframework.data.release.model.Project;
+import org.springframework.data.release.model.TrainIteration;
+import org.springframework.plugin.core.PluginRegistry;
import org.springframework.shell.core.CommandMarker;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
@@ -32,58 +34,62 @@ import org.springframework.util.StringUtils;
* @author Oliver Gierke
*/
@Component
-public class JiraCommands implements CommandMarker {
+public class IssueTracerCommands implements CommandMarker {
- private final JiraConnector connector;
+ private final PluginRegistry tracker;
+ private final JiraConnector jira;
private final Credentials credentials;
/**
- * @param connector
+ * @param tracker
* @param environment
*/
@Autowired
- public JiraCommands(JiraConnector connector, Environment environment) {
+ public IssueTracerCommands(PluginRegistry tracker, JiraConnector jira, Environment environment) {
String username = environment.getProperty("jira.username", (String) null);
String password = environment.getProperty("jira.password", (String) null);
- this.connector = connector;
+ this.tracker = tracker;
+ this.jira = jira;
this.credentials = StringUtils.hasText(username) ? new Credentials(username, password) : null;
}
@CliCommand("jira evict")
public void jiraEvict() {
- connector.reset();
+ jira.reset();
}
@CliCommand(value = "jira tickets")
public String jira(
- @CliOption(key = { "", "train" }, mandatory = true, help = "The name of the release train.") String trainName, //
- @CliOption(key = "iteration", mandatory = true, help = "An iteration key (one of M1, RC1, GA).") String iterationName, //
+ @CliOption(key = "", mandatory = true) TrainIteration iteration, //
@CliOption(key = "for-current-user", specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") boolean forCurrentUser) {
if (forCurrentUser && credentials == null) {
return "No authentication specified! Use 'jira authenticate' first!";
}
- Train train = ReleaseTrains.getTrainByName(trainName);
- Iteration iteration = train.getIterations().getIterationByName(iterationName);
-
- return connector.getTicketsFor(train, iteration, forCurrentUser ? credentials : null).toString();
+ return jira.getTicketsFor(iteration, forCurrentUser ? credentials : null).toString();
}
- @CliCommand("changelog")
- public String changelog(@CliOption(key = { "", "train" }, mandatory = true) String trainName, //
- @CliOption(key = { "iteration" }, mandatory = true) String iterationName, //
+ @CliCommand("tracker changelog")
+ public String changelog(@CliOption(key = "", mandatory = true) TrainIteration iteration, //
@CliOption(key = "module") String moduleName) {
- Train train = ReleaseTrains.getTrainByName(trainName);
- Iteration iteration = train.getIteration(iterationName);
-
if (StringUtils.hasText(moduleName)) {
- return connector.getChangelogFor(train.getModuleIteration(iteration, moduleName)).toString();
+
+ ModuleIteration module = iteration.getModule(moduleName);
+ return tracker.getPluginFor(module.getProject()).getChangelogFor(module).toString();
}
- return "";
+ StringBuilder builder = new StringBuilder();
+
+ for (ModuleIteration module : iteration) {
+
+ IssueTracker issues = tracker.getPluginFor(module.getProject());
+ builder.append(issues.getChangelogFor(module)).append("\n");
+ }
+
+ return builder.toString();
}
}
diff --git a/src/main/java/org/springframework/data/release/cli/ModelCommands.java b/src/main/java/org/springframework/data/release/cli/ModelCommands.java
index 2344df7..522e3b1 100644
--- a/src/main/java/org/springframework/data/release/cli/ModelCommands.java
+++ b/src/main/java/org/springframework/data/release/cli/ModelCommands.java
@@ -33,16 +33,16 @@ import org.springframework.util.StringUtils;
public class ModelCommands implements CommandMarker {
@CliCommand("trains")
- public String train(@CliOption(key = { "", "train" }) String trainName) {
+ public String train(@CliOption(key = { "", "train" }) Train train) {
- if (StringUtils.hasText(trainName)) {
- return ReleaseTrains.getTrainByName(trainName).toString();
+ if (train != null) {
+ return train.toString();
}
List names = new ArrayList<>();
- for (Train train : ReleaseTrains.TRAINS) {
- names.add(train.getName());
+ for (Train releaseTrain : ReleaseTrains.TRAINS) {
+ names.add(releaseTrain.getName());
}
return StringUtils.collectionToDelimitedString(names, ", ");
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 35f26e5..2b4667c 100644
--- a/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java
+++ b/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java
@@ -15,6 +15,7 @@
*/
package org.springframework.data.release.cli;
+import static org.springframework.data.release.model.Projects.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,11 +25,11 @@ 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;
-import org.springframework.data.release.model.Project;
+import org.springframework.data.release.model.Phase;
import org.springframework.data.release.model.ReleaseTrains;
import org.springframework.data.release.model.Train;
+import org.springframework.data.release.model.TrainIteration;
import org.springframework.shell.core.CommandMarker;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
@@ -48,17 +49,16 @@ public class ReleaseCommands implements CommandMarker {
@CliCommand("release predict")
public String predictTrainAndIteration() throws Exception {
- Project commons = ReleaseTrains.COMMONS;
- Pom pom = maven.getMavenProject(commons);
+ Pom pom = maven.getMavenProject(COMMONS);
- Tags tags = git.getTags(commons);
+ Tags tags = git.getTags(COMMONS);
ArtifactVersion version = tags.getLatest().toArtifactVersion();
System.out.println(version);
for (Train train : ReleaseTrains.TRAINS) {
- Module module = train.getModule(commons);
+ Module module = train.getModule(COMMONS);
if (!pom.getVersion().toString().startsWith(module.getVersion().toMajorMinorBugfix())) {
continue;
@@ -78,14 +78,10 @@ public class ReleaseCommands implements CommandMarker {
* @throws Exception
*/
@CliCommand("release distribute")
- public void distribute(@CliOption(key = { "", "train" }, mandatory = true) String trainName, @CliOption(
- key = "iteration", mandatory = true) String iterationName) throws Exception {
+ public void distribute(@CliOption(key = "", mandatory = true) TrainIteration iteration) throws Exception {
- Train train = ReleaseTrains.getTrainByName(trainName);
- Iteration iteration = train.getIteration(iterationName);
-
- git.checkout(train, iteration);
- maven.triggerDistributionBuild(train, iteration);
+ git.checkout(iteration);
+ maven.triggerDistributionBuild(iteration);
}
/**
@@ -96,17 +92,22 @@ public class ReleaseCommands implements CommandMarker {
* @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 {
+ public void prepare(@CliOption(key = "", mandatory = true) TrainIteration iteration) throws Exception {
- Train train = ReleaseTrains.getTrainByName(trainName);
- Iteration iteration = train.getIteration(iterationName);
+ git.prepare(iteration);
+ misc.prepareChangelogs(iteration);
+ maven.updatePom(iteration, Phase.PREPARE);
+ }
- git.prepare(train, iteration);
- misc.prepareChangelogs(train, iteration);
+ @CliCommand(value = "release conclude")
+ public void conclude(@CliOption(key = "", mandatory = true) TrainIteration iteration) throws Exception {
- for (Module module : train) {
- maven.prepareProject(train, iteration, module.getProject());
- }
+ // - pull updates
+ // - tag release
+ // - post release pom updates
+
+ maven.updatePom(iteration, Phase.CLEANUP);
+
+ // - push
}
}
diff --git a/src/main/java/org/springframework/data/release/cli/TrainConverter.java b/src/main/java/org/springframework/data/release/cli/TrainConverter.java
new file mode 100644
index 0000000..5ab2deb
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/cli/TrainConverter.java
@@ -0,0 +1,62 @@
+/*
+ * 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.cli;
+
+import java.util.List;
+
+import org.springframework.data.release.model.ReleaseTrains;
+import org.springframework.data.release.model.Train;
+import org.springframework.shell.core.Completion;
+import org.springframework.shell.core.Converter;
+import org.springframework.shell.core.MethodTarget;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+/**
+ * @author Oliver Gierke
+ */
+@Component
+public class TrainConverter implements Converter {
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.shell.core.Converter#supports(java.lang.Class, java.lang.String)
+ */
+ @Override
+ public boolean supports(Class> type, String optionContext) {
+ return Train.class.isAssignableFrom(type);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.shell.core.Converter#convertFromText(java.lang.String, java.lang.Class, java.lang.String)
+ */
+ @Override
+ public Train convertFromText(String value, Class> targetType, String optionContext) {
+ return StringUtils.hasText(value) ? ReleaseTrains.getTrainByName(value) : null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.shell.core.Converter#getAllPossibleValues(java.util.List, java.lang.Class, java.lang.String, java.lang.String, org.springframework.shell.core.MethodTarget)
+ */
+ @Override
+ public boolean getAllPossibleValues(List completions, Class> targetType, String existingData,
+ String optionContext, MethodTarget target) {
+
+ return false;
+ }
+}
diff --git a/src/main/java/org/springframework/data/release/cli/TrainIterationConverter.java b/src/main/java/org/springframework/data/release/cli/TrainIterationConverter.java
new file mode 100644
index 0000000..61ab822
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/cli/TrainIterationConverter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.cli;
+
+import java.util.List;
+
+import org.springframework.data.release.model.Iteration;
+import org.springframework.data.release.model.ReleaseTrains;
+import org.springframework.data.release.model.Train;
+import org.springframework.data.release.model.TrainIteration;
+import org.springframework.shell.core.Completion;
+import org.springframework.shell.core.Converter;
+import org.springframework.shell.core.MethodTarget;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Oliver Gierke
+ */
+@Component
+public class TrainIterationConverter implements Converter {
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.shell.core.Converter#supports(java.lang.Class, java.lang.String)
+ */
+ @Override
+ public boolean supports(Class> type, String optionContext) {
+ return TrainIteration.class.equals(type);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.shell.core.Converter#convertFromText(java.lang.String, java.lang.Class, java.lang.String)
+ */
+ @Override
+ public TrainIteration convertFromText(String value, Class> targetType, String optionContext) {
+
+ String[] parts = value.split(" ");
+ Train train = ReleaseTrains.getTrainByName(parts[0].trim());
+ Iteration iteration = train.getIteration(parts[1].trim());
+
+ return new TrainIteration(train, iteration);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.shell.core.Converter#getAllPossibleValues(java.util.List, java.lang.Class, java.lang.String, java.lang.String, org.springframework.shell.core.MethodTarget)
+ */
+ @Override
+ public boolean getAllPossibleValues(List completions, Class> targetType, String existingData,
+ String optionContext, MethodTarget target) {
+
+ for (Train train : ReleaseTrains.TRAINS) {
+
+ // if (!StringUtils.hasText(existingData) &&
+ // !train.getName().toLowerCase().startsWith(existingData.toLowerCase())) {
+ // continue;
+ // }
+
+ for (Iteration iteration : train.getIterations()) {
+ completions.add(new Completion(new TrainIteration(train, iteration).toString()));
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/src/main/java/org/springframework/data/release/git/Branch.java b/src/main/java/org/springframework/data/release/git/Branch.java
index 516e818..0e74377 100644
--- a/src/main/java/org/springframework/data/release/git/Branch.java
+++ b/src/main/java/org/springframework/data/release/git/Branch.java
@@ -29,7 +29,7 @@ import org.springframework.util.Assert;
*/
@RequiredArgsConstructor
@EqualsAndHashCode
-public class Branch {
+class Branch {
private static final Branch MASTER = new Branch("master");
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 da7c504..a98956b 100644
--- a/src/main/java/org/springframework/data/release/git/GiCommands.java
+++ b/src/main/java/org/springframework/data/release/git/GiCommands.java
@@ -18,10 +18,9 @@ package org.springframework.data.release.git;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.release.model.Iteration;
import org.springframework.data.release.model.Project;
import org.springframework.data.release.model.ReleaseTrains;
-import org.springframework.data.release.model.Train;
+import org.springframework.data.release.model.TrainIteration;
import org.springframework.shell.core.CommandMarker;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
@@ -33,24 +32,18 @@ import org.springframework.util.StringUtils;
*/
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
-public class GiCommands implements CommandMarker {
+class GiCommands implements CommandMarker {
private final GitOperations git;
@CliCommand("git checkout")
- public void checkout(@CliOption(key = { "", "train" }, mandatory = true) String trainName, @CliOption(
- key = "iteration", mandatory = true) String iterationName) throws Exception {
-
- Train train = ReleaseTrains.getTrainByName(trainName);
- Iteration iteration = train.getIteration(iterationName);
-
- git.checkout(train, iteration);
+ public void checkout(@CliOption(key = "", mandatory = true) TrainIteration iteration) throws Exception {
+ git.checkout(iteration);
}
@CliCommand("git update")
public void checkout(@CliOption(key = { "", "train" }, mandatory = true) String trainName) throws Exception,
InterruptedException {
-
git.update(ReleaseTrains.getTrainByName(trainName));
}
@@ -69,10 +62,7 @@ public class GiCommands implements CommandMarker {
}
@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));
+ public void prepare(@CliOption(key = "", mandatory = true) TrainIteration iteration) throws Exception {
+ git.prepare(iteration);
}
}
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 03f026d..3b8cd7d 100644
--- a/src/main/java/org/springframework/data/release/git/GitOperations.java
+++ b/src/main/java/org/springframework/data/release/git/GitOperations.java
@@ -20,7 +20,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
-import java.util.logging.Logger;
import lombok.RequiredArgsConstructor;
@@ -34,7 +33,8 @@ import org.springframework.data.release.model.Module;
import org.springframework.data.release.model.ModuleIteration;
import org.springframework.data.release.model.Project;
import org.springframework.data.release.model.Train;
-import org.springframework.shell.support.logging.HandlerUtils;
+import org.springframework.data.release.model.TrainIteration;
+import org.springframework.data.release.utils.Logger;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -48,11 +48,10 @@ import org.springframework.util.StringUtils;
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class GitOperations {
- private static final Logger LOGGER = HandlerUtils.getLogger(GitOperations.class);
-
private final GitServer server = new GitServer();
private final OsCommandOperations osCommandOperations;
private final Workspace workspace;
+ private final Logger logger;
public GitProject getGitProject(Project project) {
return new GitProject(project, server);
@@ -80,11 +79,11 @@ public class GitOperations {
* @param iteration
* @throws Exception
*/
- public void checkout(Train train, Iteration iteration) throws Exception {
+ public void checkout(TrainIteration iteration) throws Exception {
- update(train);
+ update(iteration.getTrain());
- for (ModuleIteration module : train.getModuleIterations(iteration)) {
+ for (ModuleIteration module : iteration) {
Project project = module.getProject();
ArtifactVersion artifactVersion = ArtifactVersion.from(module);
@@ -99,13 +98,12 @@ public class GitOperations {
osCommandOperations.executeCommand(String.format("git checkout %s", tag), project).get();
}
- LOGGER.info(String.format("Successfully checked out iteration %s for release train %s.", iteration.getName(),
- train.getName()));
+ logger.log(iteration, "Successfully checked out projects.");
}
- public void prepare(Train train, Iteration iteration) throws Exception {
+ public void prepare(TrainIteration iteration) throws Exception {
- for (ModuleIteration module : train.getModuleIterations(iteration)) {
+ for (ModuleIteration module : iteration) {
Branch branch = Branch.from(module);
@@ -139,15 +137,14 @@ public class GitOperations {
if (workspace.hasProjectDirectory(project)) {
- LOGGER.info(String.format("Found existing repository %s. Obtaining latest changes…", repositoryName));
+ logger.log(project, "Found existing repository %s. Obtaining latest changes…", repositoryName);
return osCommandOperations.executeCommand("git checkout master && git fetch --tags && git pull origin master",
project);
} else {
- LOGGER.info(String.format("No repository found for project %s. Cloning repository from %s…", repositoryName,
- gitProject.getProjectUri()));
+ logger.log(project, "No repository found! Cloning from %s…", gitProject.getProjectUri());
File projectDirectory = workspace.getProjectDirectory(project);
String command = String.format("git clone %s %s", gitProject.getProjectUri(), projectDirectory.getName());
diff --git a/src/main/java/org/springframework/data/release/io/CommonsExecOsCommandOperations.java b/src/main/java/org/springframework/data/release/io/CommonsExecOsCommandOperations.java
index a028585..c8a6dd4 100644
--- a/src/main/java/org/springframework/data/release/io/CommonsExecOsCommandOperations.java
+++ b/src/main/java/org/springframework/data/release/io/CommonsExecOsCommandOperations.java
@@ -21,7 +21,6 @@ import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
-import java.util.logging.Logger;
import javax.annotation.PostConstruct;
@@ -33,11 +32,10 @@ import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;
import org.apache.commons.io.output.WriterOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.release.git.GitOperations;
import org.springframework.data.release.model.Project;
+import org.springframework.data.release.utils.Logger;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
-import org.springframework.shell.support.logging.HandlerUtils;
import org.springframework.stereotype.Component;
/**
@@ -51,12 +49,10 @@ import org.springframework.stereotype.Component;
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
class CommonsExecOsCommandOperations implements OsCommandOperations {
- private static final Logger LOGGER = HandlerUtils.getLogger(GitOperations.class);
- private static final String PREFIX_TEMPLATE = "%s > %s";
-
private static final Map ENVIRONMENT = new HashMap<>();
private final Workspace workspace;
+ private final Logger logger;
/*
* (non-Javadoc)
@@ -76,7 +72,7 @@ class CommonsExecOsCommandOperations implements OsCommandOperations {
@Override
public Future executeCommand(String command, Project project) throws IOException {
- LOGGER.info(String.format(PREFIX_TEMPLATE, project.getName(), command));
+ logger.log(project, command);
return executeCommand(command, workspace.getProjectDirectory(project), true);
}
@@ -88,7 +84,7 @@ class CommonsExecOsCommandOperations implements OsCommandOperations {
@Override
public Future executeWithOutput(String command, Project project) throws IOException {
- LOGGER.info(String.format(PREFIX_TEMPLATE, project.getName(), command));
+ logger.log(project, command);
return executeCommand(command, workspace.getProjectDirectory(project), false);
}
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 8397c9a..facb97b 100644
--- a/src/main/java/org/springframework/data/release/jira/Changelog.java
+++ b/src/main/java/org/springframework/data/release/jira/Changelog.java
@@ -61,7 +61,7 @@ public class Changelog {
String summary = ticket.getSummary();
- builder.append("* ").append(ticket.getId()).append(" - ").append(summary);
+ builder.append("* ").append(ticket.getId()).append(" - ").append(summary.trim());
if (!summary.endsWith(".")) {
builder.append(".");
diff --git a/src/main/java/org/springframework/data/release/jira/GitHubIssue.java b/src/main/java/org/springframework/data/release/jira/GitHubIssue.java
new file mode 100644
index 0000000..7e0edde
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/jira/GitHubIssue.java
@@ -0,0 +1,28 @@
+/*
+ * 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.jira;
+
+import lombok.Data;
+
+/**
+ * @author Oliver Gierke
+ */
+@Data
+class GitHubIssue {
+
+ private String number;
+ private String title;
+}
diff --git a/src/main/java/org/springframework/data/release/jira/GitHubIssueTracker.java b/src/main/java/org/springframework/data/release/jira/GitHubIssueTracker.java
new file mode 100644
index 0000000..4a7c7b4
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/jira/GitHubIssueTracker.java
@@ -0,0 +1,143 @@
+/*
+ * 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.jira;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import lombok.RequiredArgsConstructor;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.data.release.git.GitProject;
+import org.springframework.data.release.git.GitServer;
+import org.springframework.data.release.model.Iteration;
+import org.springframework.data.release.model.ModuleIteration;
+import org.springframework.data.release.model.Project;
+import org.springframework.data.release.model.ReleaseTrains;
+import org.springframework.data.release.model.Tracker;
+import org.springframework.data.release.model.TrainIteration;
+import org.springframework.data.release.utils.Logger;
+import org.springframework.http.HttpMethod;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestOperations;
+import org.springframework.web.util.UriTemplate;
+
+/**
+ * @author Oliver Gierke
+ */
+@Component
+@RequiredArgsConstructor(onConstructor = @_(@Autowired))
+class GitHubIssueTracker implements IssueTracker {
+
+ private static final String MILESTONE_URI = "https://api.github.com/repos/spring-projects/{repoName}/milestones?state={state}";
+ private static final String URI_TEMPLATE = "https://api.github.com/repos/spring-projects/{repoName}/issues?milestone={id}&state=all";
+
+ private static final ParameterizedTypeReference> MILESTONES_TYPE = new ParameterizedTypeReference>() {};
+ private static final ParameterizedTypeReference> ISSUES_TYPE = new ParameterizedTypeReference>() {};
+
+ private final RestOperations operations;
+ private final Logger logger;
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.release.jira.IssueTracker#getChangelogFor(org.springframework.data.release.model.ModuleIteration)
+ */
+ @Override
+ public Changelog getChangelogFor(ModuleIteration module) {
+
+ String repositoryName = new GitProject(module.getProject(), new GitServer()).getRepositoryName();
+
+ GitHubMilestone milestone = findMilestone(module, repositoryName);
+
+ Map parameters = new HashMap<>();
+ parameters.put("repoName", repositoryName);
+ parameters.put("id", milestone.getNumber());
+
+ List issues = operations.exchange(URI_TEMPLATE, HttpMethod.GET, null, ISSUES_TYPE, parameters)
+ .getBody();
+ List tickets = new ArrayList<>(issues.size());
+
+ for (GitHubIssue issue : issues) {
+ tickets.add(new Ticket("#" + issue.getNumber(), issue.getTitle()));
+ }
+
+ logger.log(module, "Created changelog with %s entries.", tickets.size());
+
+ return new Changelog(module, new Tickets(tickets));
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.plugin.core.Plugin#supports(java.lang.Object)
+ */
+ @Override
+ public boolean supports(Project project) {
+ return project.uses(Tracker.GITHUB);
+ }
+
+ private GitHubMilestone findMilestone(ModuleIteration module, String repositoryName) {
+
+ for (String state : Arrays.asList("close", "open")) {
+
+ Map parameters = new HashMap<>();
+ parameters.put("repoName", repositoryName);
+ parameters.put("state", state);
+
+ URI milestoneUri = new UriTemplate(MILESTONE_URI).expand(parameters);
+
+ logger.log(module, "Looking up milestone from %s…", milestoneUri);
+
+ List exchange = operations.exchange(MILESTONE_URI, HttpMethod.GET, null, MILESTONES_TYPE,
+ parameters).getBody();
+
+ GitHubMilestone milestone = null;
+
+ for (GitHubMilestone candidate : exchange) {
+ if (candidate.getTitle().contains(module.getVersionString())) {
+ milestone = candidate;
+ }
+ }
+
+ if (milestone != null) {
+ logger.log(module, "Found milestone %s.", milestone);
+ return milestone;
+ }
+ }
+
+ throw new IllegalStateException(String.format("No milestone found containing %s!", module.getVersionString()));
+ }
+
+ public static void main(String[] args) {
+
+ try (ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
+ "META-INF/spring/spring-shell-plugin.xml")) {
+
+ GitHubIssueTracker tracker = context.getBean(GitHubIssueTracker.class);
+
+ TrainIteration iteration = new TrainIteration(ReleaseTrains.CODD, Iteration.SR2);
+ Changelog changelog = tracker.getChangelogFor(iteration.getModule("Build"));
+
+ System.out.println(changelog);
+ }
+ }
+}
diff --git a/src/main/java/org/springframework/data/release/jira/GitHubMilestone.java b/src/main/java/org/springframework/data/release/jira/GitHubMilestone.java
new file mode 100644
index 0000000..7cee9a4
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/jira/GitHubMilestone.java
@@ -0,0 +1,28 @@
+/*
+ * 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.jira;
+
+import lombok.Data;
+
+/**
+ * @author Oliver Gierke
+ */
+@Data
+class GitHubMilestone {
+
+ private String title;
+ private Long number;
+}
diff --git a/src/main/java/org/springframework/data/release/jira/IssueTracker.java b/src/main/java/org/springframework/data/release/jira/IssueTracker.java
new file mode 100644
index 0000000..9af5a21
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/jira/IssueTracker.java
@@ -0,0 +1,28 @@
+/*
+ * 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.jira;
+
+import org.springframework.data.release.model.ModuleIteration;
+import org.springframework.data.release.model.Project;
+import org.springframework.plugin.core.Plugin;
+
+/**
+ * @author Oliver Gierke
+ */
+public interface IssueTracker extends Plugin {
+
+ Changelog getChangelogFor(ModuleIteration iteration);
+}
diff --git a/src/main/java/org/springframework/data/release/jira/RestJiraConnector.java b/src/main/java/org/springframework/data/release/jira/Jira.java
similarity index 62%
rename from src/main/java/org/springframework/data/release/jira/RestJiraConnector.java
rename to src/main/java/org/springframework/data/release/jira/Jira.java
index 812fbb6..3faf275 100644
--- a/src/main/java/org/springframework/data/release/jira/RestJiraConnector.java
+++ b/src/main/java/org/springframework/data/release/jira/Jira.java
@@ -15,35 +15,40 @@
*/
package org.springframework.data.release.jira;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.logging.Logger;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.release.model.Iteration;
import org.springframework.data.release.model.ModuleIteration;
-import org.springframework.data.release.model.Train;
+import org.springframework.data.release.model.Project;
+import org.springframework.data.release.model.ReleaseTrains;
+import org.springframework.data.release.model.Tracker;
+import org.springframework.data.release.model.TrainIteration;
+import org.springframework.data.release.utils.Logger;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestOperations;
+import org.springframework.web.util.UriTemplate;
/**
* @author Oliver Gierke
*/
@Component
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
-class RestJiraConnector implements JiraConnector {
-
- protected final Logger LOGGER = Logger.getLogger(getClass().getName());
+class Jira implements JiraConnector {
private static final String JIRA_HOST = "https://jira.spring.io";
private static final String BASE_URI = "/rest/api/2";
@@ -51,6 +56,7 @@ class RestJiraConnector implements JiraConnector {
+ "/search?jql={jql}&fields={fields}&startAt={startAt}";
private final RestOperations operations;
+ private final Logger logger;
/*
* (non-Javadoc)
@@ -62,15 +68,33 @@ class RestJiraConnector implements JiraConnector {
}
+ @Cacheable("release-tickets")
+ public Ticket getReleaseTicketFor(ModuleIteration iteration) {
+
+ JqlQuery query = JqlQuery.from(iteration).and("summary ~ \"Release\"");
+
+ Map parameters = new HashMap<>();
+ parameters.put("jql", query);
+ parameters.put("fields", "summary");
+ parameters.put("startAt", 0);
+
+ JiraIssues issues = operations.exchange(SEARCH_TEMPLATE, HttpMethod.GET, null, JiraIssues.class, parameters)
+ .getBody();
+
+ JiraIssue issue = issues.getIssues().get(0);
+
+ return new Ticket(issue.getKey(), issue.getFields().getSummary());
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.release.jira.JiraConnector#getTicketsFor(org.springframework.data.release.model.Train, org.springframework.data.release.model.Iteration, org.springframework.data.release.jira.Credentials)
*/
@Override
@Cacheable("tickets")
- public Tickets getTicketsFor(Train train, Iteration iteration, Credentials credentials) {
+ public Tickets getTicketsFor(TrainIteration iteration, Credentials credentials) {
- JqlQuery query = JqlQuery.from(train, iteration);
+ JqlQuery query = JqlQuery.from(iteration);
HttpHeaders headers = new HttpHeaders();
int startAt = 0;
@@ -83,10 +107,9 @@ class RestJiraConnector implements JiraConnector {
headers.set("Authorization", String.format("Basic %s", credentials.asBase64()));
- LOGGER.info(String.format("Retrieving tickets for %s %s (for user %s).", train.getName(), iteration.getName(),
- credentials.getUsername()));
+ logger.log(iteration, "Retrieving tickets (for user %s)…", credentials.getUsername());
} else {
- LOGGER.info(String.format("Retrieving tickets for %s %s.", train.getName(), iteration.getName()));
+ logger.log(iteration, "Retrieving tickets…");
}
query = query.orderBy("updatedDate DESC");
@@ -101,10 +124,10 @@ class RestJiraConnector implements JiraConnector {
issues = operations.exchange(SEARCH_TEMPLATE, HttpMethod.GET, new HttpEntity<>(headers), JiraIssues.class,
parameters).getBody();
- LOGGER.info(String.format("Got tickets %s to %s of %s.", startAt, issues.getNextStartAt(), issues.getTotal()));
+ logger.log(iteration, "Got tickets %s to %s of %s.", startAt, issues.getNextStartAt(), issues.getTotal());
for (JiraIssue issue : issues) {
- if (!issue.wasBackportedFrom(train)) {
+ if (!issue.wasBackportedFrom(iteration.getTrain())) {
tickets.add(new Ticket(issue.getKey(), issue.getFields().getSummary()));
}
}
@@ -121,7 +144,7 @@ class RestJiraConnector implements JiraConnector {
* @see org.springframework.data.release.jira.JiraConnector#verifyBeforeRelease(org.springframework.data.release.model.Train, org.springframework.data.release.model.Iteration)
*/
@Override
- public void verifyBeforeRelease(Train train, Iteration iteration) {
+ public void verifyBeforeRelease(TrainIteration iteration) {
// for each module
@@ -134,7 +157,7 @@ class RestJiraConnector implements JiraConnector {
* @see org.springframework.data.release.jira.JiraConnector#closeIteration(org.springframework.data.release.model.Train, org.springframework.data.release.model.Iteration, org.springframework.data.release.jira.Credentials)
*/
@Override
- public void closeIteration(Train train, Iteration iteration, Credentials credentials) {
+ public void closeIteration(TrainIteration iteration, Credentials credentials) {
// for each module
@@ -159,13 +182,44 @@ class RestJiraConnector implements JiraConnector {
parameters.put("fields", "summary,fixVersions");
parameters.put("startAt", 0);
- JiraIssues issues = operations.getForObject(SEARCH_TEMPLATE, JiraIssues.class, parameters);
+ URI searchUri = new UriTemplate(SEARCH_TEMPLATE).expand(parameters);
+
+ logger.log(module, "Looking up JIRA issues from %s…", searchUri);
+
+ JiraIssues issues = operations.getForObject(searchUri, JiraIssues.class);
List tickets = new ArrayList<>();
for (JiraIssue issue : issues) {
tickets.add(new Ticket(issue.getKey(), issue.getFields().getSummary()));
}
+ logger.log(module, "Created changelog with %s entries.", tickets.size());
+
return new Changelog(module, new Tickets(tickets, tickets.size()));
}
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.plugin.core.Plugin#supports(java.lang.Object)
+ */
+ @Override
+ public boolean supports(Project project) {
+ return project.uses(Tracker.JIRA);
+ }
+
+ public static void main(String[] args) {
+
+ try (ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
+ "META-INF/spring/spring-shell-plugin.xml")) {
+
+ JiraConnector tracker = context.getBean(JiraConnector.class);
+ TrainIteration iteration = new TrainIteration(ReleaseTrains.CODD, Iteration.SR2);
+ ModuleIteration module = iteration.getModule("JPA");
+
+ // Changelog changelog = tracker.getChangelogFor(module);
+ // System.out.println(changelog);
+
+ System.out.println(tracker.getReleaseTicketFor(module));
+ }
+ }
}
diff --git a/src/main/java/org/springframework/data/release/jira/JiraConfiguration.java b/src/main/java/org/springframework/data/release/jira/JiraConfiguration.java
index d795836..6a87c67 100644
--- a/src/main/java/org/springframework/data/release/jira/JiraConfiguration.java
+++ b/src/main/java/org/springframework/data/release/jira/JiraConfiguration.java
@@ -26,6 +26,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.plugin.core.config.EnablePluginRegistries;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.DeserializationFeature;
@@ -37,6 +38,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
@EnableCaching
@PropertySource(value = "file:jira.properties", ignoreResourceNotFound = true)
+@EnablePluginRegistries({ IssueTracker.class })
class JiraConfiguration {
@Bean
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 22914a1..45af741 100644
--- a/src/main/java/org/springframework/data/release/jira/JiraConnector.java
+++ b/src/main/java/org/springframework/data/release/jira/JiraConnector.java
@@ -18,14 +18,17 @@ package org.springframework.data.release.jira;
import org.springframework.data.release.model.Iteration;
import org.springframework.data.release.model.ModuleIteration;
import org.springframework.data.release.model.Train;
+import org.springframework.data.release.model.TrainIteration;
/**
* @author Oliver Gierke
*/
-public interface JiraConnector {
+public interface JiraConnector extends IssueTracker {
void reset();
+ Ticket getReleaseTicketFor(ModuleIteration iteration);
+
/**
* Returns all {@link Tickets} for the given {@link Train} and {@link Iteration}.
*
@@ -33,11 +36,9 @@ public interface JiraConnector {
* @param iteration must not be {@literal null}.
* @return
*/
- Tickets getTicketsFor(Train train, Iteration iteration, Credentials credentials);
+ Tickets getTicketsFor(TrainIteration iteration, Credentials credentials);
- void verifyBeforeRelease(Train train, Iteration iteration);
+ void verifyBeforeRelease(TrainIteration iteration);
- void closeIteration(Train train, Iteration iteration, Credentials credentials);
-
- Changelog getChangelogFor(ModuleIteration iteration);
+ void closeIteration(TrainIteration iteration, Credentials credentials);
}
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 b59806c..d54d1c6 100644
--- a/src/main/java/org/springframework/data/release/jira/JqlQuery.java
+++ b/src/main/java/org/springframework/data/release/jira/JqlQuery.java
@@ -15,15 +15,15 @@
*/
package org.springframework.data.release.jira;
+import static org.springframework.data.release.model.Projects.*;
+
import java.util.ArrayList;
import java.util.List;
import lombok.Value;
-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.data.release.model.TrainIteration;
import org.springframework.util.StringUtils;
/**
@@ -51,15 +51,11 @@ class JqlQuery {
return new JqlQuery(String.format(PROJECT_VERSION_TEMPLATE, iteration.getProjectKey(), version));
}
- public static JqlQuery from(Train train, Iteration iteration) {
+ public static JqlQuery from(TrainIteration iteration) {
List parts = new ArrayList<>();
- for (ModuleIteration module : train.getModuleIterations(iteration)) {
-
- if (ReleaseTrains.BUILD.equals(module.getProject())) {
- continue;
- }
+ for (ModuleIteration module : iteration.getModulesExcept(BUILD)) {
JiraVersion version = new JiraVersion(module);
parts.add(String.format(PROJECT_VERSION_TEMPLATE, module.getProjectKey(), version));
diff --git a/src/main/java/org/springframework/data/release/jira/Tickets.java b/src/main/java/org/springframework/data/release/jira/Tickets.java
index a56a7fc..c7d6160 100644
--- a/src/main/java/org/springframework/data/release/jira/Tickets.java
+++ b/src/main/java/org/springframework/data/release/jira/Tickets.java
@@ -18,6 +18,7 @@ package org.springframework.data.release.jira;
import java.util.Iterator;
import java.util.List;
+import lombok.RequiredArgsConstructor;
import lombok.Value;
import org.springframework.util.StringUtils;
@@ -28,11 +29,16 @@ import org.springframework.util.StringUtils;
* @author Oliver Gierke
*/
@Value
+@RequiredArgsConstructor
public class Tickets implements Iterable {
private final List tickets;
private final int overallTotal;
+ public Tickets(List tickets) {
+ this(tickets, tickets.size());
+ }
+
/*
* (non-Javadoc)
* @see java.lang.Iterable#iterator()
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 7727d42..cd99321 100644
--- a/src/main/java/org/springframework/data/release/maven/Artifact.java
+++ b/src/main/java/org/springframework/data/release/maven/Artifact.java
@@ -15,11 +15,12 @@
*/
package org.springframework.data.release.maven;
+import static org.springframework.data.release.model.Projects.*;
+import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.springframework.data.release.model.ArtifactVersion;
import org.springframework.data.release.model.ModuleIteration;
-import org.springframework.data.release.model.ReleaseTrains;
import org.springframework.util.Assert;
/**
@@ -27,6 +28,7 @@ import org.springframework.util.Assert;
*
* @author Oliver Gierke
*/
+@EqualsAndHashCode
public class Artifact {
private static final GroupId GROUP_ID = new GroupId("org.springframework.data");
@@ -57,7 +59,11 @@ public class Artifact {
public String getArtifactId() {
String artifactId = String.format("spring-data-%s", module.getProject().getName().toLowerCase());
- return ReleaseTrains.REST.equals(module.getProject()) ? artifactId.concat("-webmvc") : artifactId;
+ return REST.equals(module.getProject()) ? artifactId.concat("-webmvc") : artifactId;
+ }
+
+ public ArtifactVersion getNextDevelopmentVersion() {
+ return version.getNextDevelopmentVersion();
}
/**
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 4098ad0..012454c 100644
--- a/src/main/java/org/springframework/data/release/maven/MavenOperations.java
+++ b/src/main/java/org/springframework/data/release/maven/MavenOperations.java
@@ -15,9 +15,11 @@
*/
package org.springframework.data.release.maven;
+import static org.springframework.data.release.model.Phase.*;
+import static org.springframework.data.release.model.Projects.*;
+
import java.io.File;
import java.io.IOException;
-import java.util.logging.Logger;
import lombok.RequiredArgsConstructor;
@@ -26,12 +28,12 @@ import org.springframework.data.release.io.CommandResult;
import org.springframework.data.release.io.OsCommandOperations;
import org.springframework.data.release.io.Workspace;
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.Phase;
import org.springframework.data.release.model.Project;
-import org.springframework.data.release.model.ReleaseTrains;
import org.springframework.data.release.model.Train;
-import org.springframework.shell.support.logging.HandlerUtils;
+import org.springframework.data.release.model.TrainIteration;
+import org.springframework.data.release.utils.Logger;
import org.springframework.stereotype.Component;
import org.xmlbeam.ProjectionFactory;
import org.xmlbeam.io.XBFileIO;
@@ -44,12 +46,12 @@ import org.xmlbeam.io.XBFileIO;
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";
private final Workspace workspace;
private final ProjectionFactory projectionFactory;
private final OsCommandOperations os;
+ private final Logger logger;
public Pom getMavenProject(Project project) throws IOException {
@@ -57,38 +59,36 @@ public class MavenOperations {
return projectionFactory.io().file(file).read(Pom.class);
}
- public void prepareProject(Train train, Iteration iteration, final Project project) throws Exception {
+ public void updatePom(TrainIteration iteration, final Phase phase) throws Exception {
- updateBomPom(train, iteration);
+ updateBomPom(iteration, phase);
- if (ReleaseTrains.BUILD.equals(project)) {
- return;
- }
+ final Repository repository = new Repository(iteration.getIteration());
+ final ArtifactVersion commonsVersion = iteration.getModuleVersion(COMMONS);
+ final ArtifactVersion buildVersion = iteration.getModuleVersion(BUILD);
- final ArtifactVersion commonsVersion = train.getModuleVersion(ReleaseTrains.COMMONS, iteration);
- final ArtifactVersion buildVersion = train.getModuleVersion(ReleaseTrains.BUILD, iteration);
- final Repository repository = new Repository(iteration);
+ for (ModuleIteration module : iteration.getModulesExcept(BUILD)) {
- File file = workspace.getFile(POM_XML, project);
+ final Project project = module.getProject();
+ File pomFile = workspace.getFile(POM_XML, project);
- execute(file, new PomCallback() {
+ execute(pomFile, new PomCallback() {
- @Override
- public Pom doWith(Pom pom) {
+ @Override
+ public Pom doWith(Pom pom) {
- if (!project.equals(ReleaseTrains.COMMONS)) {
+ if (!project.equals(COMMONS)) {
+ pom.setProperty(COMMONS_VERSION_PROPERTY,
+ CLEANUP.equals(phase) ? commonsVersion.getNextDevelopmentVersion() : commonsVersion);
+ }
- System.out.println(pom.getProperty(COMMONS_VERSION_PROPERTY));
- pom.setProperty(COMMONS_VERSION_PROPERTY, commonsVersion);
+ pom.setParentVersion(CLEANUP.equals(phase) ? buildVersion.getNextDevelopmentVersion() : buildVersion);
+ updateRepository(pom, repository, phase);
+
+ return pom;
}
-
- pom.setParentVersion(buildVersion);
- pom.setRepositoryId("spring-libs-snapshot", "spring-libs-release");
- pom.setRepositoryUrl(repository.getId(), repository.getUrl());
-
- return pom;
- }
- });
+ });
+ }
}
/**
@@ -99,23 +99,22 @@ public class MavenOperations {
* @throws IOException
* @throws InterruptedException
*/
- public void triggerDistributionBuild(Train train, Iteration iteration) throws Exception {
+ public void triggerDistributionBuild(TrainIteration iteration) throws Exception {
- for (ModuleIteration moduleIteration : train.getModuleIterations(iteration)) {
+ for (ModuleIteration moduleIteration : iteration) {
Project project = moduleIteration.getProject();
- if (ReleaseTrains.BUILD.equals(project)) {
+ if (BUILD.equals(project)) {
continue;
}
if (!isMavenProject(project)) {
- LOGGER.info(String.format("Skipping project %s as no pom.xml could be found in the working directory!",
- project.getFullName()));
+ logger.log(project, "Skipping project as no pom.xml could be found in the working directory!");
continue;
}
- LOGGER.info(String.format("Triggering distribution build for %s…", project.getFullName()));
+ logger.log(project, "Triggering distribution build…");
ArtifactVersion version = ArtifactVersion.from(moduleIteration);
@@ -133,7 +132,7 @@ public class MavenOperations {
throw result.getException();
}
- LOGGER.info(String.format("Successfully finished distribution build for %s!", project));
+ logger.log(project, "Successfully finished distribution build!");
}
}
@@ -141,19 +140,22 @@ public class MavenOperations {
return workspace.getFile(POM_XML, project).exists();
}
- private void updateBomPom(final Train train, final Iteration iteration) throws Exception {
+ private void updateBomPom(final TrainIteration iteration, final Phase phase) throws Exception {
- File bomPomFile = workspace.getFile("bom/pom.xml", ReleaseTrains.BUILD);
+ File bomPomFile = workspace.getFile("bom/pom.xml", BUILD);
execute(bomPomFile, new PomCallback() {
@Override
public Pom doWith(Pom pom) {
- for (ModuleIteration module : train.getModuleIterations(iteration, ReleaseTrains.BUILD)) {
+ for (ModuleIteration module : iteration.getModulesExcept(BUILD)) {
Artifact artifact = new Artifact(module);
- pom.setDependencyVersion(artifact.getArtifactId(), artifact.getVersion());
+ ArtifactVersion version = artifact.getVersion();
+ version = PREPARE.equals(phase) ? version : version.getNextDevelopmentVersion();
+
+ pom.setDependencyVersion(artifact.getArtifactId(), version);
}
return pom;
@@ -161,6 +163,17 @@ public class MavenOperations {
});
}
+ private void updateRepository(Pom pom, Repository repository, Phase phase) {
+
+ if (PREPARE.equals(phase)) {
+ pom.setRepositoryId(repository.getSnapshotId(), repository.getId());
+ pom.setRepositoryUrl(repository.getId(), repository.getUrl());
+ } else {
+ pom.setRepositoryId(repository.getId(), repository.getSnapshotId());
+ pom.setRepositoryUrl(repository.getSnapshotId(), repository.getSnapshotUrl());
+ }
+ }
+
private void execute(File file, PomCallback callback) throws Exception {
XBFileIO io = projectionFactory.io().file(file);
diff --git a/src/main/java/org/springframework/data/release/maven/MavenProject.java b/src/main/java/org/springframework/data/release/maven/MavenProject.java
index 3682d4f..6d1d7eb 100644
--- a/src/main/java/org/springframework/data/release/maven/MavenProject.java
+++ b/src/main/java/org/springframework/data/release/maven/MavenProject.java
@@ -24,7 +24,7 @@ import org.springframework.data.release.model.Module;
* @author Oliver Gierke
*/
@Value
-public class MavenProject {
+class MavenProject {
private final Module module;
diff --git a/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java b/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java
index 4053584..6c02351 100644
--- a/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java
+++ b/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java
@@ -24,11 +24,13 @@ 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.jira.IssueTracker;
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.Project;
import org.springframework.data.release.model.Train;
+import org.springframework.data.release.model.TrainIteration;
+import org.springframework.plugin.core.PluginRegistry;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
@@ -41,7 +43,7 @@ import com.google.common.io.Files;
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ReleaseOperations {
- private final JiraConnector jira;
+ private final PluginRegistry trackers;
private final Workspace workspace;
/**
@@ -51,14 +53,13 @@ public class ReleaseOperations {
* @param iteration must not be {@literal null}.
* @throws Exception
*/
- public void prepareChangelogs(Train train, Iteration iteration) throws Exception {
+ public void prepareChangelogs(TrainIteration 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)) {
+ for (ModuleIteration module : iteration) {
- Changelog changelog = jira.getChangelogFor(module);
+ Changelog changelog = trackers.getPluginFor(module.getProject()).getChangelogFor(module);
File file = workspace.getFile("src/main/resources/changelog.txt", module.getProject());
StringBuilder builder = new StringBuilder();
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 6034d0f..2c0ff68 100644
--- a/src/main/java/org/springframework/data/release/model/ArtifactVersion.java
+++ b/src/main/java/org/springframework/data/release/model/ArtifactVersion.java
@@ -83,18 +83,18 @@ public class ArtifactVersion implements Comparable {
Assert.notNull(iterationVersion, "IterationVersion must not be null!");
Version version = iterationVersion.getVersion();
- String iterationName = iterationVersion.getIteration().getName();
+ Iteration iteration = iterationVersion.getIteration();
- if (iterationName.equals("GA")) {
+ if (iteration.isGAVersion()) {
return new ArtifactVersion(version, RELEASE_SUFFIX);
}
- if (iterationName.startsWith("SR")) {
- int bugfixDigits = Integer.parseInt(iterationName.substring(2, iterationName.length()));
- return new ArtifactVersion(version.withBugfix(bugfixDigits), RELEASE_SUFFIX);
+ if (iteration.isServiceIteration()) {
+ Version bugfixVersion = version.withBugfix(iteration.getBugfixValue());
+ return new ArtifactVersion(bugfixVersion, RELEASE_SUFFIX);
}
- return new ArtifactVersion(version, iterationName);
+ return new ArtifactVersion(version, iteration.getName());
}
/**
diff --git a/src/main/java/org/springframework/data/release/model/Iteration.java b/src/main/java/org/springframework/data/release/model/Iteration.java
index f0c0b47..935a1d4 100644
--- a/src/main/java/org/springframework/data/release/model/Iteration.java
+++ b/src/main/java/org/springframework/data/release/model/Iteration.java
@@ -18,6 +18,8 @@ package org.springframework.data.release.model;
import lombok.NonNull;
import lombok.Value;
+import org.springframework.util.Assert;
+
/**
* Value object to represent an individual release train iteration.
*
@@ -40,6 +42,18 @@ public class Iteration {
private final @NonNull String name;
private final Iteration next;
+ Iteration(String name, Iteration next) {
+
+ Assert.hasText(name, "Name must not be null or empty!");
+
+ this.name = name;
+ this.next = next;
+ }
+
+ public boolean isGAVersion() {
+ return this.equals(GA);
+ }
+
public boolean isPublicVersion() {
return isServiceIteration() || this.equals(GA);
}
diff --git a/src/main/java/org/springframework/data/release/model/IterationVersion.java b/src/main/java/org/springframework/data/release/model/IterationVersion.java
index a6159d3..09ee3bc 100644
--- a/src/main/java/org/springframework/data/release/model/IterationVersion.java
+++ b/src/main/java/org/springframework/data/release/model/IterationVersion.java
@@ -16,6 +16,8 @@
package org.springframework.data.release.model;
/**
+ * A {@link Version} tied to an {@link Iteration}.
+ *
* @author Oliver Gierke
*/
public interface IterationVersion {
diff --git a/src/main/java/org/springframework/data/release/model/Iterations.java b/src/main/java/org/springframework/data/release/model/Iterations.java
deleted file mode 100644
index c74f410..0000000
--- a/src/main/java/org/springframework/data/release/model/Iterations.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.model;
-
-import static org.springframework.data.release.model.Iteration.*;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import lombok.Value;
-
-import org.springframework.util.Assert;
-
-/**
- * Value object to represent a set of {@link Iteration}s.
- *
- * @author Oliver Gierke
- */
-@Value
-public class Iterations implements Iterable {
-
- public static Iterations DEFAULT = new Iterations(M1, RC1, GA, SR1, SR2, SR3, SR4);
-
- private final List iterations;
-
- /**
- * Creates a new {@link Iterations} from the given {@link Iteration}.
- *
- * @param iterations
- */
- Iterations(Iteration... iterations) {
- this.iterations = Arrays.asList(iterations);
- }
-
- /**
- * Returns the iteration with the given name.
- *
- * @param name must not be {@literal null} or empty.
- * @return
- */
- public Iteration getIterationByName(String name) {
-
- Assert.hasText(name, "Name must not be null or empty!");
-
- for (Iteration iteration : this) {
- if (iteration.getName().equalsIgnoreCase(name)) {
- return iteration;
- }
- }
-
- return null;
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Iterable#iterator()
- */
- @Override
- public Iterator iterator() {
- return iterations.iterator();
- }
-}
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 e228bda..35d320b 100644
--- a/src/main/java/org/springframework/data/release/model/Module.java
+++ b/src/main/java/org/springframework/data/release/model/Module.java
@@ -29,11 +29,11 @@ public class Module {
private final Version version;
private final Iteration customFirstIteration;
- public Module(Project project, String version) {
+ Module(Project project, String version) {
this(project, version, null);
}
- public Module(Project project, String version, String customFirstIteration) {
+ Module(Project project, String version, String customFirstIteration) {
Assert.notNull(project, "Project must not be 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 62a8e09..30d1753 100644
--- a/src/main/java/org/springframework/data/release/model/ModuleIteration.java
+++ b/src/main/java/org/springframework/data/release/model/ModuleIteration.java
@@ -62,4 +62,29 @@ public class ModuleIteration implements IterationVersion {
return String.format("%s %s (%s)", module.getVersion(), iteration.getName(), train.getName());
}
+ /**
+ * Returns the {@link String} representation of the logical version of the {@link ModuleIteration}.
+ *
+ * @return
+ */
+ public String getVersionString() {
+
+ StringBuilder builder = new StringBuilder();
+ builder.append(ArtifactVersion.from(this).toShortString());
+
+ if (!iteration.isServiceIteration()) {
+ builder.append(" ").append(iteration.getName());
+ }
+
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return String.format("%s %s", module.getProject().getFullName(), getVersionString());
+ }
}
diff --git a/src/main/java/org/springframework/data/release/model/Phase.java b/src/main/java/org/springframework/data/release/model/Phase.java
new file mode 100644
index 0000000..e35b9fa
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/model/Phase.java
@@ -0,0 +1,24 @@
+/*
+ * 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.model;
+
+/**
+ * @author Oliver Gierke
+ */
+public enum Phase {
+
+ PREPARE, CLEANUP;
+}
diff --git a/src/main/java/org/springframework/data/release/model/Project.java b/src/main/java/org/springframework/data/release/model/Project.java
index dd4b93c..8cb89d2 100644
--- a/src/main/java/org/springframework/data/release/model/Project.java
+++ b/src/main/java/org/springframework/data/release/model/Project.java
@@ -18,23 +18,36 @@ package org.springframework.data.release.model;
import java.util.Arrays;
import java.util.List;
-import lombok.Value;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
/**
* @author Oliver Gierke
*/
-@Value
+@ToString
+@EqualsAndHashCode
public class Project {
- private final ProjectKey key;
- private final String name;
+ private final @Getter ProjectKey key;
+ private final @Getter String name;
private final List dependencies;
+ private final Tracker tracker;
- public Project(String key, String name, Project... dependencies) {
+ Project(String key, String name, Project... dependencies) {
+ this(key, name, Tracker.JIRA, dependencies);
+ }
+
+ Project(String key, String name, Tracker tracker, Project... dependencies) {
this.key = new ProjectKey(key);
this.name = name;
this.dependencies = Arrays.asList(dependencies);
+ this.tracker = tracker;
+ }
+
+ public boolean uses(Tracker tracker) {
+ return this.tracker.equals(tracker);
}
public String getFullName() {
diff --git a/src/main/java/org/springframework/data/release/model/Projects.java b/src/main/java/org/springframework/data/release/model/Projects.java
new file mode 100644
index 0000000..2ad8c77
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/model/Projects.java
@@ -0,0 +1,49 @@
+/*
+ * 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.model;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Oliver Gierke
+ */
+public class Projects {
+
+ public static final Project COMMONS, BUILD, REST, JPA, MONGO_DB, NEO4J, SOLR, COUCHBASE, CASSANDRA, ELASTICSEARCH,
+ REDIS, GEMFIRE;
+ public static final List PROJECTS;
+
+ static {
+
+ BUILD = new Project("DATABUILD", "Build", Tracker.GITHUB);
+ COMMONS = new Project("DATACMNS", "Commons", BUILD);
+ JPA = new Project("DATAJPA", "JPA", COMMONS);
+ MONGO_DB = new Project("DATAMONGO", "MongoDB", COMMONS);
+ NEO4J = new Project("DATAGRAPH", "Neo4j", COMMONS);
+ SOLR = new Project("DATASOLR", "Solr", COMMONS);
+ COUCHBASE = new Project("DATACOUCH", "Couchbase", COMMONS);
+ CASSANDRA = new Project("DATACASS", "Cassandra", COMMONS);
+ ELASTICSEARCH = new Project("DATAES", "Elasticsearch", COMMONS);
+ REDIS = new Project("DATAREDIS", "Redis");
+ GEMFIRE = new Project("SGF", "Gemfire", COMMONS);
+
+ REST = new Project("DATAREST", "REST", COMMONS, JPA, MONGO_DB, NEO4J, GEMFIRE);
+
+ PROJECTS = Arrays.asList(BUILD, COMMONS, JPA, MONGO_DB, NEO4J, SOLR, COUCHBASE, CASSANDRA, ELASTICSEARCH, REDIS,
+ GEMFIRE, REST);
+ }
+}
diff --git a/src/main/java/org/springframework/data/release/model/ReleaseTrains.java b/src/main/java/org/springframework/data/release/model/ReleaseTrains.java
index f0bb297..4ddfd28 100644
--- a/src/main/java/org/springframework/data/release/model/ReleaseTrains.java
+++ b/src/main/java/org/springframework/data/release/model/ReleaseTrains.java
@@ -15,6 +15,8 @@
*/
package org.springframework.data.release.model;
+import static org.springframework.data.release.model.Projects.*;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -26,30 +28,9 @@ public class ReleaseTrains {
public static final List TRAINS;
public static final Train CODD, DIJKSTRA, EVANS, FOWLER;
- public static final Project COMMONS, BUILD, REST;
-
- private static final Project JPA, MONGO_DB, NEO4J, SOLR, COUCHBASE, CASSANDRA, ELASTICSEARCH, REDIS, GEMFIRE;
- private static final List PROJECTS;
static {
- BUILD = new Project("DATABUILD", "Build");
- COMMONS = new Project("DATACMNS", "Commons", BUILD);
- JPA = new Project("DATAJPA", "JPA", COMMONS);
- MONGO_DB = new Project("DATAMONGO", "MongoDB", COMMONS);
- NEO4J = new Project("DATAGRAPH", "Neo4j", COMMONS);
- SOLR = new Project("DATASOLR", "Solr", COMMONS);
- COUCHBASE = new Project("DATACOUCH", "Couchbase", COMMONS);
- CASSANDRA = new Project("DATACASS", "Cassandra", COMMONS);
- ELASTICSEARCH = new Project("DATAES", "Elasticsearch", COMMONS);
- REDIS = new Project("DATAREDIS", "Redis");
- GEMFIRE = new Project("SGF", "Gemfire", COMMONS);
-
- REST = new Project("DATAREST", "REST", COMMONS, JPA, MONGO_DB, NEO4J, GEMFIRE);
-
- PROJECTS = Arrays.asList(BUILD, COMMONS, JPA, MONGO_DB, NEO4J, SOLR, COUCHBASE, CASSANDRA, ELASTICSEARCH, REDIS,
- GEMFIRE, REST);
-
CODD = codd();
DIJKSTRA = dijkstra();
EVANS = DIJKSTRA.next("Evans", Transition.MINOR);
diff --git a/src/main/java/org/springframework/data/release/model/Tracker.java b/src/main/java/org/springframework/data/release/model/Tracker.java
new file mode 100644
index 0000000..4383523
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/model/Tracker.java
@@ -0,0 +1,24 @@
+/*
+ * 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.model;
+
+/**
+ * @author Oliver Gierke
+ */
+public enum Tracker {
+
+ JIRA, GITHUB;
+}
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 758df5b..7f06b5b 100644
--- a/src/main/java/org/springframework/data/release/model/Train.java
+++ b/src/main/java/org/springframework/data/release/model/Train.java
@@ -15,15 +15,20 @@
*/
package org.springframework.data.release.model;
+import static org.springframework.data.release.model.Iteration.*;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
import lombok.Value;
import org.springframework.shell.support.util.OsUtils;
+import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -107,7 +112,7 @@ public class Train implements Iterable {
return getModuleIterations(iteration, new Project[0]);
}
- public Iterable getModuleIterations(Iteration iteration, Project... exclusions) {
+ List getModuleIterations(Iteration iteration, Project... exclusions) {
List iterations = new ArrayList<>(modules.size());
List exclusionList = Arrays.asList(exclusions);
@@ -144,4 +149,55 @@ public class Train implements Iterable {
return builder.toString();
}
+
+ /**
+ * Value object to represent a set of {@link Iteration}s.
+ *
+ * @author Oliver Gierke
+ */
+ @EqualsAndHashCode
+ @ToString
+ private static class Iterations implements Iterable {
+
+ public static Iterations DEFAULT = new Iterations(M1, RC1, GA, SR1, SR2, SR3, SR4);
+
+ private final List iterations;
+
+ /**
+ * Creates a new {@link Iterations} from the given {@link Iteration}.
+ *
+ * @param iterations
+ */
+ Iterations(Iteration... iterations) {
+ this.iterations = Arrays.asList(iterations);
+ }
+
+ /**
+ * Returns the iteration with the given name.
+ *
+ * @param name must not be {@literal null} or empty.
+ * @return
+ */
+ Iteration getIterationByName(String name) {
+
+ Assert.hasText(name, "Name must not be null or empty!");
+
+ for (Iteration iteration : this) {
+ if (iteration.getName().equalsIgnoreCase(name)) {
+ return iteration;
+ }
+ }
+
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Iterable#iterator()
+ */
+ @Override
+ public Iterator iterator() {
+ return iterations.iterator();
+ }
+ }
}
diff --git a/src/main/java/org/springframework/data/release/model/TrainIteration.java b/src/main/java/org/springframework/data/release/model/TrainIteration.java
new file mode 100644
index 0000000..b00372c
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/model/TrainIteration.java
@@ -0,0 +1,64 @@
+/*
+ * 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.model;
+
+import java.util.Iterator;
+
+import lombok.Value;
+
+/**
+ * @author Oliver Gierke
+ */
+@Value
+public class TrainIteration implements Iterable {
+
+ private final Train train;
+ private final Iteration iteration;
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Iterable#iterator()
+ */
+ @Override
+ public Iterator iterator() {
+ return train.getModuleIterations(iteration).iterator();
+ }
+
+ public ArtifactVersion getModuleVersion(Project project) {
+ return train.getModuleVersion(project, iteration);
+ }
+
+ public ModuleIteration getModule(String name) {
+ return train.getModuleIteration(iteration, name);
+ }
+
+ public ModuleIteration getModule(Project project) {
+ return train.getModuleIteration(iteration, project.getName());
+ }
+
+ public Iterable getModulesExcept(Project... exclusions) {
+ return train.getModuleIterations(iteration, exclusions);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return String.format("%s - %s", train.getName(), iteration.getName());
+ }
+}
diff --git a/src/main/java/org/springframework/data/release/utils/Logger.java b/src/main/java/org/springframework/data/release/utils/Logger.java
new file mode 100644
index 0000000..94c854c
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/utils/Logger.java
@@ -0,0 +1,49 @@
+/*
+ * 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.utils;
+
+import org.springframework.data.release.model.ModuleIteration;
+import org.springframework.data.release.model.Project;
+import org.springframework.data.release.model.TrainIteration;
+import org.springframework.shell.support.logging.HandlerUtils;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Oliver Gierke
+ */
+@Component
+public class Logger {
+
+ private static final String PREFIX_TEMPLATE = "%s > %s";
+
+ private final java.util.logging.Logger LOGGER = HandlerUtils.getLogger(getClass());
+
+ public void log(ModuleIteration module, String template, Object... args) {
+ log(module.getProject(), template, args);
+ }
+
+ public void log(Project project, String template, Object... args) {
+ log(project.getName(), template, args);
+ }
+
+ public void log(TrainIteration iteration, String template, Object... args) {
+ log(iteration.toString(), template, args);
+ }
+
+ private void log(String context, String template, Object... args) {
+ LOGGER.info(String.format(PREFIX_TEMPLATE, context, String.format(template, args)));
+ }
+}
diff --git a/src/test/java/org/springframework/data/release/ArtifactUnitTests.java b/src/test/java/org/springframework/data/release/ArtifactUnitTests.java
new file mode 100644
index 0000000..32af713
--- /dev/null
+++ b/src/test/java/org/springframework/data/release/ArtifactUnitTests.java
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+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.ReleaseTrains;
+
+/**
+ * @author Oliver Gierke
+ */
+public class ArtifactUnitTests {
+
+ @Test
+ public void testname() {
+
+ Artifact artifact = new Artifact(ReleaseTrains.DIJKSTRA.getModuleIteration(Iteration.M1, "JPA"));
+
+ assertThat(artifact.getArtifactId(), is("spring-data-jpa"));
+ assertThat(artifact.getVersion(), is(ArtifactVersion.parse("1.6.0.M1")));
+ assertThat(artifact.getNextDevelopmentVersion(), is(ArtifactVersion.parse("1.6.0.BUILD-SNAPSHOT")));
+ }
+}
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 1e9af7c..a2cb2ca 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,8 @@
*/
package org.springframework.data.release.git;
+import static org.springframework.data.release.model.Projects.*;
+
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -39,7 +41,7 @@ public class GitOperationsIntegrationTests extends AbstractIntegrationTests {
@Ignore
public void showTags() throws Exception {
- Tags tags = gitOperations.getTags(ReleaseTrains.COMMONS);
+ Tags tags = gitOperations.getTags(COMMONS);
System.out.println(StringUtils.collectionToDelimitedString(tags.asList(), "\n"));
}
}
diff --git a/src/test/java/org/springframework/data/release/model/IterationUnitTests.java b/src/test/java/org/springframework/data/release/model/IterationUnitTests.java
new file mode 100644
index 0000000..5277b87
--- /dev/null
+++ b/src/test/java/org/springframework/data/release/model/IterationUnitTests.java
@@ -0,0 +1,24 @@
+/*
+ * 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.model;
+
+/**
+ *
+ * @author Oliver Gierke
+ */
+public class IterationUnitTests {
+
+}
diff --git a/src/test/java/org/springframework/data/release/model/ModuleIterationUnitTests.java b/src/test/java/org/springframework/data/release/model/ModuleIterationUnitTests.java
new file mode 100644
index 0000000..a6f1b7b
--- /dev/null
+++ b/src/test/java/org/springframework/data/release/model/ModuleIterationUnitTests.java
@@ -0,0 +1,45 @@
+/*
+ * 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.model;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * @author Oliver Gierke
+ */
+public class ModuleIterationUnitTests {
+
+ @Test
+ public void abbreviatesTrailingZerosForNonServiceReleases() {
+
+ TrainIteration iteration = new TrainIteration(ReleaseTrains.DIJKSTRA, Iteration.M1);
+ ModuleIteration module = iteration.getModule(Projects.JPA);
+
+ assertThat(module.getVersionString(), is("1.6 M1"));
+ }
+
+ @Test
+ public void doesNotListIterationSuffixForServiceReleases() {
+
+ TrainIteration iteration = new TrainIteration(ReleaseTrains.DIJKSTRA, Iteration.SR1);
+ ModuleIteration module = iteration.getModule(Projects.JPA);
+
+ assertThat(module.getVersionString(), is("1.6.1"));
+ }
+}