Allow to specify which group of the comment link holds the issue id
This configuration option is useful when reusing the same comment
link for different its plugins.
Change-Id: I16786b96c388deca5559f57d1d7760a5c8472410
diff --git a/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java b/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java
index 2be5be8..cdca3e8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java
@@ -147,6 +147,10 @@
/**
* Gets the regular expression used to identify issue ids.
+ * <p>
+ * The index of the group that holds the issue id is
+ * {@link #getIssuePatternGroupIndex()}.
+ *
* @return the regular expression, or {@code null}, if there is no pattern
* to match issue ids.
*/
@@ -161,6 +165,24 @@
}
/**
+ * Gets the index of the group in the issue pattern that holds the issue id.
+ * <p>
+ * The corresponding issue pattern is {@link #getIssuePattern()}
+ *
+ * @return the group index for {@link #getIssuePattern()} that holds the
+ * issue id. The group index is guaranteed to be a valid group index.
+ */
+ public int getIssuePatternGroupIndex() {
+ Pattern pattern = getIssuePattern();
+ int groupCount = pattern.matcher("").groupCount();
+ int index = gerritConfig.getInt(pluginName, "commentlinkGroupIndex", 1);
+ if (index < 0 || index > groupCount) {
+ index = (groupCount == 0 ? 0 : 1);
+ }
+ return index;
+ }
+
+ /**
* Gets how necessary it is to associate commits with issues
* @return policy on how necessary association with issues is
*/
diff --git a/src/main/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractor.java b/src/main/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractor.java
index 4894492..45892d2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractor.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractor.java
@@ -51,8 +51,8 @@
Set<String> issues = Sets.newHashSet();
Matcher matcher = pattern.matcher(haystack);
+ int groupIdx = itsConfig.getIssuePatternGroupIndex();
while (matcher.find()) {
- int groupIdx = Math.min(matcher.groupCount(), 1);
String issueId = matcher.group(groupIdx);
if (!Strings.isNullOrEmpty(issueId)) {
issues.add(issueId);
diff --git a/src/main/resources/Documentation/config-common.md b/src/main/resources/Documentation/config-common.md
index 26da3ca..a111aba 100644
--- a/src/main/resources/Documentation/config-common.md
+++ b/src/main/resources/Documentation/config-common.md
@@ -17,8 +17,8 @@
[commentlink][upstream-comment-link-doc]s of
([per default][common-config-commentlink]) name "`@PLUGIN@`".
-The first group of `commentlink.@PLUGIN@.match` is considered the
-issue id.
+The ([per default][common-config-commentlinkGroupIndex]) first group of
+`commentlink.@PLUGIN@.match` is considered the issue id.
So for example having
@@ -148,6 +148,7 @@
-----------------------------------------------------------------------
[common-config-commentlink]: #common-config-commentlink
+[common-config-commentlinkGroupIndex]: #common-config-commentlinkGroupIndex
<a name="common-config-commentlink">`@PLUGIN@.commentlink`
: The name of the comment link to use to extract issue ids.
@@ -159,6 +160,13 @@
Default is `@PLUGIN@`
+<a name="common-config-commentlinkGroupIndex">`@PLUGIN@.commentlinkGroupIndex`
+: The group index within `@PLUGIN@.commentlink` that holds the issue id.
+
+ Default is `1`, if there are are groups within the regular expression for
+ the `@PLUGIN@.commentlink` comment link, and the default is `0`, if there
+ are no such groups.
+
[Back to @PLUGIN@ documentation index][index]
[index]: index.html
diff --git a/src/test/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfigTest.java b/src/test/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfigTest.java
index 0417c55..88b99fd 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfigTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfigTest.java
@@ -465,6 +465,102 @@
}
+ public void testPatternGroupIndexGroupDefault() {
+ ItsConfig itsConfig = createItsConfig();
+
+ expect(serverConfig.getString("ItsTestName", null, "commentlink"))
+ .andReturn(null).atLeastOnce();
+ expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
+ .andReturn("(foo)(bar)(baz)").atLeastOnce();
+ expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
+ .andReturn(1).atLeastOnce();
+
+ replayMocks();
+
+ assertEquals("Expected and actual group index do not match",
+ 1, itsConfig.getIssuePatternGroupIndex());
+ }
+
+ public void testPatternGroupIndexGroupDefaultGroupless() {
+ ItsConfig itsConfig = createItsConfig();
+
+ expect(serverConfig.getString("ItsTestName", null, "commentlink"))
+ .andReturn(null).atLeastOnce();
+ expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
+ .andReturn("foo").atLeastOnce();
+ expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
+ .andReturn(1).atLeastOnce();
+
+ replayMocks();
+
+ assertEquals("Expected and actual group index do not match",
+ 0, itsConfig.getIssuePatternGroupIndex());
+ }
+
+ public void testPatternGroupIndexGroup1() {
+ ItsConfig itsConfig = createItsConfig();
+
+ expect(serverConfig.getString("ItsTestName", null, "commentlink"))
+ .andReturn(null).atLeastOnce();
+ expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
+ .andReturn("(foo)(bar)(baz)").atLeastOnce();
+ expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
+ .andReturn(1).atLeastOnce();
+
+ replayMocks();
+
+ assertEquals("Expected and actual group index do not match",
+ 1, itsConfig.getIssuePatternGroupIndex());
+ }
+
+ public void testPatternGroupIndexGroup3() {
+ ItsConfig itsConfig = createItsConfig();
+
+ expect(serverConfig.getString("ItsTestName", null, "commentlink"))
+ .andReturn(null).atLeastOnce();
+ expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
+ .andReturn("(foo)(bar)(baz)").atLeastOnce();
+ expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
+ .andReturn(3).atLeastOnce();
+
+ replayMocks();
+
+ assertEquals("Expected and actual group index do not match",
+ 3, itsConfig.getIssuePatternGroupIndex());
+ }
+
+ public void testPatternGroupIndexGroupTooHigh() {
+ ItsConfig itsConfig = createItsConfig();
+
+ expect(serverConfig.getString("ItsTestName", null, "commentlink"))
+ .andReturn(null).atLeastOnce();
+ expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
+ .andReturn("(foo)(bar)(baz)").atLeastOnce();
+ expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
+ .andReturn(5).atLeastOnce();
+
+ replayMocks();
+
+ assertEquals("Expected and actual group index do not match",
+ 1, itsConfig.getIssuePatternGroupIndex());
+ }
+
+ public void testPatternGroupIndexGroupTooHighGroupless() {
+ ItsConfig itsConfig = createItsConfig();
+
+ expect(serverConfig.getString("ItsTestName", null, "commentlink"))
+ .andReturn(null).atLeastOnce();
+ expect(serverConfig.getString("commentlink", "ItsTestName", "match"))
+ .andReturn("foo").atLeastOnce();
+ expect(serverConfig.getInt("ItsTestName", "commentlinkGroupIndex", 1))
+ .andReturn(5).atLeastOnce();
+
+ replayMocks();
+
+ assertEquals("Expected and actual group index do not match",
+ 0, itsConfig.getIssuePatternGroupIndex());
+ }
+
public void testItsAssociationPolicyOptional() {
ItsConfig itsConfig = createItsConfig();
diff --git a/src/test/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractorTest.java b/src/test/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractorTest.java
index f20e955..7a1530d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractorTest.java
@@ -65,6 +65,7 @@
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
replayMocks();
@@ -79,6 +80,7 @@
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(X*)(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
replayMocks();
@@ -93,6 +95,7 @@
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
replayMocks();
@@ -108,6 +111,7 @@
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
replayMocks();
@@ -123,6 +127,7 @@
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#\\d+"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(0).atLeastOnce();
replayMocks();
@@ -133,11 +138,12 @@
assertLogMessageContains("Matching");
}
- public void testIssueIdsMultiGroupMatch() {
+ public void testIssueIdsMultiGroupMatchGroup1() {
IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
expect(itsConfig.getIssuePattern())
.andReturn(Pattern.compile("bug#(\\d)(\\d+)")).atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
replayMocks();
@@ -148,11 +154,28 @@
assertLogMessageContains("Matching");
}
+ public void testIssueIdsMultiGroupMatchGroup2() {
+ IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
+
+ expect(itsConfig.getIssuePattern())
+ .andReturn(Pattern.compile("bug#(\\d)(\\d+)")).atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(2).atLeastOnce();
+
+ replayMocks();
+
+ String ret[] = issueExtractor.getIssueIds("Foo bug#4711 bar");
+ assertEquals("Number of found ids do not match", 1, ret.length);
+ assertEquals("Found issue id does not match", "711", ret[0]);
+
+ assertLogMessageContains("Matching");
+ }
+
public void testIssueIdsMulipleMatches() {
IssueExtractor issueExtractor = injector.getInstance(IssueExtractor.class);
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
replayMocks();
@@ -171,6 +194,7 @@
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
replayMocks();
@@ -188,6 +212,7 @@
public void testIssueIdsCommitSingleIssue() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -215,6 +240,7 @@
public void testIssueIdsCommitMultipleIssues() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -243,6 +269,7 @@
public void testIssueIdsCommitMultipleIssuesMultipleTimes() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -271,6 +298,7 @@
public void testIssueIdsCommitSingleIssueBody() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -301,6 +329,7 @@
public void testIssueIdsCommitSingleIssueFooter() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -332,6 +361,7 @@
public void testIssueIdsCommitMultipleIssuesFooter() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -372,6 +402,7 @@
public void testIssueIdsCommitDifferentParts() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -406,6 +437,7 @@
public void testIssueIdsCommitDifferentPartsEmptySubject() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -439,6 +471,7 @@
public void testIssueIdsCommitDifferentPartsLinePastFooter() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -473,6 +506,7 @@
public void testIssueIdsCommitDifferentPartsLinesPastFooter() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -508,6 +542,7 @@
public void testIssueIdsCommitDifferentPartsNoFooter() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -535,6 +570,7 @@
public void testIssueIdsCommitDifferentPartsNoFooterTrailingLine() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -562,6 +598,7 @@
public void testIssueIdsCommitDifferentPartsNoFooterTrailingLines() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -590,6 +627,7 @@
public void testIssueIdsCommitEmpty() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn("");
@@ -611,6 +649,7 @@
public void testIssueIdsCommitBlankLine() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn("\n");
@@ -630,6 +669,7 @@
public void testIssueIdsCommitBlankLines() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn("\n\n");
@@ -649,6 +689,7 @@
public void testIssueIdsCommitMoreBlankLines() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn("\n\n\n");
@@ -668,6 +709,7 @@
public void testIssueIdsCommitMixed() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn(
@@ -708,6 +750,7 @@
public void testIssueIdsCommitWAddedEmptyFirst() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
expect(commitMessageFetcher.fetchGuarded("testProject",
"1234567891123456789212345678931234567894")).andReturn("");
@@ -730,6 +773,7 @@
public void testIssueIdsCommitWAddedSingleSubjectIssueFirst() {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
Change.Id changeId = createMock(Change.Id.class);
@@ -766,6 +810,7 @@
throws OrmException {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
Change.Id changeId = createMock(Change.Id.class);
@@ -828,6 +873,7 @@
throws OrmException {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
Change.Id changeId = createMock(Change.Id.class);
@@ -889,6 +935,7 @@
throws OrmException {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
Change.Id changeId = createMock(Change.Id.class);
@@ -951,6 +998,7 @@
throws OrmException {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
Change.Id changeId = createMock(Change.Id.class);
@@ -1015,6 +1063,7 @@
throws OrmException {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
Change.Id changeId = createMock(Change.Id.class);
@@ -1083,6 +1132,7 @@
throws OrmException {
expect(itsConfig.getIssuePattern()).andReturn(Pattern.compile("bug#(\\d+)"))
.atLeastOnce();
+ expect(itsConfig.getIssuePatternGroupIndex()).andReturn(1).atLeastOnce();
Change.Id changeId = createMock(Change.Id.class);