diff options
Diffstat (limited to 'src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java')
-rw-r--r-- | src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java | 127 |
1 files changed, 100 insertions, 27 deletions
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index c71cc99..6736ee9 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -9,11 +9,15 @@ import java.util.logging.Logger; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.ApiClient; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.BuildState; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.Pullrequest; +import java.util.LinkedList; import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; import jenkins.model.Jenkins; import jenkins.scm.api.SCMSource; +import jenkins.scm.api.SCMSourceOwner; +import jenkins.scm.api.SCMSourceOwners; +import org.apache.commons.lang.StringUtils; /** * Created by nishio @@ -22,7 +26,9 @@ public class BitbucketRepository { private static final Logger logger = Logger.getLogger(BitbucketRepository.class.getName()); private static final String BUILD_DESCRIPTION = "%s: %s into %s"; private static final String BUILD_REQUEST_MARKER = "test this please"; - private static final String BUILD_REQUEST_MARKER_COUNTER_RX = "\\[(\\d+)]\\"; + private static final String BUILD_REQUEST_DONE_MARKER = "ttp build flag"; + private static final String BUILD_REQUEST_MARKER_TAG_SINGLE_RX = "\\#[\\w\\-\\d]+"; + private static final String BUILD_REQUEST_MARKER_TAGS_RX = "\\[bid\\:\\s?(.*)\\]"; private String projectPath; private BitbucketPullRequestsBuilder builder; @@ -35,15 +41,19 @@ public class BitbucketRepository { } public void init() { - trigger = this.builder.getTrigger(); - client = new ApiClient( + this.init(null); + } + + public void init(ApiClient client) { + this.trigger = this.builder.getTrigger(); + this.client = (client == null) ? new ApiClient( trigger.getUsername(), trigger.getPassword(), trigger.getRepositoryOwner(), trigger.getRepositoryName(), trigger.getCiKey(), trigger.getCiName() - ); + ) : client; } public Collection<Pullrequest> getTargetPullRequests() { @@ -102,10 +112,68 @@ public class BitbucketRepository { public void postPullRequestApproval(String pullRequestId) { this.client.postPullRequestApproval(pullRequestId); } - - private Integer extractRebuildTimesFromComment(String content) { - Matcher matcher = Pattern.compile(BUILD_REQUEST_MARKER_COUNTER_RX).matcher(content); - return matcher.groupCount() >= 1 ? Integer.parseInt(matcher.group(1)) : 0; + + 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]```"; + + private List<String> getAvailableBuildTagsFromTTPComment(String buildTags) { + logger.log(Level.INFO, "Parse {0}", new Object[]{ buildTags }); + 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()) { + logger.log(Level.INFO, "Content {0} g[1]:{1} mykey:{2}", new Object[] { content, tagsMatcher.group(1).trim(), this.getMyBuildTag(buildKey) }); + return this.getAvailableBuildTagsFromTTPComment(tagsMatcher.group(1).trim()).contains(this.getMyBuildTag(buildKey)); + } + else return false; + } + + 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)); + 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 processTTPCommentBuildTags(String content, String buildKey) { + if (!this.isTTPCommentBuildTags(content)) return true; + logger.log(Level.INFO, "Processing ttp with build comment: {0}", content); + return !this.hasMyBuildTagInTTPComment(content, buildKey); + } + + private boolean isTTPComment(String content) { + return content.toLowerCase().contains(BUILD_REQUEST_MARKER.toLowerCase()); + } + + 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>(); + 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 (isTTP || isTTPBuild) filteredComments.add(comment); + if (isTTP) break; + } + return filteredComments; } private boolean isBuildTarget(Pullrequest pullRequest) { @@ -121,41 +189,40 @@ public class BitbucketRepository { String repositoryName = destination.getRepository().getRepositoryName(); Pullrequest.Repository sourceRepository = source.getRepository(); + String buildKeyPart = this.builder.getProjectId(); - boolean commitAlreadyBeenProcessed = this.client.hasBuildStatus( - sourceRepository.getOwnerName(), sourceRepository.getRepositoryName(), sourceCommit, this.builder.getProjectId() + 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", - new Object[]{ sourceCommit, this.builder.getProjectId() } + new Object[]{ sourceCommit, buildKeyPart } ); - String id = pullRequest.getId(); + final String id = pullRequest.getId(); List<Pullrequest.Comment> comments = client.getPullRequestComments(owner, repositoryName, id); boolean rebuildCommentAvailable = false; if (comments != null) { - Collections.sort(comments); - Collections.reverse(comments); - for (Pullrequest.Comment comment : comments) { + Collection<Pullrequest.Comment> filteredComments = this.filterPullRequestComments(comments); + for (Pullrequest.Comment comment : filteredComments) { String content = comment.getContent(); - if (content == null || content.isEmpty()) { - continue; - } - - if (content.contains(BUILD_REQUEST_MARKER.toLowerCase())) { + if (this.isTTPComment(content)) { rebuildCommentAvailable = true; logger.log(Level.INFO, "Rebuild comment available for commit {0} and comment #{1}", new Object[]{ sourceCommit, comment.getId() } - ); - this.client.deleteComment(id, Integer.toString(comment.getId())); - } + ); + } + rebuildCommentAvailable &= this.processTTPCommentBuildTags(content, buildKeyPart); + if (!rebuildCommentAvailable) break; } - } + } + if (rebuildCommentAvailable) this.postBuildTagInTTPComment(id, "TTP build flag", buildKeyPart); - logger.log(Level.INFO, "Build target? {0}", rebuildCommentAvailable || !commitAlreadyBeenProcessed); - return rebuildCommentAvailable || !commitAlreadyBeenProcessed; + final boolean canBuildTarget = rebuildCommentAvailable || !commitAlreadyBeenProcessed; + logger.log(Level.INFO, "Build target? {0} [rebuild:{1} processed:{2}]", new Object[]{ canBuildTarget, rebuildCommentAvailable, commitAlreadyBeenProcessed}); + return canBuildTarget; } return false; @@ -188,9 +255,15 @@ public class BitbucketRepository { pullRequest.getDestination().getCommit().getHash() ); + //@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(Jenkins.getInstance().getExtensionList(SCMSource.class), this.trigger.getBranchesFilter()); + BitbucketBuildFilter.InstanceBySCM(sources, this.trigger.getBranchesFilter()); return filter.approved(cause); } |