Skip to content

Commit

Permalink
Merge pull request danielflower#119
Browse files Browse the repository at this point in the history
  • Loading branch information
danielflower authored Apr 24, 2022
2 parents 61eb242 + a12837a commit 90b35f1
Show file tree
Hide file tree
Showing 32 changed files with 301 additions and 51 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.github.danielflower.mavenplugins</groupId>
<artifactId>multi-module-maven-release-plugin</artifactId>
<version>3.5-SNAPSHOT</version> <!-- When changing also update scaffolding.TestProject.PLUGIN_VERSION_FOR_TESTS and add to src/site/markdown/changelog.md -->
<version>3.6-SNAPSHOT</version> <!-- When changing also update scaffolding.TestProject.PLUGIN_VERSION_FOR_TESTS and add to src/site/markdown/changelog.md -->

<name>The Multi Module Maven Release Plugin</name>
<description>A maven release plugin built for multi-maven-module git repositories allowing continuous deployment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevWalk;
import org.json.simple.JSONObject;
Expand All @@ -16,28 +17,58 @@
public class AnnotatedTag {
public static final String VERSION = "version";
public static final String BUILD_NUMBER = "buildNumber";
public static final String TAG_PREFIX = "refs/tags/";
private final String name;
private final JSONObject message;
private Ref ref;
private RevCommit tagCommit;

private AnnotatedTag(Ref ref, String name, JSONObject message) {
private AnnotatedTag(Ref ref, RevCommit tagCommit, String name, JSONObject message) {
Guard.notBlank("tag name", name);
Guard.notNull("tag message", message);
this.ref = ref;
this.name = name;
this.message = message;
this.tagCommit = tagCommit;
}

public ObjectId getObjectId() {
return tagCommit.getId();
}

public static AnnotatedTag create(String name, String version, long buildNumber) {
JSONObject message = new JSONObject();
message.put(VERSION, version);
message.put(BUILD_NUMBER, String.valueOf(buildNumber));
return new AnnotatedTag(null, name, message);
return new AnnotatedTag(null, null, name, message);
}

public static AnnotatedTag fromRef(Repository repository, Ref gitTag) throws IOException, IncorrectObjectTypeException {
Guard.notNull("gitTag", gitTag);

RevWalk walk = new RevWalk(repository);
JSONObject message;
RevCommit tagCommit;
try {
ObjectId tagId = gitTag.getObjectId();
RevTag tag = walk.parseTag(tagId);
tagCommit = walk.parseCommit(tag);
message = (JSONObject) JSONValue.parse(tag.getFullMessage());
} finally {
walk.dispose();
}
if (message == null) {
message = new JSONObject();
message.put(VERSION, "0");
message.put(BUILD_NUMBER, "0");
}
return new AnnotatedTag(gitTag, tagCommit, stripRefPrefix(gitTag.getName()), message);
}


public static AnnotatedTag fromRefCommit(Repository repository, Ref gitTag, RevCommit commit) throws IOException, IncorrectObjectTypeException {
Guard.notNull("gitTag", gitTag);

RevWalk walk = new RevWalk(repository);
JSONObject message;
try {
Expand All @@ -52,11 +83,12 @@ public static AnnotatedTag fromRef(Repository repository, Ref gitTag) throws IOE
message.put(VERSION, "0");
message.put(BUILD_NUMBER, "0");
}
return new AnnotatedTag(gitTag, stripRefPrefix(gitTag.getName()), message);
return new AnnotatedTag(gitTag, commit, stripRefPrefix(gitTag.getName()), message);
}

static String stripRefPrefix(String refName) {
return refName.substring("refs/tags/".length());
assert refName.startsWith(TAG_PREFIX);
return refName.substring(TAG_PREFIX.length());
}

public String name() {
Expand All @@ -74,6 +106,7 @@ public long buildNumber() {
public Ref saveAtHEAD(Git git) throws GitAPIException {
String json = message.toJSONString();
ref = git.tag().setName(name()).setAnnotated(true).setMessage(json).call();
tagCommit = git.log().setMaxCount(1).call().iterator().next();
return ref;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package com.github.danielflower.mavenplugins.release;

import static java.util.stream.Collectors.groupingBy;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.maven.plugin.MojoExecutionException;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.LogCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.revwalk.RevCommit;

class AnnotatedTagFinder {
private VersionNamer versionNamer;
Expand All @@ -20,28 +25,56 @@ class AnnotatedTagFinder {

List<AnnotatedTag> tagsForVersion(Git git, String module, String versionWithoutBuildNumber) throws MojoExecutionException {
ArrayList<AnnotatedTag> results = new ArrayList<AnnotatedTag>();
List<Ref> tags;
try {
tags = git.tagList().call();
} catch (GitAPIException e) {
throw new MojoExecutionException("Error while getting a list of tags in the local repo", e);
}
Collections.reverse(tags);
String tagWithoutBuildNumber = module + "-" + versionWithoutBuildNumber;
for (Ref tag : tags) {
if (isPotentiallySameVersionIgnoringBuildNumber(tagWithoutBuildNumber, tag.getName())) {
try {
results.add(AnnotatedTag.fromRef(git.getRepository(), tag));
} catch (IncorrectObjectTypeException ignored) {
// not actually a tag, so skip it.
} catch (IOException e) {
throw new MojoExecutionException("Error while looking up tag " + tag, e);
ArrayList<RefWithCommitId> tagCommits = getAnnotatedTags(git, module, versionWithoutBuildNumber);
Map<ObjectId, List<RefWithCommitId>> commitTags = tagCommits.stream().collect(groupingBy(
RefWithCommitId::getCommitObjectId));
Iterable<RevCommit> commits = git.log().call();
for (RevCommit commit : commits) {
if (commitTags.containsKey(commit.getId())) {
for (RefWithCommitId tag : commitTags.get(commit.getId())) {
try {
results.add(AnnotatedTag.fromRefCommit(git.getRepository(), tag.getRef(), commit));
} catch (IncorrectObjectTypeException ignored) {
// not actually a tag, so skip it.
} catch (IOException e) {
throw new MojoExecutionException("Error while looking up tag " + tag, e);
}
}
// we want the version of the latest commit so we stop here
break;
}
}
} catch (GitAPIException | IOException e) {
throw new MojoExecutionException("Error while getting a list of annotated tags in the local repo", e);
}
return results;
}

private ArrayList<RefWithCommitId> getAnnotatedTags(Git git, String module, String versionWithoutBuildNumber)
throws GitAPIException, IOException
{
String tagWithoutBuildNumber = module + "-" + versionWithoutBuildNumber;
ArrayList<RefWithCommitId> allTags = new ArrayList<RefWithCommitId>();
List<Ref> tags = git.tagList().call();

for (Ref ref : tags) {
if(!isPotentiallySameVersionIgnoringBuildNumber(tagWithoutBuildNumber, ref.getName())) continue;

LogCommand log = git.log();

Ref peeledRef = git.getRepository().getRefDatabase().peel(ref);
if(peeledRef.getPeeledObjectId() != null) {
log.add(peeledRef.getPeeledObjectId());
} else {
log.add(ref.getObjectId());
}
RevCommit commit = log.call().iterator().next();
allTags.add(new RefWithCommitId(ref, commit.getId()));
}
return allTags;
}

boolean isPotentiallySameVersionIgnoringBuildNumber(String versionWithoutBuildNumber, String refName) {
return buildNumberOf(versionWithoutBuildNumber, refName) != null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import java.io.IOException;
import java.util.Collection;
import java.util.List;

public interface DiffDetector {
boolean hasChangedSince(String modulePath, java.util.List<String> childModules, Collection<AnnotatedTag> tags) throws IOException;
boolean hasChangedSince(String modulePath, List<String> childModules, Collection<AnnotatedTag> tags) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.github.danielflower.mavenplugins.release;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;

public final class RefWithCommitId
{
private final Ref ref;
private final ObjectId commitId;

public RefWithCommitId(Ref ref, ObjectId commitId) {
Guard.notNull("ref", ref);
Guard.notNull("commitId", commitId);
this.ref = ref;
this.commitId = commitId;
}

public Ref getRef() {
return ref;
}



public ObjectId getCommitObjectId() {
return commitId;
}

@Override
public String toString() {
return "RefWithCommitId{" +
"ref='" + ref.toString() + '\'' +
", commitId=" + commitId.toString() +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RefWithCommitId that = (RefWithCommitId) o;
return ref.equals(that.ref);
}

@Override
public int hashCode() {
return ref.hashCode();
}
}
4 changes: 4 additions & 0 deletions src/site/markdown/changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Changelog
---------

### 3.6.0

* Latest tagged version from current branch is used for unchanged modules [issue #118 for details](https://github.com/danielflower/multi-module-maven-release-plugin/issues/118)

### 3.2.0

* Added support for processing version properties e.g. `<version>${foo.version}</version>`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,21 @@ public class AnnotatedTagFinderTest {
public void findsTheLatestCommitWhereThereHaveBeenNoBranches() throws Exception {
TestProject project = TestProject.independentVersionsProject();

AnnotatedTag tag1 = saveFileInModule(project, "console-app", "1.2", 3);
AnnotatedTag tag2 = saveFileInModule(project, "core-utils", "2", 0);
AnnotatedTag tag3 = saveFileInModule(project, "console-app", "1.2", 4);
saveFileInModuleAndTag(project, "console-app", "1.2", 3);
AnnotatedTag tag1 = saveFileInModuleAndTag(project, "core-utils", "2", 0);
AnnotatedTag tag2 = saveFileInModuleAndTag(project, "console-app", "1.2", 4);

assertThat(annotatedTagFinder.tagsForVersion(project.local, "console-app", "1.3"), hasSize(0));
assertThat(annotatedTagFinder.tagsForVersion(project.local, "console-app", "1.2"), containsInAnyOrder(tag1, tag3));
assertThat(annotatedTagFinder.tagsForVersion(project.local, "core-utils", "2"), contains(tag2));
assertThat(annotatedTagFinder.tagsForVersion(project.local, "console-app", "1.2"), contains(tag2));
assertThat(annotatedTagFinder.tagsForVersion(project.local, "core-utils", "2"), contains(tag1));
}

static AnnotatedTag saveFileInModule(TestProject project, String moduleName, String version, long buildNumber) throws IOException, GitAPIException {
static AnnotatedTag saveFileInModuleAndTag(TestProject project, String moduleName, String version, long buildNumber) throws IOException, GitAPIException {
project.commitRandomFile(moduleName);
return tagCurrentCommit(project, moduleName, version, buildNumber);
}

static AnnotatedTag tagCurrentCommit(TestProject project, String moduleName, String version, long buildNumber) throws GitAPIException {
String nameForTag = moduleName.equals(".") ? "root" : moduleName;
return tagLocalRepo(project, nameForTag + "-" + version + versionNamer.getDelimiter() + buildNumber, version, buildNumber);
}
Expand All @@ -54,14 +58,28 @@ public void canRecogniseTagsThatArePotentiallyOfTheSameVersion() {
@Test
public void returnsMultipleTagsOnASingleCommit() throws IOException, GitAPIException, MojoExecutionException {
TestProject project = TestProject.independentVersionsProject();
saveFileInModule(project, "console-app", "1.2", 1);
AnnotatedTag tag1 = tagLocalRepo(project, "console-app-1.1.1.1", "1.1.1", 1);
AnnotatedTag tag3 = tagLocalRepo(project, "console-app-1.1.1.3", "1.1.1", 3);
AnnotatedTag tag2 = tagLocalRepo(project, "console-app-1.1.1.2", "1.1.1", 2);
saveFileInModuleAndTag(project, "console-app", "1.2", 1);
AnnotatedTag tag1 = tagCurrentCommit(project, "console-app", "1.1.1", 1);
AnnotatedTag tag3 = tagCurrentCommit(project, "console-app", "1.1.1", 3);
AnnotatedTag tag2 = tagCurrentCommit(project, "console-app", "1.1.1", 2);
List<AnnotatedTag> annotatedTags = annotatedTagFinder.tagsForVersion(project.local, "console-app", "1.1.1");
assertThat(annotatedTags, containsInAnyOrder(tag1, tag2, tag3));
}

@Test
public void returnsOnlyTagsOfCurrentBranch() throws IOException, GitAPIException, MojoExecutionException {
TestProject project = TestProject.singleModuleProject();
AnnotatedTag tag1 = saveFileInModuleAndTag(project, ".", "1.0", 0);
project.createBranch("feature");
project.commitRandomFile(".");
AnnotatedTag tag2 = saveFileInModuleAndTag(project, ".", "1.0", 1);
project.checkoutBranch("feature");

List<AnnotatedTag> annotatedTags = annotatedTagFinder.tagsForVersion(project.local, "root", "1.0");

assertThat(annotatedTags, both(contains(tag1)).and(not(contains(tag2))));
}

@Test
public void versionNamerCaresNotForOrderOfTags() throws ValidationException {
VersionNamer versionNamer = new VersionNamer();
Expand Down
Loading

0 comments on commit 90b35f1

Please sign in to comment.