From 6bddf9951f5add4e7df03519b4843371d79e6fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 8 Nov 2018 14:59:00 +0100 Subject: [PATCH] Make commit message configurable --- .../repository/api/MergeCommandBuilder.java | 23 +++++++++++++++++-- .../repository/spi/MergeCommandRequest.java | 9 ++++++++ .../scm/repository/spi/GitMergeCommand.java | 22 ++++++++++++++---- .../repository/spi/GitMergeCommandTest.java | 22 ++++++++++++++++++ 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandBuilder.java index 3823b2b3a7..881a374864 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandBuilder.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandBuilder.java @@ -10,8 +10,8 @@ import sonia.scm.repository.spi.MergeCommandRequest; * the branches could be merged without conflicts ({@link #dryRun()}). To do so, you have to specify the name of * the target branch ({@link #setTargetBranch(String)}) and the name of the branch that should be merged * ({@link #setBranchToMerge(String)}). Additionally you can specify an author that should be used for the commit - * ({@link #setAuthor(Person)}) if you are not doing a dry run only. If no author is specified, the logged in user - * will be used instead. + * ({@link #setAuthor(Person)}) and a message template ({@link #setMessageTemplate(String)}) if you are not doing a dry + * run only. If no author is specified, the logged in user and a default message will be used instead. * * To actually merge feature_branch into integration_branch do this: *

@@ -91,6 +91,25 @@ public class MergeCommandBuilder {
     return this;
   }
 
+  /**
+   * Use this to set a template for the commit message. If no message is set, a default message will be used.
+   *
+   * You can use the placeholder {0} for the branch to be merged and {1} for the target
+   * branch, eg.:
+   *
+   * 

+   * ...setMessageTemplate("Merge of {0} into {1}")...
+   * 
+ * + * This is optional and for {@link #executeMerge()} only. + * + * @return This builder instance. + */ + public MergeCommandBuilder setMessageTemplate(String messageTemplate) { + request.setMessageTemplate(messageTemplate); + return this; + } + /** * Use this to reset the command. * @return This builder instance. diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/MergeCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/MergeCommandRequest.java index 05f160ec0a..baf03a0aef 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/MergeCommandRequest.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/MergeCommandRequest.java @@ -16,6 +16,7 @@ public class MergeCommandRequest implements Validateable, Resetable, Serializabl private String branchToMerge; private String targetBranch; private Person author; + private String messageTemplate; public String getBranchToMerge() { return branchToMerge; @@ -41,6 +42,14 @@ public class MergeCommandRequest implements Validateable, Resetable, Serializabl this.author = author; } + public String getMessageTemplate() { + return messageTemplate; + } + + public void setMessageTemplate(String messageTemplate) { + this.messageTemplate = messageTemplate; + } + public boolean isValid() { return !Strings.isNullOrEmpty(getBranchToMerge()) && !Strings.isNullOrEmpty(getTargetBranch()); diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommand.java index f61038b069..05541e8295 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommand.java @@ -1,5 +1,6 @@ package sonia.scm.repository.spi; +import com.google.common.base.Strings; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; import org.eclipse.jgit.api.Git; @@ -19,15 +20,16 @@ import sonia.scm.repository.api.MergeDryRunCommandResult; import sonia.scm.user.User; import java.io.IOException; +import java.text.MessageFormat; public class GitMergeCommand extends AbstractGitCommand implements MergeCommand { private static final Logger logger = LoggerFactory.getLogger(GitMergeCommand.class); - private static final String MERGE_COMMIT_MESSAGE_TEMPLATE = - "Merge of branch %s into %s\n" + - "\n" + - "Automatic merge by SCM-Manager."; + private static final String MERGE_COMMIT_MESSAGE_TEMPLATE = String.join("\n", + "Merge of branch {0} into {1}", + "", + "Automatic merge by SCM-Manager."); private final GitWorkdirFactory workdirFactory; @@ -64,11 +66,13 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand private final String toMerge; private final Person author; private final Git clone; + private final String messageTemplate; private MergeWorker(Repository clone, MergeCommandRequest request) { this.target = request.getTargetBranch(); this.toMerge = request.getBranchToMerge(); this.author = request.getAuthor(); + this.messageTemplate = request.getMessageTemplate(); this.clone = new Git(clone); } @@ -111,13 +115,21 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand try { clone.commit() .setAuthor(authorToUse.getName(), authorToUse.getMail()) - .setMessage(String.format(MERGE_COMMIT_MESSAGE_TEMPLATE, toMerge, target)) + .setMessage(MessageFormat.format(determineMessageTemplate(), toMerge, target)) .call(); } catch (GitAPIException e) { throw new InternalRepositoryException("could not commit merge between branch " + toMerge + " and " + target, e); } } + private String determineMessageTemplate() { + if (Strings.isNullOrEmpty(messageTemplate)) { + return MERGE_COMMIT_MESSAGE_TEMPLATE; + } else { + return messageTemplate; + } + } + private Person determineAuthor() { if (author == null) { Subject subject = SecurityUtils.getSubject(); diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitMergeCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitMergeCommandTest.java index 5bb9af7d8f..1fca7814ed 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitMergeCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitMergeCommandTest.java @@ -67,14 +67,36 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase { Iterable commits = new Git(repository).log().add(repository.resolve("master")).setMaxCount(1).call(); RevCommit mergeCommit = commits.iterator().next(); PersonIdent mergeAuthor = mergeCommit.getAuthorIdent(); + String message = mergeCommit.getFullMessage(); assertThat(mergeAuthor.getName()).isEqualTo("Dirk Gently"); assertThat(mergeAuthor.getEmailAddress()).isEqualTo("dirk@holistic.det"); + assertThat(message).contains("master", "mergeable"); // We expect the merge result of file b.txt here by looking up the sha hash of its content. // If the file is missing (aka not merged correctly) this will throw a MissingObjectException: byte[] contentOfFileB = repository.open(repository.resolve("9513e9c76e73f3e562fd8e4c909d0607113c77c6")).getBytes(); assertThat(new String(contentOfFileB)).isEqualTo("b\ncontent from branch\n"); } + @Test + public void shouldUseConfiguredCommitMessageTemplate() throws IOException, GitAPIException { + GitMergeCommand command = createCommand(); + MergeCommandRequest request = new MergeCommandRequest(); + request.setTargetBranch("master"); + request.setBranchToMerge("mergeable"); + request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det")); + request.setMessageTemplate("simple"); + + MergeCommandResult mergeCommandResult = command.merge(request); + + assertThat(mergeCommandResult.isSuccess()).isTrue(); + + Repository repository = createContext().open(); + Iterable commits = new Git(repository).log().add(repository.resolve("master")).setMaxCount(1).call(); + RevCommit mergeCommit = commits.iterator().next(); + String message = mergeCommit.getFullMessage(); + assertThat(message).isEqualTo("simple"); + } + @Test public void shouldNotMergeConflictingBranches() { GitMergeCommand command = createCommand();