aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxim Epishchev <epishev@garant.ru>2016-04-19 16:58:43 +0300
committerMaxim Epishchev <epishev@garant.ru>2016-04-20 13:54:29 +0300
commitade4a1a1e2fdfac7180cadebd574ffe5bdedd062 (patch)
tree573567f237cd68e1f36e2f9d51412c17fe833281 /src
parentf08fe64257973cddea7ca3ae837f5cfe3db7b720 (diff)
downloadbbprb-ade4a1a1e2fdfac7180cadebd574ffe5bdedd062.tar.gz
Available "pullRequestAuthor" env variable (featured from #83)
Env variable "pullRequestAuthor" contain two parts of author: full name of user and short username in format, like: "Some Doo <@somedoo>". Add test for PR build filter: now we can filter also by author: "a:maxvodo" by example.
Diffstat (limited to 'src')
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java86
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java3
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketCause.java9
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java7
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java36
-rw-r--r--src/test/java/BitbucketBuildFilterTest.java20
6 files changed, 144 insertions, 17 deletions
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java
index c251930..d4173a2 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java
@@ -1,5 +1,6 @@
package bitbucketpullrequestbuilder.bitbucketpullrequestbuilder;
+import hudson.model.Action;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.ArrayList;
@@ -29,6 +30,7 @@ abstract class Filter {
public static final String SRC_RX = "s:(" + RX_FILTER_FLAG_SINGLE + ")?";
public static final String DST_RX = "d:(" + RX_FILTER_FLAG_SINGLE + ")?";
+ public static final String AUTHOR_RX = "a:(" + RX_FILTER_FLAG_SINGLE + ")?";
public static final String BRANCH_FILTER_RX_PART = "([^\\s$]*)";
abstract public boolean apply(String filter, BitbucketCause cause);
@@ -36,6 +38,20 @@ abstract class Filter {
static final Pattern RX_SRC_DST_PARTS = Pattern.compile("(s:)|(d:)");
public static boolean HasSourceOrDestPartsPredicate(String filter) { return RX_SRC_DST_PARTS.matcher(filter).find(); }
+
+ static final Pattern RX_AUTHOR_PARTS = Pattern.compile("(a:)");
+ public static boolean HasAuthorPartsPredicate(String filter) { return RX_AUTHOR_PARTS.matcher(filter).find(); }
+
+ protected boolean applyByRx(Pattern rx, Filter usedFilter, String filter, BitbucketCause cause) {
+ Matcher srcMatch = rx.matcher(filter);
+ boolean apply = false;
+ while (srcMatch.find()) {
+ String computedFilter = ((srcMatch.group(1) == null ? "" : srcMatch.group(1)) + srcMatch.group(2)).trim();
+ logger.log(Level.INFO, "Apply computed filter: {0}", computedFilter);
+ apply = apply || (computedFilter.isEmpty() ? true : usedFilter.apply(computedFilter, cause));
+ }
+ return apply;
+ }
}
class EmptyFilter extends Filter {
@@ -84,17 +100,6 @@ class SourceDestFlag extends Filter {
static final Pattern SRC_MATCHER_RX = Pattern.compile(SRC_RX + BRANCH_FILTER_RX_PART, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ);
static final Pattern DST_MATCHER_RX = Pattern.compile(DST_RX + BRANCH_FILTER_RX_PART, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ);
- boolean applyByRx(Pattern rx, Filter usedFilter, String filter, BitbucketCause cause) {
- Matcher srcMatch = rx.matcher(filter);
- boolean apply = rx.matcher(filter).matches();
- while (srcMatch.find()) {
- String computedFilter = ((srcMatch.group(1) == null ? "" : srcMatch.group(1)) + srcMatch.group(2)).trim();
- logger.log(Level.INFO, "Apply computed filter: {0}", computedFilter);
- apply = apply || (computedFilter.isEmpty() ? true : usedFilter.apply(computedFilter, cause));
- }
- return apply;
- }
-
@Override
public boolean apply(String filter, BitbucketCause cause) {
return this.applyByRx(SRC_MATCHER_RX, new OnlySourceFlag(), filter, cause) &&
@@ -106,6 +111,54 @@ class SourceDestFlag extends Filter {
}
}
+class AuthorFlag extends Filter {
+ static final Pattern AUTHOR_MATCHER_RX = Pattern.compile(AUTHOR_RX + BRANCH_FILTER_RX_PART, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ);
+
+ class AuthorFlagImpl extends Filter {
+ @Override
+ public boolean apply(String filter, BitbucketCause cause) {
+ String selectedRx = filter.startsWith(RX_FILTER_FLAG_SINGLE) ? filter.substring(RX_FILTER_FLAG_SINGLE.length()) : Pattern.quote(filter);
+ logger.log(Level.INFO, "AuthorFlagImpl using filter: {0}", selectedRx);
+ Matcher matcher = Pattern.compile(selectedRx, Pattern.CASE_INSENSITIVE).matcher(cause.getPullRequestAuthor());
+ return filter.startsWith(RX_FILTER_FLAG_SINGLE) ? matcher.find() : matcher.matches();
+ }
+ @Override
+ public boolean check(String filter) { return false; }
+ }
+
+ @Override
+ public boolean apply(String filter, BitbucketCause cause) {
+ return this.applyByRx(AUTHOR_MATCHER_RX, new AuthorFlagImpl(), filter, cause);
+ }
+ @Override
+ public boolean check(String filter) {
+ return HasAuthorPartsPredicate(filter);
+ }
+}
+
+class CombinedFlags extends Filter {
+ private final Filter[] _filters;
+ public CombinedFlags(Filter[] filters) {
+ _filters = filters;
+ }
+
+ @Override
+ public boolean apply(String filter, BitbucketCause cause) {
+ boolean applied = true;
+ for(Filter f: _filters)
+ if (f.check(filter))
+ applied = applied && f.apply(filter, cause);
+ return applied;
+ }
+ @Override
+ public boolean check(String filter) {
+ for(Filter f: _filters)
+ if (f.check(filter))
+ return true;
+ return false;
+ }
+}
+
/**
* Created by maxvodo
*/
@@ -118,10 +171,15 @@ public class BitbucketBuildFilter {
static {
ArrayList<Filter> filters = new ArrayList<Filter>();
- filters.add(new AnyFlag());
+
+ filters.add(new AnyFlag());
+ filters.add(new CombinedFlags(new Filter[] {
+ new SourceDestFlag(),
+ new AuthorFlag()
+ }));
filters.add(new OnlyDestFlag());
- filters.add(new SourceDestFlag());
- filters.add(new EmptyFilter());
+ filters.add(new EmptyFilter());
+
AvailableFilters = filters;
}
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java
index 2375ec7..1120aca 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java
@@ -164,6 +164,7 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> {
public QueueTaskFuture<?> startJob(BitbucketCause cause) {
Map<String, ParameterValue> values = this.getDefaultParameters();
+
values.put("sourceBranch", new StringParameterValue("sourceBranch", cause.getSourceBranch()));
values.put("targetBranch", new StringParameterValue("targetBranch", cause.getTargetBranch()));
values.put("repositoryOwner", new StringParameterValue("repositoryOwner", cause.getRepositoryOwner()));
@@ -172,6 +173,8 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> {
values.put("destinationRepositoryOwner", new StringParameterValue("destinationRepositoryOwner", cause.getDestinationRepositoryOwner()));
values.put("destinationRepositoryName", new StringParameterValue("destinationRepositoryName", cause.getDestinationRepositoryName()));
values.put("pullRequestTitle", new StringParameterValue("pullRequestTitle", cause.getPullRequestTitle()));
+ values.put("pullRequestAuthor", new StringParameterValue("pullRequestAuthor", cause.getPullRequestAuthor()));
+
return this.job.scheduleBuild2(0, cause, new ParametersAction(new ArrayList(values.values())), new RevisionParameterAction(cause.getSourceCommitHash()));
}
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketCause.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketCause.java
index e233371..3cb107b 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketCause.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketCause.java
@@ -16,6 +16,7 @@ public class BitbucketCause extends Cause {
private final String pullRequestTitle;
private final String sourceCommitHash;
private final String destinationCommitHash;
+ private final String pullRequestAuthor;
public static final String BITBUCKET_URL = "https://bitbucket.org/";
public BitbucketCause(String sourceBranch,
@@ -27,7 +28,8 @@ public class BitbucketCause extends Cause {
String destinationRepositoryName,
String pullRequestTitle,
String sourceCommitHash,
- String destinationCommitHash) {
+ String destinationCommitHash,
+ String pullRequestAuthor) {
this.sourceBranch = sourceBranch;
this.targetBranch = targetBranch;
this.repositoryOwner = repositoryOwner;
@@ -38,6 +40,7 @@ public class BitbucketCause extends Cause {
this.pullRequestTitle = pullRequestTitle;
this.sourceCommitHash = sourceCommitHash;
this.destinationCommitHash = destinationCommitHash;
+ this.pullRequestAuthor = pullRequestAuthor;
}
public String getSourceBranch() {
@@ -83,4 +86,8 @@ public class BitbucketCause extends Cause {
description += "\">#" + this.getPullRequestId() + " " + this.getPullRequestTitle() + "</a>";
return description;
}
+
+ public String getPullRequestAuthor() {
+ return this.pullRequestAuthor;
+ }
}
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java
index 9b92775..4417d74 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java
@@ -117,7 +117,9 @@ public class BitbucketRepository {
pullRequest.getDestination().getRepository().getRepositoryName(),
pullRequest.getTitle(),
pullRequest.getSource().getCommit().getHash(),
- pullRequest.getDestination().getCommit().getHash());
+ pullRequest.getDestination().getCommit().getHash(),
+ pullRequest.getAuthor().getCombinedUsername()
+ );
setBuildStatus(cause, BuildState.INPROGRESS, Jenkins.getInstance().getRootUrl());
this.builder.getTrigger().startJob(cause);
}
@@ -286,7 +288,8 @@ public class BitbucketRepository {
pullRequest.getDestination().getRepository().getRepositoryName(),
pullRequest.getTitle(),
pullRequest.getSource().getCommit().getHash(),
- pullRequest.getDestination().getCommit().getHash()
+ pullRequest.getDestination().getCommit().getHash(),
+ pullRequest.getAuthor().getCombinedUsername()
);
//@FIXME: Way to iterate over all available SCMSources
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java
index 1e8bf5c..140c213 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java
@@ -28,6 +28,7 @@ public class Pullrequest {
private String updatedOn;
private String mergeCommit;
private String id;
+ private Author author;
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Response {
@@ -233,6 +234,33 @@ public class Pullrequest {
this.createdOn = createdOn;
}
}
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class Author {
+ private String username;
+ private String display_name;
+ public static final String COMBINED_NAME = "%s <@%s>";
+
+ public String getUsername() {
+ return username;
+ }
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ @JsonProperty("display_name")
+ public String getDisplayName() {
+ return display_name;
+ }
+
+ @JsonProperty("display_name")
+ public void setDisplayName(String display_name) {
+ this.display_name = display_name;
+ }
+ public String getCombinedUsername() {
+ return String.format(COMBINED_NAME, this.getDisplayName(), this.getUsername());
+ }
+ }
//-------------------- only getters and setters follow -----------------
@@ -341,5 +369,13 @@ public class Pullrequest {
public void setId(String id) {
this.id = id;
}
+
+ public Author getAuthor() {
+ return this.author;
+ }
+
+ public void setAutohor(Author author) {
+ this.author = author;
+ }
}
diff --git a/src/test/java/BitbucketBuildFilterTest.java b/src/test/java/BitbucketBuildFilterTest.java
index 3b35dbc..3a94c82 100644
--- a/src/test/java/BitbucketBuildFilterTest.java
+++ b/src/test/java/BitbucketBuildFilterTest.java
@@ -142,6 +142,26 @@ public class BitbucketBuildFilterTest {
@Test
@WithoutJenkins
+ public void authorFilter() {
+ BitbucketCause cause = EasyMock.createMock(BitbucketCause.class);
+ EasyMock.expect(cause.getTargetBranch()).andReturn("master").anyTimes();
+ EasyMock.expect(cause.getSourceBranch()).andReturn("feature-master").anyTimes();
+ EasyMock.expect(cause.getPullRequestAuthor()).andReturn("test").anyTimes();
+ EasyMock.replay(cause);
+
+ for(String f : new String[] {"a:test", "a:r:^test", "d: s: a:", "a:", "a:foo a:test"}) {
+ BitbucketBuildFilter filter = BitbucketBuildFilter.InstanceByString(f);
+ assertTrue(filter.approved(cause));
+ }
+
+ for(String f : new String[] {"s:feature-master", "d:master", "s:feature-master d: a:foo", "a:bar"}) {
+ BitbucketBuildFilter filter = BitbucketBuildFilter.InstanceByString(f);
+ assertFalse(filter.approved(cause));
+ }
+ }
+
+ @Test
+ @WithoutJenkins
public void emptyGitSCMFilter() {
BitbucketCause cause = EasyMock.createMock(BitbucketCause.class);
EasyMock.expect(cause.getTargetBranch()).andReturn("master").anyTimes();