diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/Releaser.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/Releaser.java
index 8bd0b564..97a96a2f 100644
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/Releaser.java
+++ b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/Releaser.java
@@ -1,13 +1,15 @@
package org.springframework.cloud.release.internal;
import java.io.File;
-import java.io.IOException;
import java.lang.invoke.MethodHandles;
+import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.release.internal.builder.ProjectBuilder;
+import org.springframework.cloud.release.internal.git.ProjectGitUpdater;
import org.springframework.cloud.release.internal.pom.ProjectUpdater;
+import org.springframework.cloud.release.internal.pom.ProjectVersion;
import org.springframework.util.StringUtils;
/**
@@ -15,33 +17,58 @@ import org.springframework.util.StringUtils;
*/
public class Releaser {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ private static final String MSG = "'q' to quit and 's' to skip\n\n";
+ private static final String SKIP = "s";
+ private static final String QUIT = "q";
private final ReleaserProperties properties;
private final ProjectUpdater projectUpdater;
private final ProjectBuilder projectBuilder;
+ private final ProjectGitUpdater projectGitUpdater;
- public Releaser(ReleaserProperties properties,
- ProjectUpdater projectUpdater, ProjectBuilder projectBuilder) {
+ public Releaser(ReleaserProperties properties, ProjectUpdater projectUpdater,
+ ProjectBuilder projectBuilder, ProjectGitUpdater projectGitUpdater) {
this.properties = properties;
this.projectUpdater = projectUpdater;
this.projectBuilder = projectBuilder;
+ this.projectGitUpdater = projectGitUpdater;
}
public void release() {
- try {
- String workingDir = StringUtils.hasText(this.properties.getWorkingDir()) ?
- this.properties.getWorkingDir() : System.getProperty("user.dir");
- log.info("\n\n\n=== UPDATING POMS ===\n\nWill run the application for root folder [{}]", workingDir);
- this.projectUpdater.updateProject(new File(workingDir));
+ String workingDir = StringUtils.hasText(this.properties.getWorkingDir()) ?
+ this.properties.getWorkingDir() : System.getProperty("user.dir");
+ File project = new File(workingDir);
+ log.info("\n\n\n=== UPDATING POMS ===\n\nWill run the application "
+ + "for root folder [{}]. \n\nPress ENTER to continue {}", workingDir, MSG);
+ boolean skipPoms = skipStep();
+ ProjectVersion version = new ProjectVersion(project);
+ if (!skipPoms) {
+ this.projectUpdater.updateProject(project);
log.info("\n\nProject was successfully updated");
- log.info("\n\n\n=== BUILD PROJECT ===\n\nPress ENTER to build the project\n\n");
- System.in.read();
+ }
+ log.info("\n\n\n=== BUILD PROJECT ===\n\nPress ENTER to build the project {}", MSG);
+ boolean skipBuild = skipStep();
+ if (!skipBuild) {
this.projectBuilder.build();
log.info("\nProject was successfully built");
- log.info("\n\n\n=== COMMITTING AND PUSHING TAGS ===\n\nPress ENTER to commit, tag and push the tag\n\n");
- System.in.read();
- } catch (IOException e) {
- throw new IllegalStateException(e);
+ }
+ log.info("\n\n\n=== COMMITTING AND PUSHING TAGS ===\n\nPress ENTER to commit, tag and push the tag {}", MSG);
+ boolean skipCommit = skipStep();
+ if (!skipCommit) {
+ this.projectGitUpdater.commitAndTagIfApplicable(project, version);
+ }
+ }
+
+ boolean skipStep() {
+ String input = System.console().readLine();
+ switch (input.toLowerCase()) {
+ case SKIP:
+ return true;
+ case QUIT:
+ System.exit(0);
+ return true;
+ default:
+ return false;
}
}
}
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/GitProjectRepo.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/git/GitRepo.java
similarity index 66%
rename from spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/GitProjectRepo.java
rename to spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/git/GitRepo.java
index f0205a79..a6d30b8d 100644
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/GitProjectRepo.java
+++ b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/git/GitRepo.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.cloud.release.internal.pom;
+package org.springframework.cloud.release.internal.git;
import java.io.File;
import java.io.IOException;
@@ -28,9 +28,11 @@ import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListBranchCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.util.ResourceUtils;
/**
* Abstraction over a Git repo. Can clonea repo from a given location
@@ -38,21 +40,20 @@ import org.slf4j.LoggerFactory;
*
* @author Marcin Grzejszczak
*/
-class GitProjectRepo {
+public class GitRepo {
- private static final Logger log = LoggerFactory
- .getLogger(MethodHandles.lookup().lookupClass());
+ private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private final GitProjectRepo.JGitFactory gitFactory;
+ private final GitRepo.JGitFactory gitFactory;
private final File basedir;
- GitProjectRepo(File basedir) {
+ public GitRepo(File basedir) {
this.basedir = basedir;
- this.gitFactory = new GitProjectRepo.JGitFactory();
+ this.gitFactory = new GitRepo.JGitFactory();
}
- GitProjectRepo(File basedir, GitProjectRepo.JGitFactory factory) {
+ GitRepo(File basedir, GitRepo.JGitFactory factory) {
this.basedir = basedir;
this.gitFactory = factory;
}
@@ -62,7 +63,7 @@ class GitProjectRepo {
* @param projectUri - URI of the project
* @return file where the project was cloned
*/
- File cloneProject(URI projectUri) {
+ public File cloneProject(URI projectUri) {
try {
log.info("Cloning repo from [{}] to [{}]", projectUri, this.basedir);
Git git = cloneToBasedir(projectUri, this.basedir);
@@ -83,7 +84,7 @@ class GitProjectRepo {
* @param project - a Git project
* @param branch - branch to check out
*/
- void checkout(File project, String branch) {
+ public void checkout(File project, String branch) {
try {
log.info("Checking out branch [{}] for repo [{}] to [{}]", this.basedir, branch);
checkoutBranch(project, branch);
@@ -94,6 +95,62 @@ class GitProjectRepo {
}
}
+ /**
+ * Performs a commit
+ * @param project - a Git project
+ * @param message - commit message
+ */
+ public void commit(File project, String message) {
+ try(Git git = this.gitFactory.open(ResourceUtils.getFile(project.toURI()).getAbsoluteFile())) {
+ git.commit().setMessage(message).call();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Creates a tag with a given name
+ * @param project
+ * @param tagName
+ */
+ public void tag(File project, String tagName) {
+ try(Git git = this.gitFactory.open(ResourceUtils.getFile(project.toURI()).getAbsoluteFile())) {
+ git.tag().setName(tagName).call();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Pushes the commits to {@code origin} remote branch
+ * @param project - Git project
+ * @param branch - remote branch to which the code should be pushed
+ */
+ public void pushBranch(File project, String branch) {
+ try(Git git = this.gitFactory.open(ResourceUtils.getFile(project.toURI()).getAbsoluteFile())) {
+ String localBranch = git.getRepository().getFullBranch();
+ RefSpec refSpec = new RefSpec(localBranch + ":" + branch);
+ git.push().setPushTags().setRefSpecs(refSpec).call();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Pushes the commits to {@code origin} remote tag
+ * @param project - Git project
+ * @param tagName - remote tag to which the code should be pushed
+ */
+ public void pushTag(File project, String tagName) {
+ try(Git git = this.gitFactory.open(ResourceUtils.getFile(project.toURI()).getAbsoluteFile())) {
+ String localBranch = git.getRepository().getFullBranch();
+ RefSpec refSpec = new RefSpec(localBranch + ":" + "refs/tags/" + tagName);
+ git.push().setPushTags().setRefSpecs(refSpec).call();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
private Git cloneToBasedir(URI projectUrl, File destinationFolder)
throws GitAPIException {
CloneCommand command = this.gitFactory.getCloneCommandByCloneRepository()
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/git/ProjectGitUpdater.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/git/ProjectGitUpdater.java
new file mode 100644
index 00000000..95beca99
--- /dev/null
+++ b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/git/ProjectGitUpdater.java
@@ -0,0 +1,39 @@
+package org.springframework.cloud.release.internal.git;
+
+import java.io.File;
+import java.lang.invoke.MethodHandles;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.release.internal.pom.ProjectVersion;
+
+/**
+ * Contains business logic around Git operations
+ *
+ * @author Marcin Grzejszczak
+ */
+public class ProjectGitUpdater {
+
+ private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ private static final String MSG = "Bumping versions";
+ private static final String PRE_RELEASE_MSG = "Bumping versions before release";
+
+ public void commitAndTagIfApplicable(File project, ProjectVersion version) {
+ GitRepo gitRepo = gitRepo(project);
+ if (version.isSnapshot()) {
+ log.info("Snapshot version [{}] found. Will only commit the changed poms", version);
+ gitRepo.commit(project, MSG);
+ } else {
+ log.info("NON-snapshot version [{}] found. Will commit the changed poms, tag the version and push the tag", version);
+ gitRepo.commit(project, PRE_RELEASE_MSG);
+ String tagName = "v" + version.version;
+ gitRepo.tag(project, tagName);
+ gitRepo.pushTag(project, tagName);
+ }
+ }
+
+ GitRepo gitRepo(File workingDir) {
+ return new GitRepo(workingDir);
+ }
+}
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/PomReader.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/PomReader.java
index 4ad0e7a0..e81ce18f 100644
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/PomReader.java
+++ b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/PomReader.java
@@ -32,7 +32,11 @@ class PomReader {
/**
* Returns a parsed POM
*/
- Model readPom(File pom) {
+ Model readPom(File file) {
+ File pom = file;
+ if (file.isDirectory()) {
+ pom = new File(file,"pom.xml");
+ }
try(Reader reader = new FileReader(pom)) {
MavenXpp3Reader xpp3Reader = new MavenXpp3Reader();
return xpp3Reader.read(reader);
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/ProjectUpdater.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/ProjectUpdater.java
index 312feb62..5272bce0 100644
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/ProjectUpdater.java
+++ b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/ProjectUpdater.java
@@ -28,6 +28,7 @@ import java.nio.file.attribute.BasicFileAttributes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.release.internal.ReleaserProperties;
+import org.springframework.cloud.release.internal.git.GitRepo;
/**
* @author Marcin Grzejszczak
@@ -38,7 +39,7 @@ public class ProjectUpdater {
private final File destinationDir;
private final ReleaserProperties properties;
- private final GitProjectRepo gitProjectRepo;
+ private final GitRepo gitRepo;
private final PomUpdater pomUpdater = new PomUpdater();
public ProjectUpdater(ReleaserProperties properties) {
@@ -47,7 +48,7 @@ public class ProjectUpdater {
new File(properties.getPom().getCloneDestinationDir()) :
Files.createTempDirectory("releaser").toFile();
this.properties = properties;
- this.gitProjectRepo = new GitProjectRepo(this.destinationDir);
+ this.gitRepo = new GitRepo(this.destinationDir);
}
catch (IOException e) {
throw new IllegalStateException("Failed to create a temporary folder", e);
@@ -61,9 +62,9 @@ public class ProjectUpdater {
* @param projectRoot - root folder with project to update
*/
public void updateProject(File projectRoot) {
- File clonedScRelease = this.gitProjectRepo.cloneProject(
+ File clonedScRelease = this.gitRepo.cloneProject(
URI.create(this.properties.getPom().getSpringCloudReleaseGitUrl()));
- this.gitProjectRepo.checkout(clonedScRelease, this.properties.getPom().getBranch());
+ this.gitRepo.checkout(clonedScRelease, this.properties.getPom().getBranch());
SCReleasePomParser sCReleasePomParser = new SCReleasePomParser(clonedScRelease);
Versions versions = sCReleasePomParser.allVersions();
log.info("Retrieved the following versions\n{}", versions);
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/ProjectVersion.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/ProjectVersion.java
new file mode 100644
index 00000000..bb62f5c1
--- /dev/null
+++ b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/ProjectVersion.java
@@ -0,0 +1,43 @@
+package org.springframework.cloud.release.internal.pom;
+
+import java.io.File;
+
+/**
+ * Object representing a root project's version.
+ * Knows how to provide a minor bumped version;
+ *
+ * @author Marcin Grzejszczak
+ */
+public class ProjectVersion {
+
+ public static ProjectVersion NO_VERSION = new ProjectVersion("");
+
+ public final String version;
+ private final PomReader pomReader = new PomReader();
+
+ public ProjectVersion(String version) {
+ this.version = version;
+ }
+
+ public ProjectVersion(File project) {
+ this.version = this.pomReader.readPom(project).getVersion();
+ }
+
+ public String bumpedVersion() {
+ // 1.0.0.BUILD-SNAPSHOT
+ String[] splitVersion = this.version.split("\\.");
+ if (splitVersion.length < 4) {
+ throw new IllegalStateException("Version is invalid. Should be of format [1.2.3.A]");
+ }
+ Integer incrementedPatch = Integer.valueOf(splitVersion[2]) + 1;
+ return String.format("%s.%s.%s.%s", splitVersion[0], splitVersion[1], incrementedPatch, splitVersion[3]);
+ }
+
+ public boolean isSnapshot() {
+ return this.version.contains("SNAPSHOT");
+ }
+
+ @Override public String toString() {
+ return this.version;
+ }
+}
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/git/GitProjectRepoTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/git/GitProjectRepoTests.java
new file mode 100644
index 00000000..e5eeb5bd
--- /dev/null
+++ b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/git/GitProjectRepoTests.java
@@ -0,0 +1,217 @@
+package org.springframework.cloud.release.internal.git;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.util.List;
+
+import org.eclipse.jgit.api.CloneCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.RemoteRemoveCommand;
+import org.eclipse.jgit.api.RemoteSetUrlCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.transport.URIish;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.springframework.cloud.release.internal.pom.TestUtils;
+
+import static org.assertj.core.api.Assertions.fail;
+import static org.assertj.core.api.BDDAssertions.then;
+import static org.assertj.core.api.BDDAssertions.thenThrownBy;
+
+/**
+ * @author Marcin Grzejszczak
+ */
+public class GitProjectRepoTests {
+
+ @Rule public TemporaryFolder tmp = new TemporaryFolder();
+ File springCloudReleaseProject;
+ File tmpFolder;
+ GitRepo gitRepo;
+
+ @Before
+ public void setup() throws IOException, URISyntaxException {
+ this.tmpFolder = this.tmp.newFolder();
+ this.springCloudReleaseProject = new File(GitProjectRepoTests.class.getResource("/projects/spring-cloud-release").toURI());
+ TestUtils.prepareLocalRepo();
+ this.gitRepo = new GitRepo(this.tmpFolder);
+ }
+
+ @Test
+ public void should_clone_the_project_from_a_given_location() throws IOException {
+ this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
+
+ then(new File(this.tmpFolder, ".git")).exists();
+ }
+
+ @Test
+ public void should_throw_exception_when_there_is_no_repo() throws IOException, URISyntaxException {
+ thenThrownBy(() -> this.gitRepo
+ .cloneProject(GitProjectRepoTests.class.getResource("/projects/").toURI()))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("Exception occurred while cloning repo");
+ }
+
+ @Test
+ public void should_throw_an_exception_when_failed_to_initialize_the_repo() throws IOException {
+ thenThrownBy(() -> new GitRepo(this.tmpFolder, new ExceptionThrowingJGitFactory()).cloneProject(this.springCloudReleaseProject.toURI()))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("Exception occurred while cloning repo")
+ .hasCauseInstanceOf(CustomException.class);
+ }
+
+ @Test
+ public void should_check_out_a_branch_on_cloned_repo() throws IOException {
+ File project = this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
+ this.gitRepo.checkout(project, "vCamden.SR3");
+
+ File pom = new File(this.tmpFolder, "pom.xml");
+ then(pom).exists();
+ then(Files.lines(pom.toPath()).anyMatch(s -> s.contains("Camden.SR3"))).isTrue();
+ }
+
+ @Test
+ public void should_check_out_a_branch_on_cloned_repo2() throws IOException {
+ File project = this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
+ this.gitRepo.checkout(project, "Camden.x");
+
+ File pom = new File(this.tmpFolder, "pom.xml");
+ then(pom).exists();
+ then(Files.lines(pom.toPath()).anyMatch(s -> s.contains("Camden.BUILD-SNAPSHOT"))).isTrue();
+ }
+
+ @Test
+ public void should_throw_an_exception_when_checking_out_nonexisting_branch() throws IOException {
+ File project = this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
+ try {
+ this.gitRepo.checkout(project, "nonExistingBranch");
+ fail("should throw an exception");
+ } catch (IllegalStateException e) {
+ then(e).hasMessageContaining("Ref nonExistingBranch can not be resolved");
+ }
+ }
+
+ @Test
+ public void should_commit_changes() throws Exception {
+ File project = this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
+ createNewFile(project);
+
+ this.gitRepo.commit(project, "some message");
+
+ try(Git git = openGitProject(project)) {
+ RevCommit revCommit = git.log().call().iterator().next();
+ then(revCommit.getShortMessage()).isEqualTo("some message");
+ }
+ }
+
+ @Test
+ public void should_create_a_tag() throws Exception {
+ File project = this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
+ createNewFile(project);
+ this.gitRepo.commit(project, "some message");
+
+ this.gitRepo.tag(project, "v1.0.0");
+
+ try(Git git = openGitProject(project)) {
+ tagIsPresent(git, "v1.0.0");
+ }
+ }
+
+ private void tagIsPresent(Git git, String tag) throws GitAPIException {
+ List[ refs = git.tagList().call();
+ System.out.println("All tags" + refs);
+ then(refs.stream().anyMatch(ref -> ref.getName().startsWith("refs/tags/" + tag))).isTrue();
+ }
+
+ @Test
+ public void should_push_changes_to_master_branch() throws Exception {
+ File origin = clonedProject();
+ File project = this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
+ setOriginOnProjectToTmp(origin, project);
+ createNewFile(project);
+ this.gitRepo.commit(project, "some message");
+
+ this.gitRepo.pushBranch(project, "master");
+
+ try(Git git = openGitProject(origin)) {
+ RevCommit revCommit = git.log().call().iterator().next();
+ then(revCommit.getShortMessage()).isEqualTo("some message");
+ }
+ }
+
+ @Test
+ public void should_push_a_tag_to_new_branch_in_origin() throws Exception {
+ File origin = clonedProject();
+ File project = this.gitRepo.cloneProject(this.springCloudReleaseProject.toURI());
+ setOriginOnProjectToTmp(origin, project);
+ createNewFile(project);
+ this.gitRepo.commit(project, "some message");
+ this.gitRepo.tag(project, "v5.6.7.RELEASE");
+
+ this.gitRepo.pushTag(project, "v5.6.7.RELEASE");
+
+ try(Git git = openGitProject(origin)) {
+ tagIsPresent(git, "v5.6.7");
+ git.checkout().setName("v5.6.7.RELEASE").call();
+ RevCommit revCommit = git.log().call().iterator().next();
+ then(revCommit.getShortMessage()).isEqualTo("some message");
+ }
+ }
+
+ private void setOriginOnProjectToTmp(File origin, File project)
+ throws GitAPIException, MalformedURLException {
+ try(Git git = openGitProject(project)) {
+ RemoteRemoveCommand remove = git.remoteRemove();
+ remove.setName("origin");
+ remove.call();
+ RemoteSetUrlCommand command = git.remoteSetUrl();
+ command.setUri(new URIish(origin.toURI().toURL()));
+ command.setName("origin");
+ command.setPush(true);
+ command.call();
+ }
+ }
+
+ private Git openGitProject(File project) {
+ return new GitRepo.JGitFactory().open(project);
+ }
+
+ private File clonedProject() throws IOException {
+ File anotherFolder = this.tmp.newFolder();
+ GitRepo projectRepo = new GitRepo(anotherFolder);
+ projectRepo.cloneProject(this.springCloudReleaseProject.toURI());
+ return anotherFolder;
+ }
+
+ private void createNewFile(File project) throws Exception {
+ File newFile = new File(this.tmpFolder, "newFile");
+ newFile.createNewFile();
+ try (PrintStream out = new PrintStream(new FileOutputStream(newFile))) {
+ out.print("foo");
+ }
+ try(Git git = openGitProject(project)) {
+ git.add().addFilepattern("newFile").call();
+ }
+ }
+
+}
+
+class ExceptionThrowingJGitFactory extends GitRepo.JGitFactory {
+ @Override CloneCommand getCloneCommandByCloneRepository() {
+ throw new CustomException("foo");
+ }
+}
+
+class CustomException extends RuntimeException {
+ public CustomException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/git/ProjectGitUpdaterTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/git/ProjectGitUpdaterTests.java
new file mode 100644
index 00000000..c1db8874
--- /dev/null
+++ b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/git/ProjectGitUpdaterTests.java
@@ -0,0 +1,47 @@
+package org.springframework.cloud.release.internal.git;
+
+import java.io.File;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.springframework.cloud.release.internal.pom.ProjectVersion;
+
+import static org.mockito.BDDMockito.then;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.never;
+
+/**
+ * @author Marcin Grzejszczak
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class ProjectGitUpdaterTests {
+
+ @Mock GitRepo gitRepo;
+ ProjectGitUpdater updater = new ProjectGitUpdater() {
+ @Override GitRepo gitRepo(File workingDir) {
+ return ProjectGitUpdaterTests.this.gitRepo;
+ }
+ };
+ File file = new File("");
+
+ @Test
+ public void should_only_commit_without_pushing_changes_when_version_is_snapshot() {
+ this.updater.commitAndTagIfApplicable(file, new ProjectVersion("1.0.0.BUILD-SNAPSHOT"));
+
+ then(this.gitRepo).should().commit(any(File.class), anyString());
+ then(this.gitRepo).should(never()).tag(any(File.class), anyString());
+ }
+
+ @Test
+ public void should_commit_tag_and_push_tag_when_version_is_not_snapshot() {
+ this.updater.commitAndTagIfApplicable(file, new ProjectVersion("1.0.0.RELEASE"));
+
+ then(this.gitRepo).should().commit(any(File.class), anyString());
+ then(this.gitRepo).should().tag(any(File.class), eq("v1.0.0.RELEASE"));
+ then(this.gitRepo).should().pushTag(any(File.class), eq("v1.0.0.RELEASE"));
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/GitProjectRepoTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/GitProjectRepoTests.java
deleted file mode 100644
index 5cdd1c41..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/GitProjectRepoTests.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.file.Files;
-
-import org.eclipse.jgit.api.CloneCommand;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import static org.assertj.core.api.Assertions.fail;
-import static org.assertj.core.api.BDDAssertions.then;
-import static org.assertj.core.api.BDDAssertions.thenThrownBy;
-
-/**
- * @author Marcin Grzejszczak
- */
-public class GitProjectRepoTests {
-
- @Rule public TemporaryFolder tmp = new TemporaryFolder();
- File springCloudReleaseProject;
- File tmpFolder;
- GitProjectRepo gitProjectRepo;
-
- @Before
- public void setup() throws IOException, URISyntaxException {
- this.tmpFolder = this.tmp.newFolder();
- this.springCloudReleaseProject = new File(GitProjectRepoTests.class.getResource("/projects/spring-cloud-release").toURI());
- TestUtils.prepareLocalRepo();
- this.gitProjectRepo = new GitProjectRepo(this.tmpFolder);
- }
-
- @Test
- public void should_clone_the_project_from_a_given_location() throws IOException {
- this.gitProjectRepo.cloneProject(this.springCloudReleaseProject.toURI());
-
- then(new File(this.tmpFolder, ".git")).exists();
- }
-
- @Test
- public void should_throw_exception_when_there_is_no_repo() throws IOException, URISyntaxException {
- thenThrownBy(() -> this.gitProjectRepo
- .cloneProject(GitProjectRepoTests.class.getResource("/projects/").toURI()))
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("Exception occurred while cloning repo");
- }
-
- @Test
- public void should_throw_an_exception_when_failed_to_initialize_the_repo() throws IOException {
- thenThrownBy(() -> new GitProjectRepo(this.tmpFolder, new ExceptionThrowingJGitFactory()).cloneProject(this.springCloudReleaseProject.toURI()))
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("Exception occurred while cloning repo")
- .hasCauseInstanceOf(CustomException.class);
- }
-
- @Test
- public void should_check_out_a_branch_on_cloned_repo() throws IOException {
- File project = this.gitProjectRepo.cloneProject(this.springCloudReleaseProject.toURI());
- this.gitProjectRepo.checkout(project, "vCamden.SR3");
-
- File pom = new File(this.tmpFolder, "pom.xml");
- then(pom).exists();
- then(Files.lines(pom.toPath()).anyMatch(s -> s.contains("Camden.SR3"))).isTrue();
- }
-
- @Test
- public void should_check_out_a_branch_on_cloned_repo2() throws IOException {
- File project = this.gitProjectRepo.cloneProject(this.springCloudReleaseProject.toURI());
- this.gitProjectRepo.checkout(project, "Camden.x");
-
- File pom = new File(this.tmpFolder, "pom.xml");
- then(pom).exists();
- then(Files.lines(pom.toPath()).anyMatch(s -> s.contains("Camden.BUILD-SNAPSHOT"))).isTrue();
- }
-
- @Test
- public void should_throw_an_exception_when_checking_out_nonexisting_branch() throws IOException {
- File project = this.gitProjectRepo.cloneProject(this.springCloudReleaseProject.toURI());
- try {
- this.gitProjectRepo.checkout(project, "nonExistingBranch");
- fail("should throw an exception");
- } catch (IllegalStateException e) {
- then(e).hasMessageContaining("Ref nonExistingBranch can not be resolved");
- }
- }
-
-}
-
-class ExceptionThrowingJGitFactory extends GitProjectRepo.JGitFactory {
- @Override CloneCommand getCloneCommandByCloneRepository() {
- throw new CustomException("foo");
- }
-}
-
-class CustomException extends RuntimeException {
- public CustomException(String message) {
- super(message);
- }
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomReaderTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomReaderTests.java
index 59c5e1c1..cc869596 100644
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomReaderTests.java
+++ b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomReaderTests.java
@@ -16,9 +16,6 @@
package org.springframework.cloud.release.internal.pom;
-import static org.assertj.core.api.BDDAssertions.then;
-import static org.assertj.core.api.BDDAssertions.thenThrownBy;
-
import java.io.File;
import java.io.IOException;
import java.net.URI;
@@ -28,6 +25,10 @@ import org.apache.maven.model.Model;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.junit.Before;
import org.junit.Test;
+import org.springframework.cloud.release.internal.git.GitProjectRepoTests;
+
+import static org.assertj.core.api.BDDAssertions.then;
+import static org.assertj.core.api.BDDAssertions.thenThrownBy;
/**
* @author Marcin Grzejszczak
@@ -35,18 +36,28 @@ import org.junit.Test;
public class PomReaderTests {
PomReader pomReader = new PomReader();
+ File springCloudReleaseProjectPom;
File springCloudReleaseProject;
File licenseFile;
@Before
public void setup() throws URISyntaxException {
URI scRelease = GitProjectRepoTests.class.getResource("/projects/spring-cloud-release").toURI();
- this.springCloudReleaseProject = new File(scRelease.getPath(), "pom.xml");
+ this.springCloudReleaseProject = new File(scRelease);
+ this.springCloudReleaseProjectPom = new File(scRelease.getPath(), "pom.xml");
this.licenseFile = new File(scRelease.getPath(), "LICENSE.txt");
}
@Test
public void should_parse_a_valid_pom() {
+ Model pom = this.pomReader.readPom(this.springCloudReleaseProjectPom);
+
+ then(pom).isNotNull();
+ then(pom.getArtifactId()).isEqualTo("spring-cloud-starter-build");
+ }
+
+ @Test
+ public void should_parse_a_valid_pom_when_passing_direcory() {
Model pom = this.pomReader.readPom(this.springCloudReleaseProject);
then(pom).isNotNull();
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomUpdaterTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomUpdaterTests.java
index 8209eff5..021d6bde 100644
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomUpdaterTests.java
+++ b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomUpdaterTests.java
@@ -30,6 +30,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.springframework.boot.test.rule.OutputCapture;
+import org.springframework.cloud.release.internal.git.GitProjectRepoTests;
import org.springframework.util.FileSystemUtils;
/**
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/ProjectVersionTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/ProjectVersionTests.java
new file mode 100644
index 00000000..60d2711c
--- /dev/null
+++ b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/ProjectVersionTests.java
@@ -0,0 +1,64 @@
+package org.springframework.cloud.release.internal.pom;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.cloud.release.internal.git.GitProjectRepoTests;
+
+import static org.assertj.core.api.BDDAssertions.then;
+import static org.assertj.core.api.BDDAssertions.thenThrownBy;
+
+/**
+ * @author Marcin Grzejszczak
+ */
+public class ProjectVersionTests {
+
+ File springCloudReleaseProject;
+
+ @Before
+ public void setup() throws URISyntaxException {
+ URI scRelease = GitProjectRepoTests.class.getResource("/projects/spring-cloud-release").toURI();
+ this.springCloudReleaseProject = new File(scRelease.getPath(), "pom.xml");
+ }
+
+ @Test
+ public void should_build_version_from_file() {
+ ProjectVersion projectVersion = new ProjectVersion(this.springCloudReleaseProject);
+
+ then(projectVersion.version).isEqualTo("Dalston.BUILD-SNAPSHOT");
+ }
+
+ @Test
+ public void should_throw_exception_if_version_is_not_long_enough() {
+ String version = "1.0";
+
+ thenThrownBy(() -> new ProjectVersion(version).bumpedVersion())
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("Version is invalid");
+ }
+
+ @Test
+ public void should_bump_version_by_patch_version() {
+ String version = "1.0.1.BUILD-SNAPSHOT";
+
+ then(new ProjectVersion(version).bumpedVersion()).isEqualTo("1.0.2.BUILD-SNAPSHOT");
+ }
+
+ @Test
+ public void should_return_true_for_snapshot_version() {
+ String version = "1.0.1.BUILD-SNAPSHOT";
+
+ then(new ProjectVersion(version).isSnapshot()).isTrue();
+ }
+
+ @Test
+ public void should_return_false_for_snapshot_version() {
+ String version = "1.0.1.RELEASE";
+
+ then(new ProjectVersion(version).isSnapshot()).isFalse();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/SCReleasePomParserTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/SCReleasePomParserTests.java
index 64db70ef..3ca488fe 100644
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/SCReleasePomParserTests.java
+++ b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/SCReleasePomParserTests.java
@@ -6,6 +6,7 @@ import java.net.URISyntaxException;
import org.junit.Before;
import org.junit.Test;
+import org.springframework.cloud.release.internal.git.GitProjectRepoTests;
import static org.assertj.core.api.BDDAssertions.then;
import static org.assertj.core.api.BDDAssertions.thenThrownBy;
diff --git a/spring-cloud-release-tools-spring/src/main/java/org/springframework/cloud/release/spring/ReleaserConfiguration.java b/spring-cloud-release-tools-spring/src/main/java/org/springframework/cloud/release/spring/ReleaserConfiguration.java
index 5c4d54a9..eec26c65 100644
--- a/spring-cloud-release-tools-spring/src/main/java/org/springframework/cloud/release/spring/ReleaserConfiguration.java
+++ b/spring-cloud-release-tools-spring/src/main/java/org/springframework/cloud/release/spring/ReleaserConfiguration.java
@@ -19,6 +19,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cloud.release.internal.Releaser;
import org.springframework.cloud.release.internal.ReleaserProperties;
import org.springframework.cloud.release.internal.builder.ProjectBuilder;
+import org.springframework.cloud.release.internal.git.ProjectGitUpdater;
import org.springframework.cloud.release.internal.pom.ProjectUpdater;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -28,6 +29,7 @@ import org.springframework.context.annotation.Configuration;
class ReleaserConfiguration {
@Bean Releaser releaser(ReleaserProperties properties) {
- return new Releaser(properties, new ProjectUpdater(properties), new ProjectBuilder(properties));
+ return new Releaser(properties, new ProjectUpdater(properties),
+ new ProjectBuilder(properties), new ProjectGitUpdater());
}
}
]