diff options
Diffstat (limited to 'src/main')
7 files changed, 109 insertions, 59 deletions
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java index d4173a2..7754106 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java @@ -1,6 +1,5 @@ package bitbucketpullrequestbuilder.bitbucketpullrequestbuilder; -import hudson.model.Action; import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.ArrayList; @@ -114,7 +113,7 @@ 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 { + static 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); @@ -204,30 +203,30 @@ public class BitbucketBuildFilter { return this.currFilter.apply(this.filter, cause); } - public static BitbucketBuildFilter InstanceByString(String filter) { + public static BitbucketBuildFilter instanceByString(String filter) { logger.log(Level.INFO, "Filter instance by filter string"); return new BitbucketBuildFilter(filter); } - static public String FilterFromGitSCMSource(AbstractGitSCMSource gitscm, String defaultFilter) { + static public String filterFromGitSCMSource(AbstractGitSCMSource gitscm, String defaultFilter) { if (gitscm == null) { logger.log(Level.INFO, "Git SCMSource unavailable. Using default value: {0}", defaultFilter); return defaultFilter; } - String filter = defaultFilter; + StringBuffer filter = new StringBuffer(defaultFilter); final String includes = gitscm.getIncludes(); if (includes != null && !includes.isEmpty()) { for(String part : includes.split("\\s+")) { - filter += String.format("%s ", part.replaceAll("\\*\\/", "d:")); + filter.append(String.format("%s ", part.replaceAll("\\*\\/", "d:"))); } } logger.log(Level.INFO, "Git includes transformation to filter result: {1} -> {0}; default: {2}", new Object[]{ filter, includes, defaultFilter }); - return filter.trim(); + return filter.toString().trim(); } - public static BitbucketBuildFilter InstanceBySCM(Collection<SCMSource> scmSources, String defaultFilter) { + public static BitbucketBuildFilter instanceBySCM(Collection<SCMSource> scmSources, String defaultFilter) { logger.log(Level.INFO, "Filter instance by using SCMSources list with {0} items", scmSources.size()); AbstractGitSCMSource gitscm = null; for(SCMSource scm : scmSources) { @@ -237,6 +236,6 @@ public class BitbucketBuildFilter { break; } } - return new BitbucketBuildFilter(FilterFromGitSCMSource(gitscm, defaultFilter)); + return new BitbucketBuildFilter(filterFromGitSCMSource(gitscm, defaultFilter)); } } diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java index 34e12b2..6b03e44 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java @@ -211,7 +211,7 @@ public class BitbucketBuildTrigger extends Trigger<Job<?, ?>> { private void cancelPreviousJobsInQueueThatMatch(@Nonnull BitbucketCause bitbucketCause) { logger.fine("Looking for queued jobs that match PR ID: " + bitbucketCause.getPullRequestId()); - Queue queue = Jenkins.getInstance().getQueue(); + Queue queue = getInstance().getQueue(); for (Queue.Item item : queue.getItems()) { if (hasCauseFromTheSamePullRequest(item.getCauses(), bitbucketCause)) { logger.info("Canceling item in queue: " + item); @@ -220,6 +220,14 @@ public class BitbucketBuildTrigger extends Trigger<Job<?, ?>> { } } + private Jenkins getInstance() { + final Jenkins instance = Jenkins.getInstance(); + if (instance == null){ + throw new IllegalStateException("Jenkins instance is NULL!"); + } + return instance; + } + private void abortRunningJobsThatMatch(@Nonnull BitbucketCause bitbucketCause) { logger.fine("Looking for running jobs that match PR ID: " + bitbucketCause.getPullRequestId()); for (Object o : job.getBuilds()) { @@ -227,7 +235,11 @@ public class BitbucketBuildTrigger extends Trigger<Job<?, ?>> { Build build = (Build) o; if (build.isBuilding() && hasCauseFromTheSamePullRequest(build.getCauses(), bitbucketCause)) { logger.info("Aborting build: " + build + " since PR is outdated"); - build.getExecutor().interrupt(Result.ABORTED); + final Executor executor = build.getExecutor(); + if (executor == null){ + throw new IllegalStateException("Executor can't be NULL"); + } + executor.interrupt(Result.ABORTED); } } } diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index 01da88e..02d11c5 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -47,7 +47,7 @@ public class BitbucketRepository { private BitbucketPullRequestsBuilder builder; private BitbucketBuildTrigger trigger; private ApiClient client; - + public BitbucketRepository(String projectPath, BitbucketPullRequestsBuilder builder) { this.projectPath = projectPath; this.builder = builder; @@ -56,26 +56,26 @@ public class BitbucketRepository { public void init() { this.init(null, null); } - + public <T extends ApiClient.HttpClientFactory> void init(T httpFactory) { this.init(null, httpFactory); } - + public void init(ApiClient client) { this.init(client, null); } - + public <T extends ApiClient.HttpClientFactory> void init(ApiClient client, T httpFactory) { this.trigger = this.builder.getTrigger(); - - if (client == null) { + + if (client == null) { String username = trigger.getUsername(); - String password = trigger.getPassword(); + String password = trigger.getPassword(); StandardUsernamePasswordCredentials credentials = getCredentials(trigger.getCredentialsId()); if (credentials != null) { username = credentials.getUsername(); password = credentials.getPassword().getPlainText(); - } + } this.client = new ApiClient( username, password, @@ -85,7 +85,7 @@ public class BitbucketRepository { trigger.getCiName(), httpFactory ); - + } else this.client = client; } @@ -100,7 +100,7 @@ public class BitbucketRepository { } return targetPullRequests; } - + public ApiClient getClient() { return this.client; } @@ -123,11 +123,20 @@ public class BitbucketRepository { pullRequest.getDestination().getCommit().getHash(), pullRequest.getAuthor().getCombinedUsername() ); - setBuildStatus(cause, BuildState.INPROGRESS, Jenkins.getInstance().getRootUrl()); + setBuildStatus(cause, BuildState.INPROGRESS, getInstance().getRootUrl()); this.builder.getTrigger().startJob(cause); } } + private Jenkins getInstance() { + final Jenkins instance = Jenkins.getInstance(); + if (instance == null){ + throw new IllegalStateException("Jenkins instance is NULL!"); + } + return instance; + } + + public void setBuildStatus(BitbucketCause cause, BuildState state, String buildUrl) { String comment = null; String sourceCommit = cause.getSourceCommitHash(); @@ -151,23 +160,23 @@ public class BitbucketRepository { public void postPullRequestApproval(String pullRequestId) { this.client.postPullRequestApproval(pullRequestId); } - + public String getMyBuildTag(String buildKey) { return "#" + this.client.buildStatusKey(buildKey); - } - + } + final static Pattern BUILD_TAGS_RX = Pattern.compile(BUILD_REQUEST_MARKER_TAGS_RX, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ); - final static Pattern SINGLE_BUILD_TAG_RX = Pattern.compile(BUILD_REQUEST_MARKER_TAG_SINGLE_RX, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ); - final static String CONTENT_PART_TEMPLATE = "```[bid: %s]```"; - + final static Pattern SINGLE_BUILD_TAG_RX = Pattern.compile(BUILD_REQUEST_MARKER_TAG_SINGLE_RX, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ); + final static String CONTENT_PART_TEMPLATE = "```[bid: %s]```"; + private List<String> getAvailableBuildTagsFromTTPComment(String buildTags) { logger.log(Level.INFO, "Parse {0}", new Object[]{ buildTags }); - List<String> availableBuildTags = new LinkedList<String>(); + List<String> availableBuildTags = new LinkedList<String>(); Matcher subBuildTagMatcher = SINGLE_BUILD_TAG_RX.matcher(buildTags); while(subBuildTagMatcher.find()) availableBuildTags.add(subBuildTagMatcher.group(0).trim()); return availableBuildTags; } - + public boolean hasMyBuildTagInTTPComment(String content, String buildKey) { Matcher tagsMatcher = BUILD_TAGS_RX.matcher(content); if (tagsMatcher.find()) { @@ -175,16 +184,16 @@ public class BitbucketRepository { return this.getAvailableBuildTagsFromTTPComment(tagsMatcher.group(1).trim()).contains(this.getMyBuildTag(buildKey)); } else return false; - } - - private void postBuildTagInTTPComment(String pullRequestId, String content, String buildKey) { + } + + private void postBuildTagInTTPComment(String pullRequestId, String content, String buildKey) { logger.log(Level.INFO, "Update build tag for {0} build key", buildKey); List<String> builds = this.getAvailableBuildTagsFromTTPComment(content); - builds.add(this.getMyBuildTag(buildKey)); + builds.add(this.getMyBuildTag(buildKey)); content += " " + String.format(CONTENT_PART_TEMPLATE, StringUtils.join(builds, " ")); logger.log(Level.INFO, "Post comment: {0} with original content {1}", new Object[]{ content, this.client.postPullRequestComment(pullRequestId, content).getId() }); } - + private boolean isTTPComment(String content) { // special case: in unit tests, trigger is null and can't be mocked String commentTrigger = DEFAULT_COMMENT_TRIGGER; @@ -193,27 +202,27 @@ public class BitbucketRepository { } return content.toLowerCase().contains(commentTrigger); } - + private boolean isTTPCommentBuildTags(String content) { return content.toLowerCase().contains(BUILD_REQUEST_DONE_MARKER.toLowerCase()); } - + public List<Pullrequest.Comment> filterPullRequestComments(List<Pullrequest.Comment> comments) { logger.info("Filter PullRequest Comments."); Collections.sort(comments); - Collections.reverse(comments); - List<Pullrequest.Comment> filteredComments = new LinkedList<Pullrequest.Comment>(); + Collections.reverse(comments); + List<Pullrequest.Comment> filteredComments = new LinkedList<Pullrequest.Comment>(); for(Pullrequest.Comment comment : comments) { String content = comment.getContent(); - if (content == null || content.isEmpty()) continue; - boolean isTTP = this.isTTPComment(content); - boolean isTTPBuild = this.isTTPCommentBuildTags(content); + if (content == null || content.isEmpty()) continue; + boolean isTTP = this.isTTPComment(content); + boolean isTTPBuild = this.isTTPCommentBuildTags(content); if (isTTP || isTTPBuild) filteredComments.add(comment); if (isTTP) break; } return filteredComments; } - + private boolean isBuildTarget(Pullrequest pullRequest) { if (pullRequest.getState() != null && pullRequest.getState().equals("OPEN")) { if (isSkipBuild(pullRequest.getTitle()) || !isFilteredBuild(pullRequest)) { @@ -232,8 +241,8 @@ public class BitbucketRepository { final boolean commitAlreadyBeenProcessed = this.client.hasBuildStatus( sourceRepository.getOwnerName(), sourceRepository.getRepositoryName(), sourceCommit, buildKeyPart ); - if (commitAlreadyBeenProcessed) logger.log(Level.INFO, - "Commit {0}#{1} has already been processed", + if (commitAlreadyBeenProcessed) logger.log(Level.INFO, + "Commit {0}#{1} has already been processed", new Object[]{ sourceCommit, buildKeyPart } ); @@ -246,18 +255,18 @@ public class BitbucketRepository { boolean hasMyBuildTag = false; for (Pullrequest.Comment comment : filteredComments) { String content = comment.getContent(); - if (this.isTTPComment(content)) { + if (this.isTTPComment(content)) { rebuildCommentAvailable = true; - logger.log(Level.INFO, - "Rebuild comment available for commit {0} and comment #{1}", + logger.log(Level.INFO, + "Rebuild comment available for commit {0} and comment #{1}", new Object[]{ sourceCommit, comment.getId() } - ); + ); } if (isTTPCommentBuildTags(content)) hasMyBuildTag |= this.hasMyBuildTagInTTPComment(content, buildKeyPart); } rebuildCommentAvailable &= !hasMyBuildTag; - } + } if (rebuildCommentAvailable) this.postBuildTagInTTPComment(id, "TTP build flag", buildKeyPart); final boolean canBuildTarget = rebuildCommentAvailable || !commitAlreadyBeenProcessed; @@ -295,17 +304,17 @@ public class BitbucketRepository { pullRequest.getDestination().getCommit().getHash(), pullRequest.getAuthor().getCombinedUsername() ); - + //@FIXME: Way to iterate over all available SCMSources List<SCMSource> sources = new LinkedList<SCMSource>(); for(SCMSourceOwner owner : SCMSourceOwners.all()) for(SCMSource src : owner.getSCMSources()) - sources.add(src); - - BitbucketBuildFilter filter = !this.trigger.getBranchesFilterBySCMIncludes() ? - BitbucketBuildFilter.InstanceByString(this.trigger.getBranchesFilter()) : - BitbucketBuildFilter.InstanceBySCM(sources, this.trigger.getBranchesFilter()); - + sources.add(src); + + BitbucketBuildFilter filter = !this.trigger.getBranchesFilterBySCMIncludes() ? + BitbucketBuildFilter.instanceByString(this.trigger.getBranchesFilter()) : + BitbucketBuildFilter.instanceBySCM(sources, this.trigger.getBranchesFilter()); + return filter.approved(cause); } diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java index 0c87478..7ab69c4 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java @@ -58,7 +58,7 @@ public class ApiClient { if (Jenkins.getInstance() == null) return client; - ProxyConfiguration proxy = Jenkins.getInstance().proxy; + ProxyConfiguration proxy = getInstance().proxy; if (proxy == null) return client; logger.log(Level.INFO, "Jenkins proxy: {0}:{1}", new Object[]{ proxy.name, proxy.port }); @@ -75,7 +75,17 @@ public class ApiClient { return client; } + + private Jenkins getInstance() { + final Jenkins instance = Jenkins.getInstance(); + if (instance == null){ + throw new IllegalStateException("Jenkins instance is NULL!"); + } + return instance; + } } + + public <T extends HttpClientFactory> ApiClient( String username, String password, diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java index 25755a4..5cf1fa7 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java @@ -189,8 +189,11 @@ public class Pullrequest { private String updatedOn; private String createdOn; + @Override public int compareTo(Comment target) { - if (this.getId() > target.getId()) { + if (target == null){ + return -1; + } else if (this.getId() > target.getId()) { return 1; } else if (this.getId().equals(target.getId())) { return 0; @@ -199,6 +202,21 @@ public class Pullrequest { } } + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Comment comment = (Comment) o; + + return getId() != null ? getId().equals(comment.getId()) : comment.getId() == null; + } + + @Override + public int hashCode() { + return getId() != null ? getId().hashCode() : 0; + } + @JsonProperty("comment_id") public Integer getId() { return id; diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly index 97e5d5c..1d7c4e4 100644 --- a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly +++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly @@ -1,3 +1,4 @@ +<?jelly escape-by-default='true'?> <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:c="/lib/credentials"> <f:entry title="Cron" field="cron"> <f:textbox /> diff --git a/src/main/resources/index.jelly b/src/main/resources/index.jelly index 0404451..372d9f8 100644 --- a/src/main/resources/index.jelly +++ b/src/main/resources/index.jelly @@ -1,3 +1,4 @@ +<?jelly escape-by-default='true'?> <!-- This view is used to render the installed plugins page. --> |