diff --git a/docs/src/main/asciidoc/_additional-stubrunner-configprops.adoc b/docs/src/main/asciidoc/_additional-stubrunner-configprops.adoc index f929e6b0d8..6fed50c24b 100644 --- a/docs/src/main/asciidoc/_additional-stubrunner-configprops.adoc +++ b/docs/src/main/asciidoc/_additional-stubrunner-configprops.adoc @@ -12,6 +12,7 @@ IMPORTANT: The following properties can be passed as a system property (for exam |`stubrunner.properties.git.username` | | When using the SCM-based approach, you can pass the username to connect to the git repository. |`stubrunner.properties.git.password` | | When using the SCM-based approach, you can pass the password to connect to the git repository. |`stubrunner.properties.git.wait-between-attempts` | `1000` | When using the SCM-based approach, you can customize waiting time in ms between attempts to push the stubs to git. +|`stubrunner.properties.git.ensure-git-suffix` | `true` | When using the SCM based approach, you can prevent stubrunner from adding `.git` to the repository URL by setting this property to `false`. This adds compatibility with git repositories which do not support such URLs, for example Azure DevOps. |`stubrunner.properties.stubs.find-producer` | `false` | When using the `stubs` protocol, you can toggle this flag to search for contracts in the `group id / artifact id` instead of taking the stubs directly from the provided folder. diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/GitRepo.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/GitRepo.java index 55e9a7593f..2483de1327 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/GitRepo.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/GitRepo.java @@ -77,9 +77,12 @@ class GitRepo { private final File basedir; + private final boolean ensureGitSuffix; + GitRepo(File basedir, GitStubDownloaderProperties properties) { this.basedir = basedir; this.gitFactory = new JGitFactory(properties); + this.ensureGitSuffix = properties.ensureGitSuffix; } // for tests @@ -87,6 +90,15 @@ class GitRepo { GitRepo(File basedir) { this.basedir = basedir; this.gitFactory = new JGitFactory(); + this.ensureGitSuffix = true; + } + + // for tests + @Deprecated + GitRepo(File basedir, boolean ensureGitSuffix) { + this.basedir = basedir; + this.gitFactory = new JGitFactory(); + this.ensureGitSuffix = ensureGitSuffix; } // for tests @@ -94,6 +106,7 @@ class GitRepo { GitRepo(File basedir, JGitFactory factory) { this.basedir = basedir; this.gitFactory = factory; + this.ensureGitSuffix = true; } /** @@ -203,8 +216,7 @@ class GitRepo { } private Git cloneToBasedir(URI projectUrl, File destinationFolder) { - String url = projectUrl.toString(); - String projectGitUrl = url.endsWith(".git") ? url : url + ".git"; + String projectGitUrl = sanitizeGitUrl(projectUrl); if (log.isDebugEnabled()) { log.debug("Project git url [" + projectGitUrl + "]"); } @@ -226,6 +238,12 @@ class GitRepo { } } + protected String sanitizeGitUrl(URI uri) { + String urlString = uri.toString(); + return (urlString.endsWith(".git") || !this.ensureGitSuffix) ? urlString + : urlString + ".git"; + } + private Ref checkoutBranch(File projectDir, String branch) throws GitAPIException { Git git = this.gitFactory.open(projectDir); CheckoutCommand command = git.checkout().setName(branch); diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ScmStubDownloaderBuilder.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ScmStubDownloaderBuilder.java index 73a7ad3a8b..7893774188 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ScmStubDownloaderBuilder.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ScmStubDownloaderBuilder.java @@ -219,6 +219,8 @@ class GitStubDownloaderProperties { private static final String GIT_PASSWORD_PROPERTY = "git.password"; + private static final String GIT_ENSURE_GIT_SUFFIX_PROPERTY = "git.ensure-git-suffix"; + final URI url; final String username; @@ -227,6 +229,8 @@ class GitStubDownloaderProperties { final String branch; + final Boolean ensureGitSuffix; + GitStubDownloaderProperties(Resource repo, StubRunnerOptions options) { String repoUrl; Map args = options.getProperties(); @@ -247,9 +251,16 @@ class GitStubDownloaderProperties { this.password = StringUtils.hasText(password) ? password : options.getPassword(); String branch = StubRunnerPropertyUtils.getProperty(args, GIT_BRANCH_PROPERTY); this.branch = StringUtils.hasText(branch) ? branch : "master"; + String ensureGitSuffix = StubRunnerPropertyUtils.getProperty(args, + GIT_ENSURE_GIT_SUFFIX_PROPERTY); + this.ensureGitSuffix = StringUtils.hasText(ensureGitSuffix) + ? Boolean.parseBoolean(ensureGitSuffix) : true; + if (log.isDebugEnabled()) { - log.debug("Repo url is [" + repoUrl + "], modified url string " + "is [" + modifiedRepo + "] URL is [" - + this.url + "] and " + "branch is [" + this.branch + "]"); + log.debug("Repo url is [" + repoUrl + "], modified url string " + "is [" + + modifiedRepo + "] URL is [" + this.url + "] branch is [" + + this.branch + "] and ensureGitSuffix is [" + this.ensureGitSuffix + + "]"); } } diff --git a/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitRepoTests.java b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitRepoTests.java index 0fbfdd7080..34edef8835 100644 --- a/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitRepoTests.java +++ b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitRepoTests.java @@ -18,6 +18,7 @@ package org.springframework.cloud.contract.stubrunner; import java.io.File; import java.io.IOException; +import java.net.URI; import java.net.URISyntaxException; import org.eclipse.jgit.api.CloneCommand; @@ -26,6 +27,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.junit.Before; import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; import static org.assertj.core.api.BDDAssertions.then; import static org.assertj.core.api.BDDAssertions.thenThrownBy; @@ -159,6 +161,34 @@ public class GitRepoTests extends AbstractGitTest { } } + @Test + public void should_add_git_suffix_to_url_if_not_present() throws Exception { + this.gitRepo = new GitRepo(this.tmpFolder, true); + String url = this.gitRepo.sanitizeGitUrl(new URI("git://example.com/repo")); + assertThat(url).isEqualTo("git://example.com/repo.git"); + } + + @Test + public void should_not_add_git_suffix_to_url_if_already_present() throws Exception { + this.gitRepo = new GitRepo(this.tmpFolder, true); + String url = this.gitRepo.sanitizeGitUrl(new URI("git://example.com/repo.git")); + assertThat(url).isEqualTo("git://example.com/repo.git"); + } + + @Test + public void should_not_add_git_suffix_to_url_if_disabled() throws Exception { + this.gitRepo = new GitRepo(this.tmpFolder, false); + String url = this.gitRepo.sanitizeGitUrl(new URI("git://example.com/repo")); + assertThat(url).isEqualTo("git://example.com/repo"); + } + + @Test + public void should_not_remove_git_suffix_from_url_if_disabled() throws Exception { + this.gitRepo = new GitRepo(this.tmpFolder, false); + String url = this.gitRepo.sanitizeGitUrl(new URI("git://example.com/repo.git")); + assertThat(url).isEqualTo("git://example.com/repo.git"); + } + } class ExceptionThrowingJGitFactory extends GitRepo.JGitFactory {