From adae31914e22b4f8ddc6f15839533b19cc661b6e Mon Sep 17 00:00:00 2001 From: Budlee Date: Sat, 20 Jun 2020 16:23:32 +0100 Subject: [PATCH] Windows file path fix#1374 (#1402) * Fix for file resolving for Windows * #1374 Better way to fix issue with file format in FileStubDownloader * #1374 Remove unused imports * #1374 forgot to add tests for change * Add more windows fixes * Checkstyle fixes gh-1374 Checkstyle fixes gh-1374 * Checkstyle fixes gh-1374 * gh-1374 pr fix * gh-1374 pr fixes * gh-1374 checkstyle changes * missed off return from statement * missed off return from statement * Remove the FileUtils * Remove the FileUtils --- README.adoc | 2 +- .../stubrunner/ContractDownloader.java | 5 +- .../stubrunner/FileStubDownloader.java | 24 ++++++++-- .../cloud/contract/stubrunner/GitRepo.java | 15 +++--- .../AetherStubDownloaderSpec.groovy | 2 +- .../stubrunner/FileStubDownloaderTests.java | 46 +++++++++++++++++++ .../stubrunner/GitStubDownloaderTests.java | 41 +++++++++-------- 7 files changed, 98 insertions(+), 37 deletions(-) create mode 100644 spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/FileStubDownloaderTests.java diff --git a/README.adoc b/README.adoc index ff772e6a54..4412bca9da 100644 --- a/README.adoc +++ b/README.adoc @@ -287,7 +287,7 @@ run the following command: ./scripts/parallelBuild.sh ``` -To use eight 8 cores, run thke following command: +To use eight 8 cores, run the following command: ``` CORES=8 ./scripts/parallelBuild.sh diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java index 579bbd4b97..98c8749861 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java @@ -193,9 +193,8 @@ public class ContractDownloader { } private String wrapWithAntPattern(String path) { - String changedPath = path.replace(File.separator, "/"); - return "**" + surroundWithSeparator(changedPath).replace(File.separator, "/") - + "**/"; + String changedPath = surroundWithSeparator(path).replace(File.separator, "/"); + return "**" + changedPath.replace(File.separator, "/") + "**/"; } private String groupArtifactToPattern(File contractsDirectory) { diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/FileStubDownloader.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/FileStubDownloader.java index 43f8258b90..de70d30188 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/FileStubDownloader.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/FileStubDownloader.java @@ -20,7 +20,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URI; -import java.nio.file.Paths; import java.util.Collections; import java.util.List; import java.util.Map; @@ -76,7 +75,26 @@ public class FileStubDownloader implements StubDownloaderBuilder { if (StringUtils.isEmpty(location) || !isProtocolAccepted(location)) { return null; } - return new StubsResource(location); + // Can be resolving a resource for Classpath as fallback + if (!location.startsWith("stubs://file://")) { + return new StubsResource(location); + } + // Convert any windows file format path to a uri + String correctlyFormattedLocation = convertLocationToUriFormat(location); + return new StubsResource(correctlyFormattedLocation); + } + + private String convertLocationToUriFormat(String location) { + final String correctlyFormattedLocation = separatorsToUnix(location); + final String rawPath = correctlyFormattedLocation.replace("stubs://file://", ""); + if (rawPath.charAt(0) != '/') { + return "stubs://file:///" + rawPath; + } + return correctlyFormattedLocation; + } + + private String separatorsToUnix(String location) { + return location != null && location.indexOf(92) != -1 ? location.replace('\\', '/') : location; } } @@ -161,7 +179,7 @@ class StubsStubDownloader implements StubDownloader { Resource resource = ResourceResolver.resource(schemeSpecificPart); if (resource != null) { try { - return Paths.get(resource.getURI()).toString(); + return resource.getURL().getFile(); } catch (IOException ex) { return schemeSpecificPart; 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 5859660cd3..3ad1496eb4 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 @@ -55,10 +55,10 @@ import org.eclipse.jgit.transport.SshTransport; import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; import org.eclipse.jgit.util.FS; -import org.eclipse.jgit.util.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.util.FileSystemUtils; import org.springframework.util.ResourceUtils; /** @@ -221,7 +221,7 @@ class GitRepo { return git; } catch (GitAPIException | URISyntaxException e) { - deleteBaseDirIfExists(); + deleteBaseDirIfExists("Failed to initialize base directory"); throw new IllegalStateException(e); } } @@ -236,7 +236,7 @@ class GitRepo { return command.call(); } catch (GitAPIException e) { - deleteBaseDirIfExists(); + deleteBaseDirIfExists("Failed to delete base directory"); throw e; } finally { @@ -290,13 +290,10 @@ class GitRepo { return false; } - private void deleteBaseDirIfExists() { + private void deleteBaseDirIfExists(String errorMessage) { if (this.basedir.exists()) { - try { - FileUtils.delete(this.basedir, FileUtils.RECURSIVE); - } - catch (IOException e) { - throw new IllegalStateException("Failed to initialize base directory", e); + if (!FileSystemUtils.deleteRecursively(this.basedir)) { + throw new IllegalStateException(errorMessage); } } } diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy index e5742e8c96..b6d33f1b66 100644 --- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy +++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy @@ -58,7 +58,7 @@ class AetherStubDownloaderSpec extends Specification { and: String localRepo = AetherFactories.localRepositoryDirectory(true) new File(localRepo, "org/springframework/cloud/spring-cloud-contract-spec" - .replaceAll("/", File.separator)).list().size() > 0 + .replace("/", File.separator)).list().size() > 0 and: AetherStubDownloader aetherStubDownloader = new AetherStubDownloader(stubRunnerOptions) diff --git a/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/FileStubDownloaderTests.java b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/FileStubDownloaderTests.java new file mode 100644 index 0000000000..2281d2b730 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/FileStubDownloaderTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner; + +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import org.springframework.core.io.Resource; + +/** + * @author Matty A + */ +public class FileStubDownloaderTests { + + @Test + public void resolve() { + final FileStubDownloader fileStubDownloader = new FileStubDownloader(); + Resource expectedUnixResource = new StubsResource("stubs://file:///User/A/B/C"); + Resource expectedWindowsResource = new StubsResource( + "stubs://file:///C:/Users/A/B/C"); + String unixFileFormat = "stubs://file:///User/A/B/C"; + String windowsFileFormat = "stubs://file://C:\\Users\\A\\B\\C"; + String windowsFileFormatCorrectPathStart = "stubs://file:///C:\\Users\\A\\B\\C"; + Assertions.assertThat(expectedUnixResource) + .isEqualTo(fileStubDownloader.resolve(unixFileFormat, null)); + Assertions.assertThat(expectedWindowsResource) + .isEqualTo(fileStubDownloader.resolve(windowsFileFormat, null)); + Assertions.assertThat(expectedWindowsResource).isEqualTo( + fileStubDownloader.resolve(windowsFileFormatCorrectPathStart, null)); + } + +} diff --git a/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitStubDownloaderTests.java b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitStubDownloaderTests.java index 3ff11da5f8..3171f82d57 100644 --- a/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitStubDownloaderTests.java +++ b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitStubDownloaderTests.java @@ -86,12 +86,12 @@ public class GitStubDownloaderTests { public void should_pick_stubs_for_group_and_artifact_with_version_from_a_git_repo() throws Exception { StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + String contractFolderLocation = (file("/git_samples/contract-git/") + .getAbsolutePath() + "/").replace(File.separator, "/"); StubDownloader stubDownloader = stubDownloaderBuilder .build(new StubRunnerOptionsBuilder() .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("git://" - + file("/git_samples/contract-git/").getAbsolutePath() - + "/") + .withStubRepositoryRoot("git://" + contractFolderLocation) .withProperties(props()).build()); Map.Entry entry = stubDownloader @@ -107,12 +107,12 @@ public class GitStubDownloaderTests { public void should_pick_latest_build_snapshot_stubs_when_latest_version_set() throws URISyntaxException { StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + String contractFolderLocation = (file("/git_samples/contract-git/") + .getAbsolutePath() + "/").replace(File.separator, "/"); StubDownloader stubDownloader = stubDownloaderBuilder .build(new StubRunnerOptionsBuilder() .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("git://" - + file("/git_samples/contract-git/").getAbsolutePath() - + "/") + .withStubRepositoryRoot("git://" + contractFolderLocation) .withProperties(props()).build()); Map.Entry entry = stubDownloader @@ -149,12 +149,12 @@ public class GitStubDownloaderTests { public void should_pick_latest_release_stubs_when_release_version_set() throws URISyntaxException { StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + String contractFolderLocation = (file("/git_samples/contract-git/") + .getAbsolutePath() + "/").replace(File.separator, "/"); StubDownloader stubDownloader = stubDownloaderBuilder .build(new StubRunnerOptionsBuilder() .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("git://" - + file("/git_samples/contract-git/").getAbsolutePath() - + "/") + .withStubRepositoryRoot("git://" + contractFolderLocation) .withProperties(props()).build()); Map.Entry entry = stubDownloader @@ -177,13 +177,14 @@ public class GitStubDownloaderTests { public void should_pick_latest_build_snapshot_stubs_when_latest_version_set_and_latest_folder_exists() throws URISyntaxException { StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + String contractFolderLocation = (file( + "/git_samples/contract-predefined-names-git/").getAbsolutePath() + .replace("/", File.separator) + + "/").replace(File.separator, "/"); StubDownloader stubDownloader = stubDownloaderBuilder .build(new StubRunnerOptionsBuilder() .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("git://" - + file("/git_samples/contract-predefined-names-git/") - .getAbsolutePath() - + "/") + .withStubRepositoryRoot("git://" + contractFolderLocation) .withProperties(props()).build()); Map.Entry entry = stubDownloader @@ -213,13 +214,13 @@ public class GitStubDownloaderTests { public void should_pick_release_folder_when_release_version_set() throws URISyntaxException { StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + String contractFolderLocation = (file( + "/git_samples/contract-predefined-names-git/").getAbsolutePath() + "/") + .replace(File.separator, "/"); StubDownloader stubDownloader = stubDownloaderBuilder .build(new StubRunnerOptionsBuilder() .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("git://" - + file("/git_samples/contract-predefined-names-git/") - .getAbsolutePath() - + "/") + .withStubRepositoryRoot("git://" + contractFolderLocation) .withProperties(props()).build()); Map.Entry entry = stubDownloader @@ -242,12 +243,12 @@ public class GitStubDownloaderTests { public void should_fail_to_fetch_stubs_when_concrete_version_was_not_specified() throws URISyntaxException { StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + String contractFolderLocation = (file("/git_samples/contract-git/") + .getAbsolutePath() + "/").replace(File.separator, "/"); StubDownloader stubDownloader = stubDownloaderBuilder .build(new StubRunnerOptionsBuilder() .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("git://" - + file("/git_samples/contract-git").getAbsolutePath() - + "/") + .withStubRepositoryRoot("git://" + contractFolderLocation) .withProperties(props()).build()); try {