diff --git a/infrastructure.properties b/infrastructure.properties
deleted file mode 100644
index 9f5bb8a..0000000
--- a/infrastructure.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-io.workDir=~/temp/spring-data-shell
-
-git.username=olivergierke
-git.author=Oliver Gierke
-git.email=ogierke@pivotal.io
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index a36135b..bc65060 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,16 +8,21 @@
org.springframework.boot
spring-boot-starter-parent
- 1.2.4.RELEASE
+ 1.3.0.RELEASE
1.8
- org.springframework.shell.Bootstrap
+ org.springframework.data.release.Application
+
+ org.springframework.boot
+ spring-boot-starter
+
+
org.springframework.boot
spring-boot-starter-logging
@@ -72,13 +77,18 @@
org.springframework.boot
spring-boot-starter-test
-
+
org.eclipse.jgit
org.eclipse.jgit
4.0.1.201506240215-r
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
@@ -93,8 +103,13 @@
- org.springframework.shell.Bootstrap
+ ${jar.mainclass}
spring-data-release-shell
+
+
+ git.password=${git.password}
+
+
diff --git a/readme.md b/readme.md
index 3e12c42..8d34a9a 100644
--- a/readme.md
+++ b/readme.md
@@ -1 +1,8 @@
-`mvn package appassembler:assemble && sh target/appassembler/bin/spring-data-release-shell`
\ No newline at end of file
+1. Add an `application-local.properties` to the project root and add the following properties:
+
+- `git.username` - Your GitHub username.
+- `git.password` - Your GitHub password.
+- `git.author` - Your full name (used for preparing commits).
+- `git.email` - Your email (used for preparing commits).
+
+2. Run `mvn package appassembler:assemble && sh target/appassembler/bin/spring-data-release-shell`
diff --git a/src/main/java/org/springframework/data/release/Application.java b/src/main/java/org/springframework/data/release/Application.java
new file mode 100644
index 0000000..a9e921c
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/Application.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2015 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 java.util.logging.Logger;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.shell.support.logging.HandlerUtils;
+
+/**
+ * @author Oliver Gierke
+ */
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+
+ SpringApplication application = new SpringApplication(Application.class);
+ application.setAdditionalProfiles("local");
+
+ try {
+ BootShim bs = new BootShim(args, application.run(args));
+ bs.run();
+ } catch (RuntimeException e) {
+ throw e;
+ } finally {
+ HandlerUtils.flushAllHandlers(Logger.getLogger(""));
+ }
+ }
+}
diff --git a/src/main/java/org/springframework/data/release/BootShim.java b/src/main/java/org/springframework/data/release/BootShim.java
new file mode 100644
index 0000000..91b0b60
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/BootShim.java
@@ -0,0 +1,126 @@
+package org.springframework.data.release;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.shell.CommandLine;
+import org.springframework.shell.ShellException;
+import org.springframework.shell.SimpleShellCommandLineOptions;
+import org.springframework.shell.core.ExitShellRequest;
+import org.springframework.shell.core.JLineShellComponent;
+import org.springframework.shell.support.logging.HandlerUtils;
+import org.springframework.util.StopWatch;
+
+public class BootShim {
+ private static BootShim bootstrap;
+ private static StopWatch sw = new StopWatch("Spring Shell");
+ private static CommandLine commandLine;
+ private ConfigurableApplicationContext ctx;
+
+ public BootShim(String[] args, ConfigurableApplicationContext context) {
+ this.ctx = context;
+
+ try {
+ commandLine = SimpleShellCommandLineOptions.parseCommandLine(args);
+ } catch (IOException var5) {
+ throw new ShellException(var5.getMessage(), var5);
+ }
+
+ this.configureApplicationContext(this.ctx);
+ ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner((BeanDefinitionRegistry) this.ctx);
+ if (commandLine.getDisableInternalCommands()) {
+ scanner.scan(new String[] { "org.springframework.shell.converters", "org.springframework.shell.plugin.support" });
+ } else {
+ scanner.scan(new String[] { "org.springframework.shell.commands", "org.springframework.shell.converters",
+ "org.springframework.shell.plugin.support" });
+ }
+
+ }
+
+ public ApplicationContext getApplicationContext() {
+ return this.ctx;
+ }
+
+ private void configureApplicationContext(ConfigurableApplicationContext annctx) {
+ this.createAndRegisterBeanDefinition(annctx, JLineShellComponent.class, "shell");
+ annctx.getBeanFactory().registerSingleton("commandLine", commandLine);
+ }
+
+ protected void createAndRegisterBeanDefinition(GenericApplicationContext annctx, Class> clazz) {
+ this.createAndRegisterBeanDefinition(annctx, clazz, (String) null);
+ }
+
+ protected void createAndRegisterBeanDefinition(ConfigurableApplicationContext annctx, Class> clazz, String name) {
+ RootBeanDefinition rbd = new RootBeanDefinition();
+ rbd.setBeanClass(clazz);
+ DefaultListableBeanFactory bf = (DefaultListableBeanFactory) annctx.getBeanFactory();
+ if (name != null) {
+ bf.registerBeanDefinition(name, rbd);
+ } else {
+ bf.registerBeanDefinition(clazz.getSimpleName(), rbd);
+ }
+
+ }
+
+ private void setupLogging() {
+ Logger rootLogger = Logger.getLogger("");
+ HandlerUtils.wrapWithDeferredLogHandler(rootLogger, Level.SEVERE);
+ Logger sfwLogger = Logger.getLogger("org.springframework");
+ sfwLogger.setLevel(Level.WARNING);
+ Logger rooLogger = Logger.getLogger("org.springframework.shell");
+ rooLogger.setLevel(Level.FINE);
+ }
+
+ public ExitShellRequest run() {
+ sw.start();
+ String[] commandsToExecuteAndThenQuit = commandLine.getShellCommandsToExecute();
+ JLineShellComponent shell = (JLineShellComponent) this.ctx.getBean("shell", JLineShellComponent.class);
+ ExitShellRequest exitShellRequest;
+ if (null != commandsToExecuteAndThenQuit) {
+ boolean successful = false;
+ exitShellRequest = ExitShellRequest.FATAL_EXIT;
+ String[] arr$ = commandsToExecuteAndThenQuit;
+ int len$ = commandsToExecuteAndThenQuit.length;
+
+ for (int i$ = 0; i$ < len$; ++i$) {
+ String cmd = arr$[i$];
+ successful = shell.executeCommand(cmd).isSuccess();
+ if (!successful) {
+ break;
+ }
+ }
+
+ if (successful) {
+ exitShellRequest = ExitShellRequest.NORMAL_EXIT;
+ }
+ } else {
+ shell.start();
+ shell.promptLoop();
+ exitShellRequest = shell.getExitShellRequest();
+ if (exitShellRequest == null) {
+ exitShellRequest = ExitShellRequest.NORMAL_EXIT;
+ }
+
+ shell.waitForComplete();
+ }
+
+ sw.stop();
+ if (shell.isDevelopmentMode()) {
+ System.out.println("Total execution time: " + sw.getLastTaskTimeMillis() + " ms");
+ }
+
+ return exitShellRequest;
+ }
+
+ public JLineShellComponent getJLineShellComponent() {
+ return (JLineShellComponent) this.ctx.getBean("shell", JLineShellComponent.class);
+ }
+}
diff --git a/src/main/java/org/springframework/data/release/io/OsConfiguration.java b/src/main/java/org/springframework/data/release/CliComponent.java
similarity index 59%
rename from src/main/java/org/springframework/data/release/io/OsConfiguration.java
rename to src/main/java/org/springframework/data/release/CliComponent.java
index 77d5416..8e2fa2c 100644
--- a/src/main/java/org/springframework/data/release/io/OsConfiguration.java
+++ b/src/main/java/org/springframework/data/release/CliComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2015 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.
@@ -13,16 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.data.release.io;
+package org.springframework.data.release;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.PropertySource;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.stereotype.Component;
/**
* @author Oliver Gierke
*/
-@Configuration
-@PropertySource("file:infrastructure.properties")
-class OsConfiguration {
+@Component
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface CliComponent {
}
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 e504ae5..41c6b47 100644
--- a/src/main/java/org/springframework/data/release/announcement/AnnouncementOperations.java
+++ b/src/main/java/org/springframework/data/release/announcement/AnnouncementOperations.java
@@ -79,6 +79,6 @@ public class AnnouncementOperations {
public static void main(String[] args) {
AnnouncementOperations operations = new AnnouncementOperations();
- System.out.println(operations.getProjectBulletpoints(new TrainIteration(ReleaseTrains.FOWLER, Iteration.SR1)));
+ System.out.println(operations.getProjectBulletpoints(new TrainIteration(ReleaseTrains.GOSLING, Iteration.SR1)));
}
}
diff --git a/src/main/java/org/springframework/data/release/cli/IssueTracerCommands.java b/src/main/java/org/springframework/data/release/cli/IssueTrackerCommands.java
similarity index 76%
rename from src/main/java/org/springframework/data/release/cli/IssueTracerCommands.java
rename to src/main/java/org/springframework/data/release/cli/IssueTrackerCommands.java
index 15268dc..f2c0ebd 100644
--- a/src/main/java/org/springframework/data/release/cli/IssueTracerCommands.java
+++ b/src/main/java/org/springframework/data/release/cli/IssueTrackerCommands.java
@@ -15,26 +15,30 @@
*/
package org.springframework.data.release.cli;
+import java.util.stream.Collectors;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
+import org.springframework.data.release.CliComponent;
+import org.springframework.data.release.jira.Changelog;
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.ModuleIteration;
import org.springframework.data.release.model.Project;
import org.springframework.data.release.model.TrainIteration;
+import org.springframework.data.release.utils.ExecutionUtils;
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;
-import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
/**
* @author Oliver Gierke
*/
-@Component
-public class IssueTracerCommands implements CommandMarker {
+@CliComponent
+public class IssueTrackerCommands implements CommandMarker {
private final PluginRegistry tracker;
private final JiraConnector jira;
@@ -45,7 +49,8 @@ public class IssueTracerCommands implements CommandMarker {
* @param environment
*/
@Autowired
- public IssueTracerCommands(PluginRegistry tracker, JiraConnector jira, Environment environment) {
+ public IssueTrackerCommands(PluginRegistry tracker, JiraConnector jira,
+ Environment environment) {
String username = environment.getProperty("jira.username", (String) null);
String password = environment.getProperty("jira.password", (String) null);
@@ -61,9 +66,9 @@ public class IssueTracerCommands implements CommandMarker {
}
@CliCommand(value = "jira tickets")
- public String jira(
- @CliOption(key = "", mandatory = true) TrainIteration iteration, //
- @CliOption(key = "for-current-user", specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") boolean forCurrentUser) {
+ public String jira(@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!";
@@ -82,14 +87,11 @@ public class IssueTracerCommands implements CommandMarker {
return tracker.getPluginFor(module.getProject()).getChangelogFor(module).toString();
}
- StringBuilder builder = new StringBuilder();
+ return ExecutionUtils.runAndReturn(iteration, this::getChangelog).//
+ stream().map(it -> it.toString()).collect(Collectors.joining("\n"));
+ }
- for (ModuleIteration module : iteration) {
-
- IssueTracker issues = tracker.getPluginFor(module.getProject());
- builder.append(issues.getChangelogFor(module)).append("\n");
- }
-
- return builder.toString();
+ private Changelog getChangelog(ModuleIteration module) {
+ return tracker.getPluginFor(module.getProject()).getChangelogFor(module);
}
}
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 522e3b1..ebad2ad 100644
--- a/src/main/java/org/springframework/data/release/cli/ModelCommands.java
+++ b/src/main/java/org/springframework/data/release/cli/ModelCommands.java
@@ -15,36 +15,25 @@
*/
package org.springframework.data.release.cli;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.stream.Collectors;
+import org.springframework.data.release.CliComponent;
import org.springframework.data.release.model.ReleaseTrains;
import org.springframework.data.release.model.Train;
import org.springframework.shell.core.CommandMarker;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
-import org.springframework.stereotype.Component;
-import org.springframework.util.StringUtils;
/**
* @author Oliver Gierke
*/
-@Component
+@CliComponent
public class ModelCommands implements CommandMarker {
@CliCommand("trains")
public String train(@CliOption(key = { "", "train" }) Train train) {
- if (train != null) {
- return train.toString();
- }
-
- List names = new ArrayList<>();
-
- for (Train releaseTrain : ReleaseTrains.TRAINS) {
- names.add(releaseTrain.getName());
- }
-
- return StringUtils.collectionToDelimitedString(names, ", ");
+ return train != null ? train.toString()
+ : ReleaseTrains.TRAINS.stream().map(Train::getName).collect(Collectors.joining(", "));
}
}
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 ac4b94b..a8b4268 100644
--- a/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java
+++ b/src/main/java/org/springframework/data/release/cli/ReleaseCommands.java
@@ -16,18 +16,17 @@
package org.springframework.data.release.cli;
import static org.springframework.data.release.model.Projects.*;
+
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.release.docs.DocumentationOperations;
import org.springframework.data.release.git.GitOperations;
-import org.springframework.data.release.git.Tags;
+import org.springframework.data.release.git.VersionTags;
import org.springframework.data.release.gradle.GradleOperations;
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.Module;
import org.springframework.data.release.model.Phase;
import org.springframework.data.release.model.ReleaseTrains;
import org.springframework.data.release.model.Train;
@@ -41,7 +40,7 @@ import org.springframework.stereotype.Component;
* @author Oliver Gierke
*/
@Component
-@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
public class ReleaseCommands implements CommandMarker {
private final MavenOperations maven;
@@ -53,25 +52,16 @@ public class ReleaseCommands implements CommandMarker {
@CliCommand("release predict")
public String predictTrainAndIteration() throws Exception {
- Pom pom = maven.getMavenProject(COMMONS);
+ return git.getTags(COMMONS).getLatest().toArtifactVersion().//
+ map(this::getTrainNameForCommonsVersion).//
+ orElse(null);
+ }
- Tags tags = git.getTags(COMMONS);
+ public String getTrainNameForCommonsVersion(ArtifactVersion version) {
- ArtifactVersion version = tags.getLatest().toArtifactVersion();
- System.out.println(version);
-
- for (Train train : ReleaseTrains.TRAINS) {
-
- Module module = train.getModule(COMMONS);
-
- if (!pom.getVersion().toString().startsWith(module.getVersion().toMajorMinorBugfix())) {
- continue;
- }
-
- return train.getName();
- }
-
- return null;
+ return ReleaseTrains.TRAINS.stream().//
+ filter(train -> version.toString().startsWith(train.getModule(COMMONS).getVersion().toString())).//
+ findFirst().map(Train::getName).orElse(null);
}
/**
diff --git a/src/main/java/org/springframework/data/release/cli/StaticResources.java b/src/main/java/org/springframework/data/release/cli/StaticResources.java
index a2bb509..863136f 100644
--- a/src/main/java/org/springframework/data/release/cli/StaticResources.java
+++ b/src/main/java/org/springframework/data/release/cli/StaticResources.java
@@ -34,7 +34,7 @@ public class StaticResources {
public StaticResources(ModuleIteration module) {
Project project = module.getProject();
- ArtifactVersion version = ArtifactVersion.from(module);
+ ArtifactVersion version = ArtifactVersion.of(module);
this.baseUrl = String.format(URL_TEMPLATE, project.getName().toLowerCase(), version);
}
diff --git a/src/main/java/org/springframework/data/release/cli/TrainConverter.java b/src/main/java/org/springframework/data/release/cli/TrainConverter.java
index 5ab2deb..b33b3bd 100644
--- a/src/main/java/org/springframework/data/release/cli/TrainConverter.java
+++ b/src/main/java/org/springframework/data/release/cli/TrainConverter.java
@@ -56,7 +56,6 @@ public class TrainConverter implements Converter {
@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/docs/DocumentationOperations.java b/src/main/java/org/springframework/data/release/docs/DocumentationOperations.java
index 584cf89..2ac390d 100644
--- a/src/main/java/org/springframework/data/release/docs/DocumentationOperations.java
+++ b/src/main/java/org/springframework/data/release/docs/DocumentationOperations.java
@@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.release.git.GitOperations;
import org.springframework.data.release.git.GitProject;
import org.springframework.data.release.git.Tag;
-import org.springframework.data.release.git.Tags;
+import org.springframework.data.release.git.VersionTags;
import org.springframework.data.release.io.Workspace;
import org.springframework.data.release.io.Workspace.LineCallback;
import org.springframework.data.release.model.ModuleIteration;
@@ -44,7 +44,7 @@ public class DocumentationOperations {
public void updateDockbookIncludes(TrainIteration iteration) throws Exception {
- Tags tags = git.getTags(COMMONS);
+ VersionTags tags = git.getTags(COMMONS);
ModuleIteration commons = iteration.getModule(COMMONS);
ModuleIteration previousIteration = iteration.getPreviousIteration(commons);
diff --git a/src/main/java/org/springframework/data/release/git/GitCommands.java b/src/main/java/org/springframework/data/release/git/GitCommands.java
index db07d85..62f4cfb 100644
--- a/src/main/java/org/springframework/data/release/git/GitCommands.java
+++ b/src/main/java/org/springframework/data/release/git/GitCommands.java
@@ -18,6 +18,7 @@ package org.springframework.data.release.git;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.release.CliComponent;
import org.springframework.data.release.model.Project;
import org.springframework.data.release.model.ReleaseTrains;
import org.springframework.data.release.model.Train;
@@ -25,14 +26,13 @@ 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;
-import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
/**
* @author Oliver Gierke
*/
-@Component
-@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+@CliComponent
+@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
public class GitCommands implements CommandMarker {
private final GitOperations git;
@@ -43,8 +43,8 @@ public class GitCommands implements CommandMarker {
}
@CliCommand("git update")
- public void checkout(@CliOption(key = { "", "train" }, mandatory = true) String trainName) throws Exception,
- InterruptedException {
+ public void checkout(@CliOption(key = { "", "train" }, mandatory = true) String trainName)
+ throws Exception, InterruptedException {
git.update(ReleaseTrains.getTrainByName(trainName));
}
@@ -84,7 +84,7 @@ public class GitCommands implements CommandMarker {
public void push(//
@CliOption(key = "", mandatory = true) TrainIteration iteration, //
@CliOption(key = "tags", specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") String tags)
- throws Exception {
+ throws Exception {
boolean pushTags = Boolean.parseBoolean(tags);
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 b49ad9f..9db5f6b 100644
--- a/src/main/java/org/springframework/data/release/git/GitOperations.java
+++ b/src/main/java/org/springframework/data/release/git/GitOperations.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2014-2015 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.
@@ -19,12 +19,8 @@ import lombok.RequiredArgsConstructor;
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Future;
import java.util.stream.Collectors;
-
-import javax.annotation.PostConstruct;
+import java.util.stream.StreamSupport;
import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
@@ -36,31 +32,25 @@ import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
-import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.TagOpt;
-import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.env.Environment;
-import org.springframework.data.release.io.CommandResult;
import org.springframework.data.release.io.Workspace;
import org.springframework.data.release.jira.IssueTracker;
import org.springframework.data.release.jira.Ticket;
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.ModuleIteration;
import org.springframework.data.release.model.Project;
import org.springframework.data.release.model.Train;
import org.springframework.data.release.model.TrainIteration;
-import org.springframework.data.release.utils.CommandUtils;
+import org.springframework.data.release.utils.ExecutionUtils;
import org.springframework.data.release.utils.Logger;
import org.springframework.plugin.core.PluginRegistry;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
/**
- * Component to execut Git related operations.
+ * Component to execute Git related operations.
*
* @author Oliver Gierke
*/
@@ -72,15 +62,7 @@ public class GitOperations {
private final Workspace workspace;
private final Logger logger;
private final PluginRegistry issueTracker;
- private final Environment environment;
-
- private CredentialsProvider credentials;
-
- @PostConstruct
- public void init() {
- this.credentials = new UsernamePasswordCredentialsProvider(environment.getProperty("git.username"),
- environment.getProperty("git.password"));
- }
+ private final GitProperties gitProperties;
public GitProject getGitProject(Project project) {
return new GitProject(project, server);
@@ -96,7 +78,7 @@ public class GitOperations {
Assert.notNull(train, "Train must not be null!");
- for (ModuleIteration module : train) {
+ ExecutionUtils.run(train, module -> {
Branch branch = Branch.from(module);
@@ -109,24 +91,23 @@ public class GitOperations {
setRef("origin/".concat(branch.toString())).//
call();
}
- }
+ });
}
/**
- * Checks out all projects of the given {@link Train} at the tags for the given {@link Iteration}.
+ * Checks out all projects of the given {@link TrainIteration}.
*
- * @param train
* @param iteration
* @throws Exception
*/
- public void checkout(TrainIteration iteration) throws Exception {
+ public void checkout(TrainIteration iteration) {
update(iteration.getTrain());
- for (ModuleIteration module : iteration) {
+ ExecutionUtils.run(iteration, module -> {
Project project = module.getProject();
- ArtifactVersion artifactVersion = ArtifactVersion.from(module);
+ ArtifactVersion artifactVersion = ArtifactVersion.of(module);
Tag tag = findTagFor(project, artifactVersion);
@@ -138,16 +119,17 @@ public class GitOperations {
try (Git git = new Git(getRepository(module.getProject()))) {
logger.log(module, "git checkout %s", tag);
+
git.checkout().setStartPoint(tag.toString());
}
- }
+ });
logger.log(iteration, "Successfully checked out projects.");
}
public void prepare(TrainIteration iteration) throws Exception {
- for (ModuleIteration module : iteration) {
+ ExecutionUtils.run(iteration, module -> {
Branch branch = Branch.from(module);
@@ -161,28 +143,18 @@ public class GitOperations {
setRebase(true).//
call();
}
- }
+ });
}
- public void update(Train train) throws Exception {
-
- List> executions = new ArrayList<>();
-
- for (Module module : train) {
- update(module.getProject());
- }
-
- for (Future execution : executions) {
- CommandUtils.getCommandResult(execution);
- }
+ public void update(Train train) {
+ ExecutionUtils.run(train, module -> update(module.getProject()));
}
- public void push(TrainIteration iteration) throws Exception {
+ public void push(TrainIteration iteration) {
- for (ModuleIteration module : iteration) {
+ ExecutionUtils.run(iteration, module -> {
Branch branch = Branch.from(module);
-
logger.log(module, "git push origin %s", branch);
try (Git git = new Git(getRepository(module.getProject()))) {
@@ -192,15 +164,15 @@ public class GitOperations {
git.push().//
setRemote("origin").//
setRefSpecs(new RefSpec(ref.getName())).//
- setCredentialsProvider(credentials).//
+ setCredentialsProvider(gitProperties.getCredentials()).//
call();
}
- }
+ });
}
- public void pushTags(Train train) throws Exception {
+ public void pushTags(Train train) {
- for (Module module : train) {
+ ExecutionUtils.run(train.getModules(), module -> {
logger.log(module.getProject(), "git push --tags");
@@ -209,10 +181,10 @@ public class GitOperations {
git.push().//
setRemote("origin").//
setPushTags().//
- setCredentialsProvider(this.credentials).//
+ setCredentialsProvider(gitProperties.getCredentials()).//
call();
}
- }
+ });
}
public void update(Project project) throws Exception {
@@ -220,9 +192,7 @@ public class GitOperations {
GitProject gitProject = new GitProject(project, server);
String repositoryName = gitProject.getRepositoryName();
- Repository repository = getRepository(project);
-
- try (Git git = new Git(repository)) {
+ try (Git git = new Git(getRepository(project))) {
if (workspace.hasProjectDirectory(project)) {
@@ -232,35 +202,34 @@ public class GitOperations {
checkout(project, Branch.MASTER);
git.reset().setMode(ResetType.HARD).call();
-
git.fetch().setTagOpt(TagOpt.FETCH_TAGS);
-
git.pull().call();
- // return os.executeCommand("git checkout master && git reset --hard && git fetch --tags && git pull origin
- // master",
- // project);
-
} else {
logger.log(project, "No repository found! Cloning from %s…", gitProject.getProjectUri());
- clone(project);
- // return os.executeCommand(command);
+ clone(project);
}
}
}
- public Tags getTags(Project project) throws Exception {
+ public VersionTags getTags(Project project) {
try (Git git = new Git(getRepository(project))) {
- return new Tags(git.tagList().call().stream().map(ref -> new Tag(ref.getName())).collect(Collectors.toList()));
+
+ return new VersionTags(git.tagList().call().stream().//
+ map(ref -> Tag.of(ref.getName())).//
+ collect(Collectors.toList()));
+
+ } catch (Exception o_O) {
+ throw new RuntimeException(o_O);
}
}
- public void tagRelease(TrainIteration iteration) throws Exception {
+ public void tagRelease(TrainIteration iteration) {
- for (ModuleIteration module : iteration) {
+ ExecutionUtils.run(iteration, module -> {
Branch branch = Branch.from(module);
Project project = module.getProject();
@@ -284,7 +253,7 @@ public class GitOperations {
git.tag().setName(tag.toString()).setObjectId(commit).call();
}
}
- }
+ });
}
/**
@@ -301,19 +270,17 @@ public class GitOperations {
Assert.notNull(iteration, "Train iteration must not be null!");
Assert.hasText(summary, "Summary must not be null or empty!");
- for (ModuleIteration module : iteration) {
- commit(module, expandSummary(summary, module, iteration), details);
- }
+ ExecutionUtils.run(iteration, module -> commit(module, expandSummary(summary, module, iteration), details));
}
- private String expandSummary(String summary, ModuleIteration module, TrainIteration iteration) {
+ private static String expandSummary(String summary, ModuleIteration module, TrainIteration iteration) {
if (!summary.contains("%s")) {
return summary;
}
return String.format(summary,
- ArtifactVersion.from(module).toString().concat(String.format(" (%s)", iteration.toString())));
+ ArtifactVersion.of(module).toString().concat(String.format(" (%s)", iteration.toString())));
}
/**
@@ -336,8 +303,8 @@ public class GitOperations {
Ticket ticket = tracker.getReleaseTicketFor(module);
Commit commit = new Commit(ticket, summary, details);
- String author = environment.getProperty("git.author");
- String email = environment.getProperty("git.email");
+ String author = gitProperties.getAuthor();
+ String email = gitProperties.getEmail();
logger.log(module, "git commit -m \"%s\" --author=\"%s <%s>\"", commit, author, email);
@@ -382,16 +349,12 @@ public class GitOperations {
* @return
* @throws IOException
*/
- private Tag findTagFor(Project project, ArtifactVersion version) throws Exception {
+ private Tag findTagFor(Project project, ArtifactVersion version) {
- for (Tag tag : getTags(project)) {
-
- if (tag.toArtifactVersion().equals(version)) {
- return tag;
- }
- }
-
- return null;
+ return StreamSupport.stream(getTags(project).spliterator(), false).//
+ filter(tag -> tag.toArtifactVersion().map(it -> it.equals(version)).orElse(false)).//
+ findFirst().orElseThrow(() -> new IllegalArgumentException(
+ String.format("No tag found for version %s of project %s!", version, project)));
}
public void checkout(Project project, Branch branch) throws Exception {
@@ -409,10 +372,11 @@ public class GitOperations {
}
checkout.call();
+
}
}
- private Repository getRepository(Project project) throws Exception {
+ private Repository getRepository(Project project) throws IOException {
return FileRepositoryBuilder.create(workspace.getFile(".git", project));
}
diff --git a/src/main/java/org/springframework/data/release/git/GitProperties.java b/src/main/java/org/springframework/data/release/git/GitProperties.java
new file mode 100644
index 0000000..fa73c59
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/git/GitProperties.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2015 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.git;
+
+import lombok.AccessLevel;
+import lombok.Data;
+import lombok.Getter;
+
+import javax.annotation.PostConstruct;
+
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
+
+/**
+ * Configurable properties for Git.
+ *
+ * @author Oliver Gierke
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "git")
+public class GitProperties {
+
+ private @Getter(AccessLevel.PRIVATE) String username, password;
+ private String author, email;
+
+ @PostConstruct
+ public void init() {
+
+ Assert.hasText(username, "No GitHub username (git.username) configured!");
+ Assert.hasText(username, "No GitHub password (git.password) configured!");
+ Assert.hasText(username, "No Git author (git.author) configured!");
+ Assert.hasText(username, "No Git email (git.email) configured!");
+ }
+
+ /**
+ * Returns the jGit {@link CredentialsProvider} to be used.
+ *
+ * @return
+ */
+ public CredentialsProvider getCredentials() {
+ return new UsernamePasswordCredentialsProvider(username, password);
+ }
+}
diff --git a/src/main/java/org/springframework/data/release/git/Tag.java b/src/main/java/org/springframework/data/release/git/Tag.java
index c09210f..c0459b6 100644
--- a/src/main/java/org/springframework/data/release/git/Tag.java
+++ b/src/main/java/org/springframework/data/release/git/Tag.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2014-2015 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.
@@ -15,9 +15,12 @@
*/
package org.springframework.data.release.git;
+import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
+import java.util.Optional;
+
import org.springframework.data.release.model.ArtifactVersion;
/**
@@ -25,12 +28,19 @@ import org.springframework.data.release.model.ArtifactVersion;
*
* @author Oliver Gierke
*/
-@RequiredArgsConstructor
@EqualsAndHashCode
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class Tag implements Comparable {
private final String name;
+ public static Tag of(String source) {
+
+ int slashIndex = source.lastIndexOf('/');
+
+ return new Tag(source.substring(slashIndex == -1 ? 0 : slashIndex + 1));
+ }
+
/**
* Returns the part of the name of the tag that is suitable to derive a version from the tag. Will transparently strip
* a {@code v} prefix from the name.
@@ -41,8 +51,17 @@ public class Tag implements Comparable {
return name.startsWith("v") ? name.substring(1) : name;
}
- public ArtifactVersion toArtifactVersion() {
- return ArtifactVersion.parse(getVersionSource());
+ public boolean isVersionTag() {
+ return toArtifactVersion().isPresent();
+ }
+
+ public Optional toArtifactVersion() {
+
+ try {
+ return Optional.of(ArtifactVersion.of(getVersionSource()));
+ } catch (IllegalArgumentException o_O) {
+ return Optional.empty();
+ }
}
/**
@@ -70,6 +89,10 @@ public class Tag implements Comparable {
*/
@Override
public int compareTo(Tag that) {
- return that.name.compareTo(this.name);
+
+ // Prefer artifact versions but fall back to name comparison
+
+ return toArtifactVersion().map(left -> that.toArtifactVersion().map(right -> left.compareTo(right)).//
+ orElse(name.compareTo(that.name))).orElse(name.compareTo(that.name));
}
}
diff --git a/src/main/java/org/springframework/data/release/git/Tags.java b/src/main/java/org/springframework/data/release/git/VersionTags.java
similarity index 79%
rename from src/main/java/org/springframework/data/release/git/Tags.java
rename to src/main/java/org/springframework/data/release/git/VersionTags.java
index ec2fde6..635e3a0 100644
--- a/src/main/java/org/springframework/data/release/git/Tags.java
+++ b/src/main/java/org/springframework/data/release/git/VersionTags.java
@@ -15,12 +15,11 @@
*/
package org.springframework.data.release.git;
-import java.util.ArrayList;
-import java.util.Collections;
+import lombok.EqualsAndHashCode;
+
import java.util.Iterator;
import java.util.List;
-
-import lombok.EqualsAndHashCode;
+import java.util.stream.Collectors;
import org.springframework.data.release.model.ArtifactVersion;
import org.springframework.data.release.model.ModuleIteration;
@@ -32,23 +31,22 @@ import org.springframework.util.Assert;
* @author Oliver Gierke
*/
@EqualsAndHashCode
-public class Tags implements Iterable {
+public class VersionTags implements Iterable {
private final List tags;
/**
- * Creates a new {@link Tags} instance for the given {@link List} of {@link Tag}s.
+ * Creates a new {@link VersionTags} instance for the given {@link List} of {@link Tag}s.
*
* @param source must not be {@literal null}.
*/
- Tags(List source) {
+ VersionTags(List source) {
Assert.notNull(source, "Tags must not be null!");
- List tags = new ArrayList<>(source);
- Collections.sort(tags);
-
- this.tags = Collections.unmodifiableList(tags);
+ this.tags = source.stream().//
+ filter(Tag::isVersionTag).//
+ sorted().collect(Collectors.toList());
}
/**
@@ -57,11 +55,11 @@ public class Tags implements Iterable {
* @return
*/
public Tag getLatest() {
- return tags.get(0);
+ return tags.get(tags.size() - 1);
}
public Tag createTag(ModuleIteration iteration) {
- return getLatest().createNew(ArtifactVersion.from(iteration));
+ return getLatest().createNew(ArtifactVersion.of(iteration));
}
/**
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 0f7cb2f..4eed8fa 100644
--- a/src/main/java/org/springframework/data/release/io/CommonsExecOsCommandOperations.java
+++ b/src/main/java/org/springframework/data/release/io/CommonsExecOsCommandOperations.java
@@ -24,8 +24,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
-import javax.annotation.PostConstruct;
-
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecuteResultHandler;
import org.apache.commons.exec.DefaultExecutor;
@@ -140,7 +138,7 @@ class CommonsExecOsCommandOperations implements OsCommandOperations {
*
* @throws Exception
*/
- @PostConstruct
+ // @PostConstruct
public void initialize() throws Exception {
String javaHome = executeCommand("/usr/libexec/java_home -F -v 1.8 -a x86_64 -d64").get().getOutput();
diff --git a/src/main/java/org/springframework/data/release/io/IoProperties.java b/src/main/java/org/springframework/data/release/io/IoProperties.java
new file mode 100644
index 0000000..aca10cd
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/io/IoProperties.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2015 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.io;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.File;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Oliver Gierke
+ */
+@Slf4j
+@Data
+@Component
+@ConfigurationProperties(prefix = "io")
+public class IoProperties {
+
+ private String workDir;
+
+ public void setWorkDir(String workDir) {
+
+ this.workDir = workDir.replace("~", System.getProperty("user.home"));
+ log.info(String.format("Using %s as working directory!", workDir));
+ }
+
+ public File getWorkDir() {
+ return new File(workDir);
+ }
+}
diff --git a/src/main/java/org/springframework/data/release/io/Workspace.java b/src/main/java/org/springframework/data/release/io/Workspace.java
index 34366bc..dfdeed3 100644
--- a/src/main/java/org/springframework/data/release/io/Workspace.java
+++ b/src/main/java/org/springframework/data/release/io/Workspace.java
@@ -15,6 +15,8 @@
*/
package org.springframework.data.release.io;
+import lombok.RequiredArgsConstructor;
+
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
@@ -23,10 +25,7 @@ import java.util.Scanner;
import javax.annotation.PostConstruct;
-import lombok.RequiredArgsConstructor;
-
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.env.Environment;
import org.springframework.data.release.model.Project;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
@@ -39,14 +38,12 @@ import com.google.common.io.Files;
* @author Oliver Gierke
*/
@Component
-@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
public class Workspace {
private static final Charset UTF_8 = Charset.forName("UTF-8");
- public static final String WORK_DIR_PROPERTY = "io.workDir";
-
- private final Environment environment;
+ private final IoProperties ioProperties;
/**
* Returns the current working directory.
@@ -54,9 +51,7 @@ public class Workspace {
* @return
*/
public File getWorkingDirectory() {
-
- String workDir = environment.getProperty("io.workDir");
- return new File(workDir.replace("~", System.getProperty("user.home")));
+ return ioProperties.getWorkDir();
}
/**
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 facb97b..5c28990 100644
--- a/src/main/java/org/springframework/data/release/jira/Changelog.java
+++ b/src/main/java/org/springframework/data/release/jira/Changelog.java
@@ -44,7 +44,7 @@ public class Changelog {
@Override
public String toString() {
- ArtifactVersion version = ArtifactVersion.from(module);
+ ArtifactVersion version = ArtifactVersion.of(module);
String headline = String.format("Changes in version %s (%s)", version,
new DateFormatter("YYYY-MM-dd").print(new Date(), Locale.US));
diff --git a/src/main/java/org/springframework/data/release/jira/GitHubIssueTracker.java b/src/main/java/org/springframework/data/release/jira/GitHubIssueTracker.java
index 552ede0..540b1bb 100644
--- a/src/main/java/org/springframework/data/release/jira/GitHubIssueTracker.java
+++ b/src/main/java/org/springframework/data/release/jira/GitHubIssueTracker.java
@@ -15,14 +15,14 @@
*/
package org.springframework.data.release.jira;
+import lombok.RequiredArgsConstructor;
+
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 java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
@@ -48,7 +48,7 @@ import org.springframework.web.util.UriTemplate;
* @author Oliver Gierke
*/
@Component
-@RequiredArgsConstructor(onConstructor = @_(@Autowired))
+@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
class GitHubIssueTracker implements IssueTracker {
private static final String MILESTONE_URI = "https://api.github.com/repos/spring-projects/{repoName}/milestones?state={state}";
@@ -68,13 +68,12 @@ class GitHubIssueTracker implements IssueTracker {
@Cacheable("release-tickets")
public Ticket getReleaseTicketFor(ModuleIteration module) {
- for (GitHubIssue issue : getIssuesFor(module)) {
- if (issue.isReleaseTicket(module)) {
- return new Ticket(issue.getId(), issue.getTitle());
- }
- }
-
- throw new IllegalArgumentException(String.format("Could not find a release ticket for %s!", module));
+ return getIssuesFor(module).stream().//
+ filter(issue -> issue.isReleaseTicket(module)).//
+ findFirst().//
+ map(issue -> new Ticket(issue.getId(), issue.getTitle())).//
+ orElseThrow(
+ () -> new IllegalArgumentException(String.format("Could not find a release ticket for %s!", module)));
}
/*
@@ -85,12 +84,9 @@ class GitHubIssueTracker implements IssueTracker {
@Cacheable("changelogs")
public Changelog getChangelogFor(ModuleIteration module) {
- List issues = getIssuesFor(module);
- List tickets = new ArrayList<>(issues.size());
-
- for (GitHubIssue issue : issues) {
- tickets.add(new Ticket(issue.getId(), issue.getTitle()));
- }
+ List tickets = getIssuesFor(module).stream().//
+ map(issue -> new Ticket(issue.getId(), issue.getTitle())).//
+ collect(Collectors.toList());
logger.log(module, "Created changelog with %s entries.", tickets.size());
@@ -131,8 +127,8 @@ class GitHubIssueTracker implements IssueTracker {
logger.log(module, "Looking up milestone from %s…", milestoneUri);
- List exchange = operations.exchange(MILESTONE_URI, HttpMethod.GET, null, MILESTONES_TYPE,
- parameters).getBody();
+ List exchange = operations
+ .exchange(MILESTONE_URI, HttpMethod.GET, null, MILESTONES_TYPE, parameters).getBody();
GitHubMilestone milestone = null;
diff --git a/src/main/java/org/springframework/data/release/jira/Jira.java b/src/main/java/org/springframework/data/release/jira/Jira.java
index 6ac1e81..ca50090 100644
--- a/src/main/java/org/springframework/data/release/jira/Jira.java
+++ b/src/main/java/org/springframework/data/release/jira/Jira.java
@@ -15,6 +15,8 @@
*/
package org.springframework.data.release.jira;
+import lombok.RequiredArgsConstructor;
+
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
@@ -22,13 +24,12 @@ 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.boot.SpringApplication;
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.Application;
import org.springframework.data.release.model.Iteration;
import org.springframework.data.release.model.ModuleIteration;
import org.springframework.data.release.model.Project;
@@ -47,7 +48,7 @@ import org.springframework.web.util.UriTemplate;
* @author Oliver Gierke
*/
@Component
-@RequiredArgsConstructor(onConstructor = @_(@Autowired))
+@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
class Jira implements JiraConnector {
private static final String JIRA_HOST = "https://jira.spring.io";
@@ -64,9 +65,7 @@ class Jira implements JiraConnector {
*/
@Override
@CacheEvict(value = "tickets", allEntries = true)
- public void reset() {
-
- }
+ public void reset() {}
@Cacheable("release-tickets")
public Ticket getReleaseTicketFor(ModuleIteration iteration) {
@@ -81,6 +80,10 @@ class Jira implements JiraConnector {
JiraIssues issues = operations.exchange(SEARCH_TEMPLATE, HttpMethod.GET, null, JiraIssues.class, parameters)
.getBody();
+ if (issues.getIssues().isEmpty()) {
+ throw new IllegalStateException(String.format("Did not find a release ticket for %s!", iteration));
+ }
+
JiraIssue issue = issues.getIssues().get(0);
return new Ticket(issue.getKey(), issue.getFields().getSummary());
@@ -121,8 +124,8 @@ class Jira implements JiraConnector {
parameters.put("fields", "summary,fixVersions");
parameters.put("startAt", startAt);
- issues = operations.exchange(SEARCH_TEMPLATE, HttpMethod.GET, new HttpEntity<>(headers), JiraIssues.class,
- parameters).getBody();
+ issues = operations
+ .exchange(SEARCH_TEMPLATE, HttpMethod.GET, new HttpEntity<>(headers), JiraIssues.class, parameters).getBody();
logger.log(iteration, "Got tickets %s to %s of %s.", startAt, issues.getNextStartAt(), issues.getTotal());
@@ -210,11 +213,10 @@ class Jira implements JiraConnector {
public static void main(String[] args) {
- try (ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
- "META-INF/spring/spring-shell-plugin.xml")) {
+ try (ConfigurableApplicationContext context = SpringApplication.run(Application.class, args)) {
JiraConnector tracker = context.getBean(JiraConnector.class);
- TrainIteration iteration = new TrainIteration(ReleaseTrains.CODD, Iteration.SR2);
+ TrainIteration iteration = new TrainIteration(ReleaseTrains.GOSLING, Iteration.SR1);
ModuleIteration module = iteration.getModule("JPA");
// Changelog changelog = tracker.getChangelogFor(module);
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 cd99321..e033592 100644
--- a/src/main/java/org/springframework/data/release/maven/Artifact.java
+++ b/src/main/java/org/springframework/data/release/maven/Artifact.java
@@ -48,7 +48,7 @@ public class Artifact {
this.module = module;
this.repository = new Repository(module.getIteration());
- this.version = ArtifactVersion.from(module);
+ this.version = ArtifactVersion.of(module);
}
/**
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 eacff6b..7de4df7 100644
--- a/src/main/java/org/springframework/data/release/maven/MavenOperations.java
+++ b/src/main/java/org/springframework/data/release/maven/MavenOperations.java
@@ -34,6 +34,7 @@ import org.springframework.data.release.model.Phase;
import org.springframework.data.release.model.Project;
import org.springframework.data.release.model.Train;
import org.springframework.data.release.model.TrainIteration;
+import org.springframework.data.release.utils.ExecutionUtils;
import org.springframework.data.release.utils.Logger;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
@@ -47,7 +48,6 @@ import org.xmlbeam.io.XBFileIO;
@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
public class MavenOperations {
- private static final String COMMONS_VERSION_PROPERTY = "springdata.commons";
private static final String POM_XML = "pom.xml";
private final Workspace workspace;
@@ -90,9 +90,8 @@ public class MavenOperations {
execute(workspace.getFile("parent/pom.xml", BUILD), new PomCallback() {
@Override
- public ParentPom doWith(ParentPom pom) {
+ public void doWith(ParentPom pom) {
pom.setSharedResourcesVersion(phase.equals(PREPARE) ? buildVersion : nextBuildVersion);
- return pom;
}
});
@@ -108,7 +107,7 @@ public class MavenOperations {
execute(workspace.getFile(POM_XML, project), new PomCallback() {
@Override
- public Pom doWith(Pom pom) {
+ public void doWith(Pom pom) {
for (Project dependency : project.getDependencies()) {
@@ -132,8 +131,6 @@ public class MavenOperations {
pom.setParentVersion(version);
updateRepository(project, pom, repository, phase);
-
- return pom;
}
});
}
@@ -149,22 +146,22 @@ public class MavenOperations {
*/
public void triggerDistributionBuild(TrainIteration iteration) throws Exception {
- for (ModuleIteration moduleIteration : iteration) {
+ ExecutionUtils.run(iteration, module -> {
- Project project = moduleIteration.getProject();
+ Project project = module.getProject();
if (BUILD.equals(project)) {
- continue;
+ return;
}
if (!isMavenProject(project)) {
logger.log(project, "Skipping project as no pom.xml could be found in the working directory!");
- continue;
+ return;
}
logger.log(project, "Triggering distribution build…");
- ArtifactVersion version = ArtifactVersion.from(moduleIteration);
+ ArtifactVersion version = ArtifactVersion.of(module);
String command = "mvn clean deploy -DskipTests -Pdistribute";
@@ -174,14 +171,14 @@ public class MavenOperations {
command = command.concat(",release");
}
- CommandResult result = os.executeWithOutput(command, moduleIteration.getProject()).get();
+ CommandResult result = os.executeWithOutput(command, module.getProject()).get();
if (result.hasError()) {
throw result.getException();
}
logger.log(project, "Successfully finished distribution build!");
- }
+ });
}
private boolean isMavenProject(Project project) {
@@ -197,7 +194,7 @@ public class MavenOperations {
execute(bomPomFile, new PomCallback() {
@Override
- public Pom doWith(Pom pom) {
+ public void doWith(Pom pom) {
for (ModuleIteration module : iteration.getModulesExcept(BUILD)) {
@@ -213,8 +210,6 @@ public class MavenOperations {
pom.setDependencyManagementVersion(additionalArtifact, version);
}
}
-
- return pom;
}
});
}
@@ -246,13 +241,11 @@ public class MavenOperations {
Class> typeArgument = GenericTypeResolver.resolveTypeArgument(callback.getClass(), PomCallback.class);
T pom = (T) io.read(typeArgument);
- pom = callback.doWith(pom);
-
+ callback.doWith(pom);
io.write(pom);
}
private interface PomCallback {
-
- public T doWith(T pom);
+ public void doWith(T pom);
}
}
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 6d1d7eb..c010c31 100644
--- a/src/main/java/org/springframework/data/release/maven/MavenProject.java
+++ b/src/main/java/org/springframework/data/release/maven/MavenProject.java
@@ -37,6 +37,6 @@ class MavenProject {
}
public ArtifactVersion getReleaseVersion() {
- return new ArtifactVersion(module.getVersion());
+ return ArtifactVersion.of(module.getVersion());
}
}
diff --git a/src/main/java/org/springframework/data/release/maven/Repository.java b/src/main/java/org/springframework/data/release/maven/Repository.java
index 1359a7a..d8a8e93 100644
--- a/src/main/java/org/springframework/data/release/maven/Repository.java
+++ b/src/main/java/org/springframework/data/release/maven/Repository.java
@@ -28,8 +28,8 @@ public class Repository {
private final String url;
public Repository(Iteration iteration) {
- this.id = iteration.isPublicVersion() ? "spring-libs-release" : "spring-libs-milestone";
- this.url = iteration.isPublicVersion() ? BASE.concat("release") : BASE.concat("milestone");
+ this.id = iteration.isPublic() ? "spring-libs-release" : "spring-libs-milestone";
+ this.url = iteration.isPublic() ? BASE.concat("release") : BASE.concat("milestone");
}
public String getId() {
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 2c0ff68..57a507c 100644
--- a/src/main/java/org/springframework/data/release/model/ArtifactVersion.java
+++ b/src/main/java/org/springframework/data/release/model/ArtifactVersion.java
@@ -16,7 +16,6 @@
package org.springframework.data.release.model;
import lombok.EqualsAndHashCode;
-import lombok.RequiredArgsConstructor;
import org.springframework.util.Assert;
@@ -25,7 +24,6 @@ import org.springframework.util.Assert;
*
* @author Oliver Gierke
*/
-@RequiredArgsConstructor
@EqualsAndHashCode
public class ArtifactVersion implements Comparable {
@@ -43,13 +41,20 @@ public class ArtifactVersion implements Comparable {
* Creates a new {@link ArtifactVersion} from the given logical {@link Version}.
*
* @param version must not be {@literal null}.
+ * @param suffix must not be {@literal null} or empty.
*/
- public ArtifactVersion(Version version) {
+ private ArtifactVersion(Version version, String suffix) {
Assert.notNull(version, "Version must not be null!");
+ Assert.hasText(suffix, "Suffix must not be null or empty!");
+ ;
this.version = version;
- this.suffix = RELEASE_SUFFIX;
+ this.suffix = suffix;
+ }
+
+ public static ArtifactVersion of(Version version) {
+ return new ArtifactVersion(version, RELEASE_SUFFIX);
}
/**
@@ -58,7 +63,7 @@ public class ArtifactVersion implements Comparable {
* @param source must not be {@literal null} or empty.
* @return
*/
- public static ArtifactVersion parse(String source) {
+ public static ArtifactVersion of(String source) {
Assert.hasText(source, "Version source must not be null or empty!");
@@ -67,7 +72,7 @@ public class ArtifactVersion implements Comparable {
Version version = Version.parse(source.substring(0, suffixStart));
String suffix = source.substring(suffixStart + 1);
- Assert.isTrue(suffix.matches(VALID_SUFFIX), "Invalid version suffix!");
+ Assert.isTrue(suffix.matches(VALID_SUFFIX), String.format("Invalid version suffix: %s!", source));
return new ArtifactVersion(version, suffix);
}
@@ -78,14 +83,14 @@ public class ArtifactVersion implements Comparable {
* @param iterationVersion must not be {@literal null}.
* @return
*/
- public static ArtifactVersion from(IterationVersion iterationVersion) {
+ public static ArtifactVersion of(IterationVersion iterationVersion) {
Assert.notNull(iterationVersion, "IterationVersion must not be null!");
Version version = iterationVersion.getVersion();
Iteration iteration = iterationVersion.getIteration();
- if (iteration.isGAVersion()) {
+ if (iteration.isGAIteration()) {
return new ArtifactVersion(version, RELEASE_SUFFIX);
}
@@ -133,17 +138,38 @@ public class ArtifactVersion implements Comparable {
return suffix.matches(MILESTONE_SUFFIX);
}
+ /**
+ * Returns the next development version to be used for the current release version, which means next minor for GA
+ * versions and next bug fix for service releases. Will return the current version as snapshot otherwise.
+ *
+ * @return
+ */
public ArtifactVersion getNextDevelopmentVersion() {
- if (suffix.equals(SNAPSHOT_SUFFIX)) {
- return this;
+ if (suffix.equals(RELEASE_SUFFIX)) {
+
+ boolean isGaVersion = version.withBugfix(0).equals(version);
+ Version nextVersion = isGaVersion ? version.nextMinor() : version.nextBugfix();
+
+ return new ArtifactVersion(nextVersion, SNAPSHOT_SUFFIX);
}
+ return suffix.equals(SNAPSHOT_SUFFIX) ? this : new ArtifactVersion(version, SNAPSHOT_SUFFIX);
+ }
+
+ /**
+ * Returns the next bug fix version for the current version if it's a release version or the snapshot version of the
+ * current one otherwise.
+ *
+ * @return
+ */
+ public ArtifactVersion getNextBugfixVersion() {
+
if (suffix.equals(RELEASE_SUFFIX)) {
return new ArtifactVersion(version.nextBugfix(), SNAPSHOT_SUFFIX);
}
- return new ArtifactVersion(version, SNAPSHOT_SUFFIX);
+ return suffix.equals(SNAPSHOT_SUFFIX) ? this : new ArtifactVersion(version, SNAPSHOT_SUFFIX);
}
/*
@@ -152,7 +178,9 @@ public class ArtifactVersion implements Comparable {
*/
@Override
public int compareTo(ArtifactVersion that) {
- return this.toString().compareTo(that.toString());
+
+ int versionsEqual = this.version.compareTo(that.version);
+ return versionsEqual != 0 ? versionsEqual : this.suffix.compareTo(that.suffix);
}
/*
@@ -165,7 +193,7 @@ public class ArtifactVersion implements Comparable {
}
/**
- * Returns the {@link String} of the plain version (read: x.y.z, ommitting trailing bugfix zeros).
+ * Returns the {@link String} of the plain version (read: x.y.z, omitting trailing bug fix zeros).
*
* @return
*/
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 236fdfa..e7fe64a 100644
--- a/src/main/java/org/springframework/data/release/model/Iteration.java
+++ b/src/main/java/org/springframework/data/release/model/Iteration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2014-2015 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.
@@ -52,11 +52,17 @@ public class Iteration {
this.next = next;
}
- public boolean isGAVersion() {
+ public boolean isGAIteration() {
return this.equals(GA);
}
- public boolean isPublicVersion() {
+ /**
+ * Returns whether the {@link Iteration} is considered public, i.e. the artifacts produced by the iteration are
+ * supposed to be published to Maven Central.
+ *
+ * @return
+ */
+ public boolean isPublic() {
return isServiceIteration() || this.equals(GA);
}
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 35d320b..73bc537 100644
--- a/src/main/java/org/springframework/data/release/model/Module.java
+++ b/src/main/java/org/springframework/data/release/model/Module.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2014-2015 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.
@@ -57,6 +57,16 @@ public class Module {
return new Module(project, nextVersion.toString());
}
+ /**
+ * Returns whether the current {@link Module} refers to the same project as the given one.
+ *
+ * @param module must not be {@literal null}.
+ * @return
+ */
+ public boolean hasSameProjectAs(Module module) {
+ return this.project.equals(module.project);
+ }
+
@Override
public String toString() {
return String.format("Spring Data %s %s - %s", project.getName(), version, project.getKey());
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 91d605a..815be00 100644
--- a/src/main/java/org/springframework/data/release/model/ModuleIteration.java
+++ b/src/main/java/org/springframework/data/release/model/ModuleIteration.java
@@ -64,7 +64,7 @@ public class ModuleIteration implements IterationVersion {
public String getVersionString() {
StringBuilder builder = new StringBuilder();
- builder.append(ArtifactVersion.from(this).toShortString());
+ builder.append(ArtifactVersion.of(this).toShortString());
if (!iteration.isServiceIteration()) {
builder.append(" ").append(iteration.getName());
diff --git a/src/main/java/org/springframework/data/release/model/Projects.java b/src/main/java/org/springframework/data/release/model/Projects.java
index 264fe3d..351cfcd 100644
--- a/src/main/java/org/springframework/data/release/model/Projects.java
+++ b/src/main/java/org/springframework/data/release/model/Projects.java
@@ -25,7 +25,7 @@ import java.util.List;
public class Projects {
public static final Project COMMONS, BUILD, REST, JPA, MONGO_DB, NEO4J, SOLR, COUCHBASE, CASSANDRA, ELASTICSEARCH,
- REDIS, GEMFIRE;
+ REDIS, GEMFIRE, KEY_VALUE, ENVERS;
public static final List PROJECTS;
static {
@@ -44,9 +44,12 @@ public class Projects {
GEMFIRE = new Project("SGF", "Gemfire", Arrays.asList(COMMONS));
REST = new Project("DATAREST", "REST", Arrays.asList(COMMONS, JPA, MONGO_DB, NEO4J, GEMFIRE, SOLR, CASSANDRA),
- Arrays.asList("spring-data-rest-core", "spring-data-rest-core"));
+ Arrays.asList("spring-data-rest-core", "spring-data-rest-core", "spring-data-rest-hal-browser"));
+
+ KEY_VALUE = new Project("DATAKV", "KeyValue", Arrays.asList(COMMONS));
+ ENVERS = new Project("DATAENV", "Envers", Arrays.asList(JPA, COMMONS));
PROJECTS = Arrays.asList(BUILD, COMMONS, JPA, MONGO_DB, NEO4J, SOLR, COUCHBASE, CASSANDRA, ELASTICSEARCH, REDIS,
- GEMFIRE, REST);
+ GEMFIRE, REST, KEY_VALUE, ENVERS);
}
}
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 49611ef..21489f7 100644
--- a/src/main/java/org/springframework/data/release/model/ReleaseTrains.java
+++ b/src/main/java/org/springframework/data/release/model/ReleaseTrains.java
@@ -27,7 +27,7 @@ import java.util.List;
public class ReleaseTrains {
public static final List TRAINS;
- public static final Train CODD, DIJKSTRA, EVANS, FOWLER;
+ public static final Train CODD, DIJKSTRA, EVANS, FOWLER, GOSLING, HOPPER;
static {
@@ -35,10 +35,13 @@ public class ReleaseTrains {
DIJKSTRA = dijkstra();
EVANS = DIJKSTRA.next("Evans", Transition.MINOR);
FOWLER = EVANS.next("Fowler", Transition.MINOR);
+ GOSLING = FOWLER.next("Gosling", Transition.MINOR, new Module(KEY_VALUE, "1.0"));
+ HOPPER = GOSLING.next("Hopper", Transition.MINOR, new Module(NEO4J, "4.1"), new Module(COUCHBASE, "2.1"),
+ new Module(ENVERS, "1.0"));
// Trains
- TRAINS = Arrays.asList(CODD, DIJKSTRA, EVANS, FOWLER);
+ TRAINS = Arrays.asList(CODD, DIJKSTRA, EVANS, FOWLER, GOSLING, HOPPER);
// Train names
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 ab42e45..788a724 100644
--- a/src/main/java/org/springframework/data/release/model/Train.java
+++ b/src/main/java/org/springframework/data/release/model/Train.java
@@ -21,15 +21,17 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.Value;
-import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.springframework.shell.support.util.OsUtils;
import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
/**
* @author Oliver Gierke
@@ -38,7 +40,7 @@ import org.springframework.util.StringUtils;
public class Train implements Iterable {
private final String name;;
- private final List modules;
+ private final Collection modules;
private final Iterations iterations;
public Train(String name, Module... modules) {
@@ -48,10 +50,10 @@ public class Train implements Iterable {
this.iterations = Iterations.DEFAULT;
}
- public Train(String name, List modules) {
+ public Train(String name, Collection modules) {
this.name = name;
- this.modules = Collections.unmodifiableList(modules);
+ this.modules = Collections.unmodifiableCollection(modules);
this.iterations = Iterations.DEFAULT;
}
@@ -66,46 +68,39 @@ public class Train implements Iterable {
public Module getModule(String name) {
- for (Module module : this) {
- if (module.getProject().getName().equals(name)) {
- return module;
- }
- }
-
- return null;
+ return modules.stream().//
+ filter(module -> module.getProject().getName().equals(name)).//
+ findFirst().//
+ orElseThrow(() -> new IllegalArgumentException(String.format("No Module found with name %s!", name)));
}
public Module getModule(Project project) {
- for (Module module : this) {
- if (module.getProject().equals(project)) {
- return module;
- }
- }
-
- return null;
+ return modules.stream().//
+ filter(module -> module.getProject().equals(project)).//
+ findFirst().orElseThrow(
+ () -> new IllegalArgumentException(String.format("No module found for project %s!", project.getName())));
}
- public Train next(String name, Transition transition) {
+ public Train next(String name, Transition transition, Module... additionalModules) {
- List nextModules = new ArrayList<>();
+ Set collect = Stream.concat(modules.stream(), Stream.of(additionalModules)).//
+ map(module -> Arrays.stream(additionalModules).//
+ reduce(module.next(transition),
+ (it, additionalModule) -> it.hasSameProjectAs(additionalModule) ? additionalModule : it))
+ .collect(Collectors.toSet());
- for (Module module : modules) {
- nextModules.add(module.next(transition));
- }
-
- return new Train(name, nextModules);
+ return new Train(name, collect);
}
public ModuleIteration getModuleIteration(Iteration iteration, String moduleName) {
- for (Module module : this) {
- if (module.hasName(moduleName)) {
- return new ModuleIteration(module, iteration, this);
- }
- }
-
- return null;
+ return modules.stream().//
+ filter(module -> module.hasName(moduleName)).//
+ findFirst().//
+ map(module -> new ModuleIteration(module, iteration, this)).//
+ orElseThrow(
+ () -> new IllegalArgumentException(String.format("No module found with module name %s!", moduleName)));
}
public Iterable getModuleIterations(Iteration iteration) {
@@ -114,19 +109,12 @@ public class Train implements Iterable {
List getModuleIterations(Iteration iteration, Project... exclusions) {
- List iterations = new ArrayList<>(modules.size());
List exclusionList = Arrays.asList(exclusions);
- for (Module module : this) {
-
- if (exclusionList.contains(module.getProject())) {
- continue;
- }
-
- iterations.add(new ModuleIteration(module, iteration, this));
- }
-
- return iterations;
+ return modules.stream().//
+ filter(module -> !exclusionList.contains(module.getProject())).//
+ map(module -> new ModuleIteration(module, iteration, this)).//
+ collect(Collectors.toList());
}
public Iteration getIteration(String name) {
@@ -136,7 +124,8 @@ public class Train implements Iterable {
public ArtifactVersion getModuleVersion(Project project, Iteration iteration) {
Module module = getModule(project);
- return ArtifactVersion.from(new ModuleIteration(module, iteration, this));
+
+ return ArtifactVersion.of(new ModuleIteration(module, iteration, this));
}
/*
@@ -148,8 +137,14 @@ public class Train implements Iterable {
StringBuilder builder = new StringBuilder();
- builder.append(name).append(OsUtils.LINE_SEPARATOR).append(OsUtils.LINE_SEPARATOR);
- builder.append(StringUtils.collectionToDelimitedString(modules, OsUtils.LINE_SEPARATOR));
+ builder.append(name).//
+ append(OsUtils.LINE_SEPARATOR).//
+ append(OsUtils.LINE_SEPARATOR);
+
+ builder.append(modules.stream().//
+ map(Module::toString).//
+ sorted().//
+ collect(Collectors.joining(OsUtils.LINE_SEPARATOR)));
return builder.toString();
}
@@ -186,24 +181,18 @@ public class Train implements Iterable {
Assert.hasText(name, "Name must not be null or empty!");
- for (Iteration iteration : this) {
- if (iteration.getName().equalsIgnoreCase(name)) {
- return iteration;
- }
- }
-
- return null;
+ return iterations.stream().//
+ filter(iteration -> iteration.getName().equalsIgnoreCase(name)).//
+ findFirst()
+ .orElseThrow(() -> new IllegalArgumentException(String.format("No iteration found with name %s!", name)));
}
Iteration getPreviousIteration(Iteration iteration) {
- for (Iteration candidate : iterations) {
- if (candidate.isNext(iteration)) {
- return candidate;
- }
- }
-
- throw new IllegalArgumentException(String.format("Could not find previous iteration for %s!", iteration));
+ return iterations.stream().//
+ filter(candidate -> candidate.isNext(iteration)).//
+ findFirst().orElseThrow(() -> new IllegalArgumentException(
+ String.format("Could not find previous iteration for %s!", iteration)));
}
/*
diff --git a/src/main/java/org/springframework/data/release/model/Version.java b/src/main/java/org/springframework/data/release/model/Version.java
index f62d073..f1ff92b 100644
--- a/src/main/java/org/springframework/data/release/model/Version.java
+++ b/src/main/java/org/springframework/data/release/model/Version.java
@@ -23,7 +23,7 @@ public class Version implements Comparable {
*
* @param parts must not be {@literal null} or empty.
*/
- public Version(int... parts) {
+ private Version(int... parts) {
Assert.notNull(parts);
Assert.isTrue(parts.length > 0 && parts.length < 5);
@@ -39,6 +39,10 @@ public class Version implements Comparable {
Assert.isTrue(build >= 0, "Build version must be greater or equal zero!");
}
+ public static Version of(int... parts) {
+ return new Version(parts);
+ }
+
/**
* Parses the given string representation of a version into a {@link Version} object.
*
diff --git a/src/main/java/org/springframework/data/release/utils/CommandUtils.java b/src/main/java/org/springframework/data/release/utils/CommandUtils.java
deleted file mode 100644
index 2aae3b0..0000000
--- a/src/main/java/org/springframework/data/release/utils/CommandUtils.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2015 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 java.util.concurrent.Future;
-
-import org.springframework.data.release.io.CommandResult;
-
-/**
- * @author Oliver Gierke
- */
-public class CommandUtils {
-
- public static CommandResult getCommandResult(Future future) throws Exception {
-
- CommandResult result = future.get();
-
- if (result.hasError()) {
- throw new CommandException(result);
- }
-
- return result;
- }
-
- public static class CommandException extends RuntimeException {
-
- private final CommandResult result;
-
- public CommandException(CommandResult result) {
-
- super(result.getException());
- this.result = result;
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Throwable#getMessage()
- */
- @Override
- public String getMessage() {
- return String.format("Command execution failed: %s.", result);
- }
- }
-}
diff --git a/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java b/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java
new file mode 100644
index 0000000..840e182
--- /dev/null
+++ b/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2015 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 java.util.Collection;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import org.springframework.util.Assert;
+
+/**
+ * Utility method to easily execute functionality in parallel.
+ *
+ * @author Oliver Gierke
+ */
+public class ExecutionUtils {
+
+ /**
+ * Runs the given {@link ConsumerWithException} for each element in the given {@link Iterable} in parallel waiting for
+ * all executions to complete before returning. Exceptions being thrown in the {@link ConsumerWithException} will be
+ * converted into {@link RuntimeException}s.
+ *
+ * @param iterable must not be {@literal null}.
+ * @param consumer must not be {@literal null}.
+ */
+ public static void run(Iterable iterable, ConsumerWithException consumer) {
+
+ Assert.notNull(iterable, "Iterable must not be null!");
+ Assert.notNull(consumer, "Consumer must not be null!");
+
+ StreamSupport.stream(iterable.spliterator(), false).//
+ map(it -> CompletableFuture.runAsync(() -> {
+ try {
+ consumer.accept(it);
+ } catch (Exception o_O) {
+ throw new RuntimeException(o_O);
+ }
+ })).collect(Collectors.toList()).forEach(future -> future.join());
+
+ }
+
+ /**
+ * Runs the given {@link Function} for each element in the given {@link Iterable} in parallel waiting for all
+ * executions to complete before returning the results.
+ *
+ * @param iterable must not be {@literal null}.
+ * @param function must not be {@literal null}.
+ * @return
+ */
+ public static Collection runAndReturn(Iterable iterable, Function function) {
+
+ Assert.notNull(iterable, "Iterable must not be null!");
+ Assert.notNull(function, "Consumer must not be null!");
+
+ return StreamSupport.stream(iterable.spliterator(), false).//
+ map(it -> CompletableFuture.supplyAsync(() -> function.apply(it))).//
+ collect(Collectors.toList()).//
+ stream().//
+ map(future -> future.join()).//
+ collect(Collectors.toList());
+ }
+
+ public static interface ConsumerWithException {
+
+ void accept(T t) throws Exception;
+ }
+}
diff --git a/src/main/java/org/springframework/data/release/utils/Logger.java b/src/main/java/org/springframework/data/release/utils/Logger.java
index 94c854c..cd357b3 100644
--- a/src/main/java/org/springframework/data/release/utils/Logger.java
+++ b/src/main/java/org/springframework/data/release/utils/Logger.java
@@ -17,6 +17,7 @@ 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.Train;
import org.springframework.data.release.model.TrainIteration;
import org.springframework.shell.support.logging.HandlerUtils;
import org.springframework.stereotype.Component;
@@ -43,6 +44,10 @@ public class Logger {
log(iteration.toString(), template, args);
}
+ public void log(Train train, String template, Object... args) {
+ log(train.getName(), 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/main/resources/META-INF/spring/spring-shell-plugin.xml b/src/main/resources/META-INF/spring/spring-shell-plugin.xml
deleted file mode 100644
index c61e0b2..0000000
--- a/src/main/resources/META-INF/spring/spring-shell-plugin.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..f759759
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1 @@
+io.work-dir=~/temp/spring-data-shell
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
deleted file mode 100644
index f1b93eb..0000000
--- a/src/main/resources/logback.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
- %d %5p %40.40c:%4L - %m%n
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/test/java/org/springframework/data/release/AbstractIntegrationTests.java b/src/test/java/org/springframework/data/release/AbstractIntegrationTests.java
index 0268b99..9faa6c4 100644
--- a/src/test/java/org/springframework/data/release/AbstractIntegrationTests.java
+++ b/src/test/java/org/springframework/data/release/AbstractIntegrationTests.java
@@ -16,14 +16,14 @@
package org.springframework.data.release;
import org.junit.runner.RunWith;
-import org.springframework.test.context.ContextConfiguration;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Oliver Gierke
*/
+@ActiveProfiles({ "test", "local" })
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = TestConfig.class)
-public abstract class AbstractIntegrationTests {
-
-}
+@SpringApplicationConfiguration(classes = Application.class)
+public abstract class AbstractIntegrationTests {}
diff --git a/src/test/java/org/springframework/data/release/ArtifactUnitTests.java b/src/test/java/org/springframework/data/release/ArtifactUnitTests.java
index 32af713..13dda41 100644
--- a/src/test/java/org/springframework/data/release/ArtifactUnitTests.java
+++ b/src/test/java/org/springframework/data/release/ArtifactUnitTests.java
@@ -35,7 +35,7 @@ public class ArtifactUnitTests {
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")));
+ assertThat(artifact.getVersion(), is(ArtifactVersion.of("1.6.0.M1")));
+ assertThat(artifact.getNextDevelopmentVersion(), is(ArtifactVersion.of("1.6.0.BUILD-SNAPSHOT")));
}
}
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 dc41076..875ca9b 100644
--- a/src/test/java/org/springframework/data/release/cli/ReleaseCommandsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/release/cli/ReleaseCommandsIntegrationTests.java
@@ -35,8 +35,8 @@ public class ReleaseCommandsIntegrationTests extends AbstractIntegrationTests {
@Test
public void predictsReleaseTrainCorrectly() throws Exception {
- git.update(ReleaseTrains.DIJKSTRA);
+ git.update(ReleaseTrains.GOSLING);
- assertThat(releaseCommands.predictTrainAndIteration(), is("Dijkstra"));
+ assertThat(releaseCommands.predictTrainAndIteration(), is("Gosling"));
}
}
diff --git a/src/test/java/org/springframework/data/release/git/BranchUnitTests.java b/src/test/java/org/springframework/data/release/git/BranchUnitTests.java
index 9b6e9dd..fe92646 100644
--- a/src/test/java/org/springframework/data/release/git/BranchUnitTests.java
+++ b/src/test/java/org/springframework/data/release/git/BranchUnitTests.java
@@ -32,14 +32,14 @@ public class BranchUnitTests {
@Test
public void testname() {
- IterationVersion iterationVersion = new SimpleIterationVersion(new Version(1, 4), Iteration.RC1);
+ IterationVersion iterationVersion = new SimpleIterationVersion(Version.of(1, 4), Iteration.RC1);
assertThat(Branch.from(iterationVersion).toString(), is("master"));
}
@Test
public void createsBugfixBranchForServiceRelease() {
- IterationVersion iterationVersion = new SimpleIterationVersion(new Version(1, 4), Iteration.SR1);
+ IterationVersion iterationVersion = new SimpleIterationVersion(Version.of(1, 4), Iteration.SR1);
assertThat(Branch.from(iterationVersion).toString(), is("1.4.x"));
}
}
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 e87726b..320c127 100644
--- a/src/test/java/org/springframework/data/release/git/GitOperationsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/release/git/GitOperationsIntegrationTests.java
@@ -15,14 +15,15 @@
*/
package org.springframework.data.release.git;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
import static org.springframework.data.release.model.Projects.*;
-import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.release.AbstractIntegrationTests;
import org.springframework.data.release.model.ReleaseTrains;
-import org.springframework.util.StringUtils;
+import org.springframework.data.release.model.TestReleaseTrains;
/**
* @author Oliver Gierke
@@ -32,22 +33,25 @@ public class GitOperationsIntegrationTests extends AbstractIntegrationTests {
@Autowired GitOperations gitOperations;
@Test
- @Ignore
- public void testname() throws Exception {
- gitOperations.update(ReleaseTrains.CODD);
+ public void updatesGitRepositories() throws Exception {
+ gitOperations.update(ReleaseTrains.GOSLING);
}
@Test
- @Ignore
public void showTags() throws Exception {
- Tags tags = gitOperations.getTags(COMMONS);
- System.out.println(StringUtils.collectionToDelimitedString(tags.asList(), "\n"));
+ gitOperations.update(TestReleaseTrains.SAMPLE);
+
+ assertThat(gitOperations.getTags(BUILD).asList(), is(not(emptyIterable())));
}
@Test
public void foo() throws Exception {
+ gitOperations.update(TestReleaseTrains.SAMPLE);
+ }
- gitOperations.update(ReleaseTrains.EVANS);
+ @Test
+ public void obtainsVersionTagsForRepoThatAlsoHasOtherTags() {
+ gitOperations.getTags(MONGO_DB);
}
}
diff --git a/src/test/java/org/springframework/data/release/git/GitProjectUnitTests.java b/src/test/java/org/springframework/data/release/git/GitProjectUnitTests.java
index d9abd50..d7b7786 100644
--- a/src/test/java/org/springframework/data/release/git/GitProjectUnitTests.java
+++ b/src/test/java/org/springframework/data/release/git/GitProjectUnitTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2014-2015 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.
@@ -19,20 +19,31 @@ import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
+import org.springframework.data.release.model.Module;
+import org.springframework.data.release.model.Project;
import org.springframework.data.release.model.ReleaseTrains;
import org.springframework.data.release.model.Train;
/**
+ * Unit tests for {@link GitProject}.
+ *
* @author Oliver Gierke
*/
public class GitProjectUnitTests {
@Test
- public void testname() {
+ public void buildsGitHubRepositoryUriCorrectly() {
Train codd = ReleaseTrains.CODD;
- GitProject project = new GitProject(codd.getModule("Commons").getProject(), new GitServer());
+ GitServer server = new GitServer();
+ Module module = codd.getModule("Commons");
+ Project project = module.getProject();
- assertThat(project.getProjectUri(), is("https://www.github.com/spring-projects/spring-data-commons"));
+ GitProject gitProject = new GitProject(project, server);
+
+ String projectUri = gitProject.getProjectUri();
+
+ assertThat(projectUri, startsWith(server.getUri()));
+ assertThat(projectUri, endsWith("spring-data-commons"));
}
}
diff --git a/src/test/java/org/springframework/data/release/git/GitPropertiesIntegrationTests.java b/src/test/java/org/springframework/data/release/git/GitPropertiesIntegrationTests.java
new file mode 100644
index 0000000..b7d8503
--- /dev/null
+++ b/src/test/java/org/springframework/data/release/git/GitPropertiesIntegrationTests.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015 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.git;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.release.AbstractIntegrationTests;
+
+/**
+ * @author Oliver Gierke
+ */
+public class GitPropertiesIntegrationTests extends AbstractIntegrationTests {
+
+ @Autowired GitProperties gitProperties;
+
+ @Test
+ public void hasBasicPropertiesConfigured() {
+ assertThat(gitProperties.getAuthor(), is(notNullValue()));
+ assertThat(gitProperties.getEmail(), is(notNullValue()));
+ }
+}
diff --git a/src/test/java/org/springframework/data/release/io/CommonsExecOsCommandOperationsIntegegrationTests.java b/src/test/java/org/springframework/data/release/io/IoPropertiesIntegrationTests.java
similarity index 51%
rename from src/test/java/org/springframework/data/release/io/CommonsExecOsCommandOperationsIntegegrationTests.java
rename to src/test/java/org/springframework/data/release/io/IoPropertiesIntegrationTests.java
index 94e2b40..7b4b2ee 100644
--- a/src/test/java/org/springframework/data/release/io/CommonsExecOsCommandOperationsIntegegrationTests.java
+++ b/src/test/java/org/springframework/data/release/io/IoPropertiesIntegrationTests.java
@@ -21,38 +21,16 @@ import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.release.AbstractIntegrationTests;
-import org.springframework.data.release.model.Projects;
/**
* @author Oliver Gierke
*/
-public class CommonsExecOsCommandOperationsIntegegrationTests extends AbstractIntegrationTests {
+public class IoPropertiesIntegrationTests extends AbstractIntegrationTests {
- @Autowired OsCommandOperations operations;
+ @Autowired IoProperties ioProperties;
@Test
- public void testname() throws Exception {
-
- // CommandResult result = operations
- // .executeCommand("export GIT_TRACE=1 && git clone https://github.com/spring-projects/spring-data-build").get();
-
- // CommandResult result = operations.executeCommand("git pull", Projects.BUILD).get();
-
- CommandResult result = operations.executeCommand("git remote -v", Projects.BUILD).get();
- // .get();
-
- if (result.hasError()) {
-
- System.out.println(result.getStatus());
- System.out.println(result.getOutput());
- System.out.println(result.getException().getMessage());
-
- throw result.getException();
- } else {
- System.out.println(result.getOutput());
- }
-
- assertThat(result.hasError(), is(false));
-
+ public void configuresWorkingDirectoryFromApplicationProperties() {
+ assertThat(ioProperties.getWorkDir(), is(notNullValue()));
}
}
diff --git a/src/test/java/org/springframework/data/release/maven/MavenIntegrationTests.java b/src/test/java/org/springframework/data/release/maven/MavenIntegrationTests.java
index 98df45e..d85930d 100644
--- a/src/test/java/org/springframework/data/release/maven/MavenIntegrationTests.java
+++ b/src/test/java/org/springframework/data/release/maven/MavenIntegrationTests.java
@@ -17,9 +17,7 @@ package org.springframework.data.release.maven;
import java.io.IOException;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.release.AbstractIntegrationTests;
@@ -36,15 +34,13 @@ public class MavenIntegrationTests extends AbstractIntegrationTests {
@Autowired Workspace workspace;
@Autowired ProjectionFactory projection;
- public @Rule TemporaryFolder folder = new TemporaryFolder();
-
@Test
public void modifiesParentPomCorrectly() throws IOException {
XBFileIO io = projection.io().file(new ClassPathResource("parent-pom.xml").getFile());
ParentPom pom = io.read(ParentPom.class);
- pom.setSharedResourcesVersion(ArtifactVersion.parse("1.2.0.RELEASE"));
+ pom.setSharedResourcesVersion(ArtifactVersion.of("1.2.0.RELEASE"));
// System.out.println(projection.asString(pom));
}
diff --git a/src/test/java/org/springframework/data/release/model/ArtifactVersionUnitTests.java b/src/test/java/org/springframework/data/release/model/ArtifactVersionUnitTests.java
index f910cea..b606a2a 100644
--- a/src/test/java/org/springframework/data/release/model/ArtifactVersionUnitTests.java
+++ b/src/test/java/org/springframework/data/release/model/ArtifactVersionUnitTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2014-2015 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.
@@ -15,14 +15,10 @@
*/
package org.springframework.data.release.model;
-import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
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.Version;
/**
* @author Oliver Gierke
@@ -31,22 +27,22 @@ public class ArtifactVersionUnitTests {
@Test(expected = IllegalArgumentException.class)
public void rejectsInvalidVersionSuffix() {
- ArtifactVersion.parse("1.4.5.GA");
+ ArtifactVersion.of("1.4.5.GA");
}
@Test
public void parsesReleaseVersionCorrectly() {
- ArtifactVersion version = ArtifactVersion.parse("1.4.5.RELEASE");
+ ArtifactVersion version = ArtifactVersion.of("1.4.5.RELEASE");
assertThat(version.isReleaseVersion(), is(true));
- assertThat(version.getNextDevelopmentVersion(), is(ArtifactVersion.parse("1.4.6.BUILD-SNAPSHOT")));
+ assertThat(version.getNextDevelopmentVersion(), is(ArtifactVersion.of("1.4.6.BUILD-SNAPSHOT")));
}
@Test
public void createsMilestoneVersionCorrectly() {
- ArtifactVersion version = ArtifactVersion.parse("1.4.5.M1");
+ ArtifactVersion version = ArtifactVersion.of("1.4.5.M1");
assertThat(version.isReleaseVersion(), is(false));
assertThat(version.isMilestoneVersion(), is(true));
@@ -55,7 +51,7 @@ public class ArtifactVersionUnitTests {
@Test
public void createsReleaseVersionByDefault() {
- ArtifactVersion version = new ArtifactVersion(new Version(1, 4, 5));
+ ArtifactVersion version = ArtifactVersion.of(Version.of(1, 4, 5));
assertThat(version.isReleaseVersion(), is(true));
assertThat(version.toString(), is("1.4.5.RELEASE"));
@@ -64,8 +60,8 @@ public class ArtifactVersionUnitTests {
@Test
public void createsMilestoneVersionFromIteration() {
- IterationVersion oneFourMilestoneOne = new SimpleIterationVersion(new Version(1, 4), Iteration.M1);
- ArtifactVersion version = ArtifactVersion.from(oneFourMilestoneOne);
+ IterationVersion oneFourMilestoneOne = new SimpleIterationVersion(Version.of(1, 4), Iteration.M1);
+ ArtifactVersion version = ArtifactVersion.of(oneFourMilestoneOne);
assertThat(version.isMilestoneVersion(), is(true));
assertThat(version.toString(), is("1.4.0.M1"));
@@ -74,8 +70,8 @@ public class ArtifactVersionUnitTests {
@Test
public void createsReleaseVersionFromIteration() {
- IterationVersion oneFourGA = new SimpleIterationVersion(new Version(1, 4), Iteration.GA);
- ArtifactVersion version = ArtifactVersion.from(oneFourGA);
+ IterationVersion oneFourGA = new SimpleIterationVersion(Version.of(1, 4), Iteration.GA);
+ ArtifactVersion version = ArtifactVersion.of(oneFourGA);
assertThat(version.isReleaseVersion(), is(true));
assertThat(version.toString(), is("1.4.0.RELEASE"));
@@ -84,10 +80,48 @@ public class ArtifactVersionUnitTests {
@Test
public void createsServiceReleaseVersionFromIteration() {
- IterationVersion oneFourServiceReleaseTwo = new SimpleIterationVersion(new Version(1, 4), Iteration.SR2);
- ArtifactVersion version = ArtifactVersion.from(oneFourServiceReleaseTwo);
+ IterationVersion oneFourServiceReleaseTwo = new SimpleIterationVersion(Version.of(1, 4), Iteration.SR2);
+ ArtifactVersion version = ArtifactVersion.of(oneFourServiceReleaseTwo);
assertThat(version.isReleaseVersion(), is(true));
assertThat(version.toString(), is("1.4.2.RELEASE"));
}
+
+ @Test
+ public void returnsNextMinorSnapshotVersionForGARelease() {
+
+ ArtifactVersion version = ArtifactVersion.of("1.5.0.RELEASE").getNextDevelopmentVersion();
+
+ assertThat(version.isMilestoneVersion(), is(false));
+ assertThat(version.isReleaseVersion(), is(false));
+ assertThat(version, is(ArtifactVersion.of("1.6.0.BUILD-SNAPSHOT")));
+ }
+
+ @Test
+ public void ordersCorrectly() {
+
+ ArtifactVersion oneNine = ArtifactVersion.of("1.9.0.RELEASE");
+ ArtifactVersion oneTen = ArtifactVersion.of("1.10.0.RELEASE");
+
+ assertThat(oneNine.compareTo(oneTen), is(lessThan(0)));
+ }
+
+ @Test
+ public void ordersSnapshotsOfSameVersionSmaller() {
+
+ ArtifactVersion oneTenRelease = ArtifactVersion.of("1.10.0.RELEASE");
+ ArtifactVersion oneTenSnapshot = ArtifactVersion.of("1.10.0.BUILD-SNAPSHOT");
+
+ assertThat(oneTenRelease.compareTo(oneTenSnapshot), is(greaterThan(0)));
+ }
+
+ @Test
+ public void returnsCorrectBugfixVersions() {
+
+ assertThat(ArtifactVersion.of("1.0.0.RELEASE").getNextBugfixVersion(),
+ is(ArtifactVersion.of("1.0.1.BUILD-SNAPSHOT")));
+ assertThat(ArtifactVersion.of("1.0.0.M1").getNextBugfixVersion(), is(ArtifactVersion.of("1.0.0.BUILD-SNAPSHOT")));
+ assertThat(ArtifactVersion.of("1.0.1.RELEASE").getNextBugfixVersion(),
+ is(ArtifactVersion.of("1.0.2.BUILD-SNAPSHOT")));
+ }
}
diff --git a/src/test/java/org/springframework/data/release/TestConfig.java b/src/test/java/org/springframework/data/release/model/TestReleaseTrains.java
similarity index 66%
rename from src/test/java/org/springframework/data/release/TestConfig.java
rename to src/test/java/org/springframework/data/release/model/TestReleaseTrains.java
index 4ad5fa5..93d09a9 100644
--- a/src/test/java/org/springframework/data/release/TestConfig.java
+++ b/src/test/java/org/springframework/data/release/model/TestReleaseTrains.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2015 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.
@@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.data.release;
+package org.springframework.data.release.model;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
+import java.util.Arrays;
/**
+ * Sample release {@link Train} definitions.
+ *
* @author Oliver Gierke
*/
-@Configuration
-@ComponentScan
-public class TestConfig {
+public class TestReleaseTrains {
+ public static Train SAMPLE = new Train("SAMPLE", Arrays.asList(new Module(Projects.BUILD, "1.0")));
}
diff --git a/src/test/java/org/springframework/data/release/model/TrainsUnitTest.java b/src/test/java/org/springframework/data/release/model/TrainsUnitTest.java
new file mode 100644
index 0000000..f52650e
--- /dev/null
+++ b/src/test/java/org/springframework/data/release/model/TrainsUnitTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2015 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;
+
+/**
+ * Unit tests for release {@link Train}s.
+ *
+ * @author Oliver Gierke
+ */
+public class TrainsUnitTest {
+
+ @Test
+ public void prefersNewVersionOfAdditionalModule() {
+
+ Module module = ReleaseTrains.HOPPER.getModule(Projects.NEO4J);
+
+ assertThat(module.getVersion(), is(Version.parse("4.1")));
+ }
+
+ @Test
+ public void addsNewlyAddedModule() {
+ assertThat(ReleaseTrains.HOPPER.getModule(Projects.ENVERS), is(notNullValue()));
+ }
+}
diff --git a/src/test/resources/application-test.properties b/src/test/resources/application-test.properties
new file mode 100644
index 0000000..4982dd4
--- /dev/null
+++ b/src/test/resources/application-test.properties
@@ -0,0 +1,3 @@
+io.work-dir=~/temp/shell-test
+logging.level.org.springframework=WARN
+logging.level.org.springframework.data.release=INFO