From 86d08c6a202954c171385a45d4193b2f52bcd8ca Mon Sep 17 00:00:00 2001 From: Sebastian Lieberknecht Date: Wed, 27 Feb 2019 22:36:53 -0800 Subject: [PATCH 1/9] Fixing lightweight pull request checkouts with files in subdirectories --- .../filesystem/BitbucketSCMFile.java | 48 ++++++++++++++----- .../filesystem/BitbucketSCMFileSystem.java | 26 ++++------ .../client/BitbucketServerAPIClient.java | 2 +- 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java index 06634e77f..7136adf10 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java @@ -24,40 +24,61 @@ package com.cloudbees.jenkins.plugins.bitbucket.filesystem; +import com.cloudbees.jenkins.plugins.bitbucket.BranchSCMHead; +import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; +import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMHead; +import java.util.Map; + import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; import java.io.InputStream; import jenkins.scm.api.SCMFile; +import jenkins.scm.api.SCMHead; +import jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy; public class BitbucketSCMFile extends SCMFile { private final BitbucketApi api; - private String ref; + private SCMHead head; private final String hash; public String getRef() { - return ref; - } + if (head instanceof BranchSCMHead) { + return head.getName(); + } + if (head instanceof PullRequestSCMHead) { + // working on a pull request - can be either "HEAD" or "MERGE" + PullRequestSCMHead pr = (PullRequestSCMHead) head; + if (pr.getRepository() == null) { // not clear when this happens + return null; + } + + // else build the bitbucket API compatible ref spec: + if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD) { + return "pull-requests/" + pr.getId() + "/from"; + } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) { + return "pull-requests/" + pr.getId() + "/merge"; + } + } + return null; - public void setRef(String ref) { - this.ref = ref; } @Deprecated public BitbucketSCMFile(BitbucketSCMFileSystem bitBucketSCMFileSystem, BitbucketApi api, - String ref) { - this(bitBucketSCMFileSystem, api, ref, null); + SCMHead head) { + this(bitBucketSCMFileSystem, api, head, null); } public BitbucketSCMFile(BitbucketSCMFileSystem bitBucketSCMFileSystem, BitbucketApi api, - String ref, String hash) { + SCMHead head, String hash) { super(); type(Type.DIRECTORY); this.api = api; - this.ref = ref; + this.head = head; this.hash = hash; } @@ -69,7 +90,7 @@ public BitbucketSCMFile(@NonNull BitbucketSCMFile parent, String name, Type type public BitbucketSCMFile(@NonNull BitbucketSCMFile parent, String name, Type type, String hash) { super(parent, name); this.api = parent.api; - this.ref = parent.ref; + this.head = parent.head; this.hash = hash; type(type); } @@ -94,8 +115,13 @@ public Iterable children() throws IOException, public InputStream content() throws IOException, InterruptedException { if (this.isDirectory()) { throw new IOException("Cannot get raw content from a directory"); - } else { + } + try { return api.getFileContent(this); + } catch (IOException e) + { + // TODO: Disable light-weight fallback to full checkout on merge conflicts + throw e; } } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java index a69bf0ab3..4799cb2a3 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java @@ -56,12 +56,12 @@ public class BitbucketSCMFileSystem extends SCMFileSystem { - private final String ref; + private final SCMHead head; private final BitbucketApi api; - protected BitbucketSCMFileSystem(BitbucketApi api, String ref, SCMRevision rev) throws IOException { + protected BitbucketSCMFileSystem(BitbucketApi api, SCMHead head, SCMRevision rev) throws IOException { super(rev); - this.ref = ref; + this.head = head; this.api = api; } @@ -80,7 +80,7 @@ public long lastModified() throws IOException { @Override public SCMFile getRoot() { SCMRevision revision = getRevision(); - return new BitbucketSCMFile(this, api, ref, revision == null ? null : revision.toString()); + return new BitbucketSCMFile(this, api, head, revision == null ? null : revision.toString()); } @Extension @@ -139,22 +139,12 @@ public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head, @Ch BitbucketAuthenticator authenticator = AuthenticationTokens.convert(BitbucketAuthenticator.authenticationContext(serverUrl), credentials); BitbucketApi apiClient = BitbucketApiFactory.newInstance(serverUrl, authenticator, owner, repository); - String ref; - if (head instanceof BranchSCMHead) { - ref = head.getName(); - } else if (head instanceof PullRequestSCMHead) { - PullRequestSCMHead pr = (PullRequestSCMHead) head; - if (!(pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) && pr.getRepository() != null) { - return new BitbucketSCMFileSystem(apiClient, pr.getOriginName(), rev); - } - return null; // TODO support merge revisions somehow - } else if (head instanceof BitbucketTagSCMHead) { - ref = "tags/" + head.getName(); - } else { - return null; + + if ((!(head instanceof BranchSCMHead) && !(head instanceof PullRequestSCMHead))) { + return null; // not supported branch head } - return new BitbucketSCMFileSystem(apiClient, ref, rev); + return new BitbucketSCMFileSystem(apiClient, head, rev); } } } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java index bc4299f93..1687229eb 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java @@ -147,7 +147,7 @@ public BitbucketCommit call() throws Exception { private static final String API_PULL_REQUESTS_PATH = API_REPOSITORY_PATH + "/pull-requests{?start,limit,at,direction,state}"; private static final String API_PULL_REQUEST_PATH = API_REPOSITORY_PATH + "/pull-requests/{id}"; private static final String API_PULL_REQUEST_MERGE_PATH = API_REPOSITORY_PATH + "/pull-requests/{id}/merge"; - private static final String API_BROWSE_PATH = API_REPOSITORY_PATH + "/browse{/path*}{?at}"; + private static final String API_BROWSE_PATH = API_REPOSITORY_PATH + "/browse{/path*}?at={+at}"; private static final String API_COMMITS_PATH = API_REPOSITORY_PATH + "/commits{/hash}"; private static final String API_PROJECT_PATH = API_BASE_PATH + "/projects/{owner}"; private static final String API_COMMIT_COMMENT_PATH = API_REPOSITORY_PATH + "/commits{/hash}/comments"; From 449f881540ffcc0d05e1cf56fc250513a1fe9f5b Mon Sep 17 00:00:00 2001 From: Sebastian Lieberknecht Date: Thu, 28 Feb 2019 20:58:53 -0800 Subject: [PATCH 2/9] optimized imports to address Checkstyle errors --- .../bitbucket/filesystem/BitbucketSCMFile.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java index 7136adf10..9ecd1bc54 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java @@ -25,19 +25,17 @@ package com.cloudbees.jenkins.plugins.bitbucket.filesystem; import com.cloudbees.jenkins.plugins.bitbucket.BranchSCMHead; -import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMHead; -import java.util.Map; - import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.IOException; -import java.io.InputStream; import jenkins.scm.api.SCMFile; import jenkins.scm.api.SCMHead; import jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy; -public class BitbucketSCMFile extends SCMFile { +import java.io.IOException; +import java.io.InputStream; + +public class BitbucketSCMFile extends SCMFile { private final BitbucketApi api; private SCMHead head; @@ -118,8 +116,7 @@ public InputStream content() throws IOException, InterruptedException { } try { return api.getFileContent(this); - } catch (IOException e) - { + } catch (IOException e) { // TODO: Disable light-weight fallback to full checkout on merge conflicts throw e; } @@ -134,7 +131,7 @@ public long lastModified() throws IOException, InterruptedException { @Override @NonNull protected SCMFile newChild(String name, boolean assumeIsDirectory) { - return new BitbucketSCMFile(this, name, assumeIsDirectory?Type.DIRECTORY:Type.REGULAR_FILE, hash); + return new BitbucketSCMFile(this, name, assumeIsDirectory ? Type.DIRECTORY : Type.REGULAR_FILE, hash); } @Override From 9a5bbca11a376cac6b50c69485e6a6804c424785 Mon Sep 17 00:00:00 2001 From: Sebastian Lieberknecht Date: Thu, 28 Feb 2019 21:58:26 -0800 Subject: [PATCH 3/9] Reverted "optimized imports to address Checkstyle errors" This reverts commit 83075a2f72546b88d686bf6153671dd6fd014acb. --- .../bitbucket/filesystem/BitbucketSCMFile.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java index 9ecd1bc54..7136adf10 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java @@ -25,17 +25,19 @@ package com.cloudbees.jenkins.plugins.bitbucket.filesystem; import com.cloudbees.jenkins.plugins.bitbucket.BranchSCMHead; +import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMHead; +import java.util.Map; + import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; import edu.umd.cs.findbugs.annotations.NonNull; +import java.io.IOException; +import java.io.InputStream; import jenkins.scm.api.SCMFile; import jenkins.scm.api.SCMHead; import jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy; -import java.io.IOException; -import java.io.InputStream; - -public class BitbucketSCMFile extends SCMFile { +public class BitbucketSCMFile extends SCMFile { private final BitbucketApi api; private SCMHead head; @@ -116,7 +118,8 @@ public InputStream content() throws IOException, InterruptedException { } try { return api.getFileContent(this); - } catch (IOException e) { + } catch (IOException e) + { // TODO: Disable light-weight fallback to full checkout on merge conflicts throw e; } @@ -131,7 +134,7 @@ public long lastModified() throws IOException, InterruptedException { @Override @NonNull protected SCMFile newChild(String name, boolean assumeIsDirectory) { - return new BitbucketSCMFile(this, name, assumeIsDirectory ? Type.DIRECTORY : Type.REGULAR_FILE, hash); + return new BitbucketSCMFile(this, name, assumeIsDirectory?Type.DIRECTORY:Type.REGULAR_FILE, hash); } @Override From 13a2d6a05a3038e5bc957d14c2d4654af8697e1d Mon Sep 17 00:00:00 2001 From: Sebastian Lieberknecht Date: Thu, 28 Feb 2019 22:52:12 -0800 Subject: [PATCH 4/9] Pulled up ref determination into old place as suggested by casz --- .../filesystem/BitbucketSCMFile.java | 48 +++++-------------- .../filesystem/BitbucketSCMFileSystem.java | 41 +++++++++++++--- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java index 7136adf10..06634e77f 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFile.java @@ -24,61 +24,40 @@ package com.cloudbees.jenkins.plugins.bitbucket.filesystem; -import com.cloudbees.jenkins.plugins.bitbucket.BranchSCMHead; -import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; -import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMHead; -import java.util.Map; - import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; import java.io.InputStream; import jenkins.scm.api.SCMFile; -import jenkins.scm.api.SCMHead; -import jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy; public class BitbucketSCMFile extends SCMFile { private final BitbucketApi api; - private SCMHead head; + private String ref; private final String hash; public String getRef() { - if (head instanceof BranchSCMHead) { - return head.getName(); - } - if (head instanceof PullRequestSCMHead) { - // working on a pull request - can be either "HEAD" or "MERGE" - PullRequestSCMHead pr = (PullRequestSCMHead) head; - if (pr.getRepository() == null) { // not clear when this happens - return null; - } - - // else build the bitbucket API compatible ref spec: - if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD) { - return "pull-requests/" + pr.getId() + "/from"; - } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) { - return "pull-requests/" + pr.getId() + "/merge"; - } - } - return null; + return ref; + } + public void setRef(String ref) { + this.ref = ref; } @Deprecated public BitbucketSCMFile(BitbucketSCMFileSystem bitBucketSCMFileSystem, BitbucketApi api, - SCMHead head) { - this(bitBucketSCMFileSystem, api, head, null); + String ref) { + this(bitBucketSCMFileSystem, api, ref, null); } public BitbucketSCMFile(BitbucketSCMFileSystem bitBucketSCMFileSystem, BitbucketApi api, - SCMHead head, String hash) { + String ref, String hash) { super(); type(Type.DIRECTORY); this.api = api; - this.head = head; + this.ref = ref; this.hash = hash; } @@ -90,7 +69,7 @@ public BitbucketSCMFile(@NonNull BitbucketSCMFile parent, String name, Type type public BitbucketSCMFile(@NonNull BitbucketSCMFile parent, String name, Type type, String hash) { super(parent, name); this.api = parent.api; - this.head = parent.head; + this.ref = parent.ref; this.hash = hash; type(type); } @@ -115,13 +94,8 @@ public Iterable children() throws IOException, public InputStream content() throws IOException, InterruptedException { if (this.isDirectory()) { throw new IOException("Cannot get raw content from a directory"); - } - try { + } else { return api.getFileContent(this); - } catch (IOException e) - { - // TODO: Disable light-weight fallback to full checkout on merge conflicts - throw e; } } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java index 4799cb2a3..ef0735cb0 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java @@ -32,6 +32,7 @@ import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApiFactory; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator; +import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudApiClient; import com.cloudbees.plugins.credentials.CredentialsMatchers; import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.common.StandardCredentials; @@ -56,12 +57,12 @@ public class BitbucketSCMFileSystem extends SCMFileSystem { - private final SCMHead head; + private final String ref; private final BitbucketApi api; - protected BitbucketSCMFileSystem(BitbucketApi api, SCMHead head, SCMRevision rev) throws IOException { + protected BitbucketSCMFileSystem(BitbucketApi api, String ref, SCMRevision rev) throws IOException { super(rev); - this.head = head; + this.ref = ref; this.api = api; } @@ -80,7 +81,7 @@ public long lastModified() throws IOException { @Override public SCMFile getRoot() { SCMRevision revision = getRevision(); - return new BitbucketSCMFile(this, api, head, revision == null ? null : revision.toString()); + return new BitbucketSCMFile(this, api, ref, revision == null ? null : revision.toString()); } @Extension @@ -139,12 +140,38 @@ public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head, @Ch BitbucketAuthenticator authenticator = AuthenticationTokens.convert(BitbucketAuthenticator.authenticationContext(serverUrl), credentials); BitbucketApi apiClient = BitbucketApiFactory.newInstance(serverUrl, authenticator, owner, repository); + String ref = null; - if ((!(head instanceof BranchSCMHead) && !(head instanceof PullRequestSCMHead))) { - return null; // not supported branch head + if (head instanceof BranchSCMHead) { + ref = head.getName(); + } + if (head instanceof PullRequestSCMHead) { + // working on a pull request - can be either "HEAD" or "MERGE" + PullRequestSCMHead pr = (PullRequestSCMHead) head; + if (pr.getRepository() == null) { // not clear when this happens + return null; + } + + if (apiClient instanceof BitbucketCloudApiClient) { + if (pr.getCheckoutStrategy() != ChangeRequestCheckoutStrategy.MERGE) { + return new BitbucketSCMFileSystem(apiClient, pr.getOriginName(), rev); + } + return null; // TODO support merge revisions somehow for cloud + + } + // else build the bitbucket API compatible ref spec: + if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD) { + ref = "pull-requests/" + pr.getId() + "/from"; + } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) { + ref = "pull-requests/" + pr.getId() + "/merge"; + } + } else if (head instanceof BitbucketTagSCMHead) { + ref = "tags/" + head.getName(); + } else { + return null; } - return new BitbucketSCMFileSystem(apiClient, head, rev); + return new BitbucketSCMFileSystem(apiClient, ref, rev); } } } From 5062669c190d763e35cd8a86ccb8d7956d9c1555 Mon Sep 17 00:00:00 2001 From: Joseph Petersen Date: Sat, 6 Apr 2019 23:51:21 +0200 Subject: [PATCH 5/9] fix browse path endpoint --- .../client/BitbucketServerAPIClient.java | 3 +- .../client/BitbucketServerAPIClientTest.java | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClientTest.java diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java index 1687229eb..24ac5f5b1 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java @@ -57,6 +57,7 @@ import com.damnhandy.uri.template.UriTemplate; import com.damnhandy.uri.template.impl.Operator; import com.fasterxml.jackson.core.type.TypeReference; +import com.google.common.annotations.VisibleForTesting; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ProxyConfiguration; @@ -147,7 +148,7 @@ public BitbucketCommit call() throws Exception { private static final String API_PULL_REQUESTS_PATH = API_REPOSITORY_PATH + "/pull-requests{?start,limit,at,direction,state}"; private static final String API_PULL_REQUEST_PATH = API_REPOSITORY_PATH + "/pull-requests/{id}"; private static final String API_PULL_REQUEST_MERGE_PATH = API_REPOSITORY_PATH + "/pull-requests/{id}/merge"; - private static final String API_BROWSE_PATH = API_REPOSITORY_PATH + "/browse{/path*}?at={+at}"; + static final String API_BROWSE_PATH = API_REPOSITORY_PATH + "/browse/{+path}{?at}"; private static final String API_COMMITS_PATH = API_REPOSITORY_PATH + "/commits{/hash}"; private static final String API_PROJECT_PATH = API_BASE_PATH + "/projects/{owner}"; private static final String API_COMMIT_COMMENT_PATH = API_REPOSITORY_PATH + "/commits{/hash}/comments"; diff --git a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClientTest.java b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClientTest.java new file mode 100644 index 000000000..979e42ef5 --- /dev/null +++ b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClientTest.java @@ -0,0 +1,34 @@ +package com.cloudbees.jenkins.plugins.bitbucket.server.client; + +import com.damnhandy.uri.template.UriTemplate; +import org.junit.Assert; +import org.junit.Test; + +import static com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerAPIClient.API_BROWSE_PATH; + +public class BitbucketServerAPIClientTest { + + @Test + public void repoBrowsePathFolder() { + String expand = UriTemplate + .fromTemplate(API_BROWSE_PATH) + .set("owner", "test") + .set("repo", "test") + .set("path", "folder/Jenkinsfile") + .set("at", "fix/test") + .expand(); + Assert.assertEquals("/rest/api/1.0/projects/test/repos/test/browse/folder/Jenkinsfile?at=fix%2Ftest", expand); + } + + @Test + public void repoBrowsePathFile() { + String expand = UriTemplate + .fromTemplate(API_BROWSE_PATH) + .set("owner", "test") + .set("repo", "test") + .set("path", "Jenkinsfile") + .expand(); + Assert.assertEquals("/rest/api/1.0/projects/test/repos/test/browse/Jenkinsfile", expand); + } + +} From cacc5e753ebaac70d9e2750fe291429a9717f49b Mon Sep 17 00:00:00 2001 From: Joseph Petersen Date: Sun, 7 Apr 2019 00:02:46 +0200 Subject: [PATCH 6/9] CR additions --- .../filesystem/BitbucketSCMFileSystem.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java index ef0735cb0..1a59cd315 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java @@ -144,23 +144,22 @@ public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head, @Ch if (head instanceof BranchSCMHead) { ref = head.getName(); - } - if (head instanceof PullRequestSCMHead) { + } else if (head instanceof PullRequestSCMHead) { // working on a pull request - can be either "HEAD" or "MERGE" PullRequestSCMHead pr = (PullRequestSCMHead) head; - if (pr.getRepository() == null) { // not clear when this happens + if (pr.getRepository() == null) { // check access to repository (forked with no access) return null; } if (apiClient instanceof BitbucketCloudApiClient) { - if (pr.getCheckoutStrategy() != ChangeRequestCheckoutStrategy.MERGE) { - return new BitbucketSCMFileSystem(apiClient, pr.getOriginName(), rev); + // Bitbucket cloud does not support refs for pull requests + // TODO waiting for cloud support: https://bitbucket.org/site/master/issues/5814/refify-pull-requests-by-making-them-a-ref + if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) { + return null; + } else { + ref = pr.getOriginName(); } - return null; // TODO support merge revisions somehow for cloud - - } - // else build the bitbucket API compatible ref spec: - if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD) { + } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD) { ref = "pull-requests/" + pr.getId() + "/from"; } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) { ref = "pull-requests/" + pr.getId() + "/merge"; From 52b803a93f740aedf98e7a64705bf8691b11142b Mon Sep 17 00:00:00 2001 From: Joseph Petersen Date: Sun, 7 Apr 2019 00:06:40 +0200 Subject: [PATCH 7/9] unused import --- .../bitbucket/server/client/BitbucketServerAPIClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java index 24ac5f5b1..d05a838d2 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java @@ -57,7 +57,6 @@ import com.damnhandy.uri.template.UriTemplate; import com.damnhandy.uri.template.impl.Operator; import com.fasterxml.jackson.core.type.TypeReference; -import com.google.common.annotations.VisibleForTesting; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ProxyConfiguration; From 9563965b574cab13b83913480bf50e7479526bf6 Mon Sep 17 00:00:00 2001 From: Joseph Petersen Date: Sun, 7 Apr 2019 00:12:27 +0200 Subject: [PATCH 8/9] clear logic --- .../plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java index 1a59cd315..49902627a 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java @@ -147,7 +147,7 @@ public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head, @Ch } else if (head instanceof PullRequestSCMHead) { // working on a pull request - can be either "HEAD" or "MERGE" PullRequestSCMHead pr = (PullRequestSCMHead) head; - if (pr.getRepository() == null) { // check access to repository (forked with no access) + if (pr.getRepository() == null) { // check access to repository (might be forked) return null; } @@ -156,7 +156,7 @@ public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head, @Ch // TODO waiting for cloud support: https://bitbucket.org/site/master/issues/5814/refify-pull-requests-by-making-them-a-ref if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) { return null; - } else { + } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD) { ref = pr.getOriginName(); } } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD) { From 776900172e482690f6a787d7af28e10097cc5d35 Mon Sep 17 00:00:00 2001 From: Joseph Petersen Date: Sun, 7 Apr 2019 01:13:28 +0200 Subject: [PATCH 9/9] support lightweight checkout on same repo in bitbucket cloud --- .../filesystem/BitbucketSCMFileSystem.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java index 49902627a..e9d3df97f 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java @@ -152,12 +152,16 @@ public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head, @Ch } if (apiClient instanceof BitbucketCloudApiClient) { - // Bitbucket cloud does not support refs for pull requests - // TODO waiting for cloud support: https://bitbucket.org/site/master/issues/5814/refify-pull-requests-by-making-them-a-ref - if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) { - return null; - } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD) { + // support lightweight checkout for branches with same owner and repository + if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD && + pr.getRepoOwner().equals(src.getRepoOwner()) && + pr.getRepository().equals(src.getRepository())) { ref = pr.getOriginName(); + } else { + // Bitbucket cloud does not support refs for pull requests + // Makes lightweight checkout for forks and merge strategy improbable + // TODO waiting for cloud support: https://bitbucket.org/site/master/issues/5814/refify-pull-requests-by-making-them-a-ref + return null; } } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD) { ref = "pull-requests/" + pr.getId() + "/from";