diff --git a/integration-tests/src/test/java/org/wildfly/prospero/it/cli/InstallTest.java b/integration-tests/src/test/java/org/wildfly/prospero/it/cli/InstallTest.java index cf7737789..11ee8f66e 100644 --- a/integration-tests/src/test/java/org/wildfly/prospero/it/cli/InstallTest.java +++ b/integration-tests/src/test/java/org/wildfly/prospero/it/cli/InstallTest.java @@ -20,10 +20,10 @@ import java.io.File; import java.net.URL; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; import java.util.concurrent.TimeUnit; +import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Test; import org.wildfly.prospero.cli.ReturnCodes; @@ -69,14 +69,21 @@ public void testInstallWithLocalRepositories() throws Exception { final URL temporaryRepo = mockTemporaryRepo(true); - Path relativePath = Paths.get(System.getProperty("user.dir")).relativize(Path.of(temporaryRepo.toURI())); + final Path currentDirectory = Path.of(".").toAbsolutePath().normalize(); + final Path testRepository = currentDirectory.resolve("test-repository"); + final Path relativePath = currentDirectory.relativize(testRepository); + try { + FileUtils.copyDirectory(Path.of(temporaryRepo.toURI()).toFile(), testRepository.toFile()); - ExecutionUtils.prosperoExecution(CliConstants.Commands.UPDATE, CliConstants.Commands.PERFORM, - CliConstants.REPOSITORIES, relativePath.toString(), - CliConstants.Y, - CliConstants.VERBOSE, - CliConstants.DIR, targetDir.getAbsolutePath()) - .execute() - .assertReturnCode(ReturnCodes.SUCCESS); + ExecutionUtils.prosperoExecution(CliConstants.Commands.UPDATE, CliConstants.Commands.PERFORM, + CliConstants.REPOSITORIES, relativePath.toString(), + CliConstants.Y, + CliConstants.VERBOSE, + CliConstants.DIR, targetDir.getAbsolutePath()) + .execute() + .assertReturnCode(ReturnCodes.SUCCESS); + } finally { + FileUtils.deleteQuietly(testRepository.toFile()); + } } } diff --git a/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMessages.java b/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMessages.java index 276f079c7..9b5ce364a 100644 --- a/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMessages.java +++ b/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMessages.java @@ -420,8 +420,8 @@ default ArgumentParsingException invalidRepositoryDefinition(String repoKey) { return new ArgumentParsingException(format(bundle.getString("prospero.general.validation.repo_format"), repoKey)); } - default ArgumentParsingException invalidFilePath(String repoKey) { - return new ArgumentParsingException(format(bundle.getString("prospero.general.validation.file_path.not_exists"), repoKey)); + default ArgumentParsingException invalidFilePath(String invalidPath) { + return new ArgumentParsingException(format(bundle.getString("prospero.general.validation.file_path.not_exists"), invalidPath)); } default IllegalArgumentException updateCandidateStateNotMatched(Path targetDir, Path updateDir) { diff --git a/prospero-cli/src/main/java/org/wildfly/prospero/cli/RepositoryDefinition.java b/prospero-cli/src/main/java/org/wildfly/prospero/cli/RepositoryDefinition.java index 70a1f8045..858d23706 100644 --- a/prospero-cli/src/main/java/org/wildfly/prospero/cli/RepositoryDefinition.java +++ b/prospero-cli/src/main/java/org/wildfly/prospero/cli/RepositoryDefinition.java @@ -20,11 +20,12 @@ import org.jboss.logging.Logger; import org.wildfly.channel.Repository; -import java.io.File; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; @@ -34,32 +35,50 @@ public class RepositoryDefinition { private static final Logger logger = Logger.getLogger(RepositoryDefinition.class.getName()); public static List from(List repos) throws ArgumentParsingException { - ArrayList repositories = new ArrayList<>(repos.size()); + final ArrayList repositories = new ArrayList<>(repos.size()); for (int i = 0; i < repos.size(); i++) { - String repoInfo = repos.get(i); - if(repoInfo.contains("::")) { - final String[] parts = repoInfo.split("::"); - if (parts.length != 2 || parts[0].isEmpty() || parts[1].isEmpty() || !isValidUrl(parts[1])) { - throw CliMessages.MESSAGES.invalidRepositoryDefinition(repoInfo); - } - repositories.add(new Repository(parts[0], parts[1])); - } else { - if (!(repoInfo.startsWith("http://") || repoInfo.startsWith("https://")) && !repoInfo.isEmpty()) { - try { - repoInfo = getAbsoluteFileURI(repoInfo).toString(); - } catch (URISyntaxException e) { - logger.warn("An error occurred while processing URI"); + final String repoInfo = repos.get(i); + final String repoId; + final String repoUri; + + try { + if (repoInfo.contains("::")) { + final String[] parts = repoInfo.split("::"); + if (parts.length != 2 || parts[0].isEmpty() || parts[1].isEmpty()) { + throw CliMessages.MESSAGES.invalidRepositoryDefinition(repoInfo); } + repoId = parts[0]; + repoUri = parseRepositoryLocation(parts[1]); + } else { + repoId = "temp-repo-" + i; + repoUri = parseRepositoryLocation(repoInfo); } - if (!isValidUrl(repoInfo)){ - throw CliMessages.MESSAGES.invalidRepositoryDefinition(repoInfo); - } - repositories.add(new Repository("temp-repo-" + i, repoInfo)); + repositories.add(new Repository(repoId, repoUri)); + } catch (URISyntaxException e) { + logger.error("Unable to parse repository uri + " + repoInfo, e); + throw CliMessages.MESSAGES.invalidRepositoryDefinition(repoInfo); } + } return repositories; } + private static String parseRepositoryLocation(String repoLocation) throws URISyntaxException, ArgumentParsingException { + if (!isRemoteUrl(repoLocation) && !repoLocation.isEmpty()) { + // the repoLocation contains either a file URI or a path + // we need to convert it to a valid file IR + repoLocation = getAbsoluteFileURI(repoLocation).toString(); + } + if (!isValidUrl(repoLocation)){ + throw CliMessages.MESSAGES.invalidRepositoryDefinition(repoLocation); + } + return repoLocation; + } + + private static boolean isRemoteUrl(String repoInfo) { + return repoInfo.startsWith("http://") || repoInfo.startsWith("https://"); + } + private static boolean isValidUrl(String text) { try { new URL(text); @@ -70,24 +89,33 @@ private static boolean isValidUrl(String text) { } public static URI getAbsoluteFileURI(String repoInfo) throws ArgumentParsingException, URISyntaxException { - File file = new File(getPath(repoInfo)); - if (file.exists()) { - return file.toURI(); + final Path repoPath = getPath(repoInfo).toAbsolutePath().normalize(); + if (Files.exists(repoPath)) { + return repoPath.toUri(); } else { throw CliMessages.MESSAGES.invalidFilePath(repoInfo); } } - public static String getPath(String repoInfo) throws URISyntaxException { + public static Path getPath(String repoInfo) throws URISyntaxException, ArgumentParsingException { if (repoInfo.startsWith("file:")) { - URI inputUri = new URI(repoInfo); - if (inputUri.getScheme().equals("file") && - !inputUri.getSchemeSpecificPart().startsWith("/")) { - return Path.of(inputUri.getSchemeSpecificPart()).toAbsolutePath().normalize().toString(); + final URI inputUri = new URI(repoInfo); + if (containsAbsolutePath(inputUri)) { + return Path.of(inputUri); + } else { + return Path.of(inputUri.getSchemeSpecificPart()); } - return Path.of(inputUri).normalize().toFile().getAbsolutePath(); } else { - return Path.of(repoInfo).toAbsolutePath().normalize().toString(); + try { + return Path.of(repoInfo); + } catch (InvalidPathException e) { + throw CliMessages.MESSAGES.invalidFilePath(repoInfo); + } } } + + private static boolean containsAbsolutePath(URI inputUri) { + // absolute paths in URI (even on Windows) has to start with slash. If not we treat it as a relative path + return inputUri.getSchemeSpecificPart().startsWith("/"); + } } diff --git a/prospero-cli/src/test/java/org/wildfly/prospero/cli/RepositoryDefinitionTest.java b/prospero-cli/src/test/java/org/wildfly/prospero/cli/RepositoryDefinitionTest.java index 3f1c322ea..c94b49c58 100644 --- a/prospero-cli/src/test/java/org/wildfly/prospero/cli/RepositoryDefinitionTest.java +++ b/prospero-cli/src/test/java/org/wildfly/prospero/cli/RepositoryDefinitionTest.java @@ -34,11 +34,13 @@ public class RepositoryDefinitionTest { - private String tempRepoURL; + private String tempRepoUrlNoHostForm; + private String tempRepoUrlEmptyHostForm; @Before public void setUp() throws Exception { - tempRepoURL = Path.of(".").normalize().toAbsolutePath().toUri().toString().replace("///","/"); + tempRepoUrlEmptyHostForm = Path.of(".").normalize().toAbsolutePath().toUri().toString(); + tempRepoUrlNoHostForm = tempRepoUrlEmptyHostForm.replace("///","/"); } @Test @@ -89,23 +91,31 @@ public void throwsErrorIfFormatIsIncorrect() throws Exception { @Test public void throwsErrorIfFormatIsIncorrectForFileURLorPathDoesNotExist() throws Exception { - assertThrows(ArgumentParsingException.class, ()->from(List.of("::"+tempRepoURL))); + assertThrows(ArgumentParsingException.class, ()->from(List.of("::"+ tempRepoUrlNoHostForm))); assertThrows(ArgumentParsingException.class, ()->from(List.of("repo-1::"))); - assertThrows(ArgumentParsingException.class, ()->from(List.of("repo-1:::"+tempRepoURL))); + assertThrows(ArgumentParsingException.class, ()->from(List.of("repo-1:::"+ tempRepoUrlNoHostForm))); - assertThrows(ArgumentParsingException.class, ()->from(List.of("foo::bar::"+tempRepoURL))); + assertThrows(ArgumentParsingException.class, ()->from(List.of("foo::bar::"+ tempRepoUrlNoHostForm))); } @Test public void testCorrectRelativeOrAbsolutePathForFileURL() throws Exception { - Repository repository = new Repository("temp-repo-0", tempRepoURL); + Repository repository = new Repository("temp-repo-0", tempRepoUrlEmptyHostForm); List actualList = from(List.of("file:../prospero-cli")); assertNotNull(actualList); assertEquals(1, actualList.size()); - assertTrue(actualList.contains(repository)); + assertThat(actualList) + .contains(repository); + + actualList = from(List.of("temp-repo-0::file:../prospero-cli")); + + assertNotNull(actualList); + assertEquals(1, actualList.size()); + assertThat(actualList) + .contains(repository); actualList = from(List.of(("file:/"+(System.getProperty("user.dir").replaceAll("\\\\","/"))).replace("//","/"))); @@ -113,22 +123,46 @@ public void testCorrectRelativeOrAbsolutePathForFileURL() throws Exception { assertEquals(1, actualList.size()); assertTrue(actualList.contains(repository)); + actualList = from(List.of(("temp-repo-0::file:/"+(System.getProperty("user.dir").replaceAll("\\\\","/"))).replace("//","/"))); + + assertNotNull(actualList); + assertEquals(1, actualList.size()); + assertTrue(actualList.contains(repository)); + actualList = from(List.of(("file:///"+(System.getProperty("user.dir").replaceAll("\\\\","/"))).replace("////","///"))); assertNotNull(actualList); assertEquals(1, actualList.size()); assertTrue(actualList.contains(repository)); + actualList = from(List.of(("temp-repo-0::file:///"+(System.getProperty("user.dir").replaceAll("\\\\","/"))).replace("////","///"))); + + assertNotNull(actualList); + assertEquals(1, actualList.size()); + assertTrue(actualList.contains(repository)); + actualList = from(List.of(System.getProperty("user.dir"))); assertNotNull(actualList); assertEquals(1, actualList.size()); assertTrue(actualList.contains(repository)); + actualList = from(List.of("temp-repo-0::" + System.getProperty("user.dir"))); + + assertNotNull(actualList); + assertEquals(1, actualList.size()); + assertTrue(actualList.contains(repository)); + actualList = from(List.of(".."+File.separator+"prospero-cli")); assertNotNull(actualList); assertEquals(1, actualList.size()); assertTrue(actualList.contains(repository)); + + actualList = from(List.of("temp-repo-0::.."+File.separator+"prospero-cli")); + + assertNotNull(actualList); + assertEquals(1, actualList.size()); + assertTrue(actualList.contains(repository)); } } \ No newline at end of file diff --git a/prospero-cli/src/test/java/org/wildfly/prospero/cli/commands/InstallCommandTest.java b/prospero-cli/src/test/java/org/wildfly/prospero/cli/commands/InstallCommandTest.java index af05abca6..c10c5e6d0 100644 --- a/prospero-cli/src/test/java/org/wildfly/prospero/cli/commands/InstallCommandTest.java +++ b/prospero-cli/src/test/java/org/wildfly/prospero/cli/commands/InstallCommandTest.java @@ -243,7 +243,7 @@ public void provisionConfigAndRemoteRepoSet() throws Exception { Path channelsFile = temporaryFolder.newFile().toPath(); File installDir = temporaryFolder.newFolder(); - String testURL = installDir.toURI().toString(); + String testURL = installDir.toPath().toUri().toString(); MetadataTestUtils.prepareChannel(channelsFile, List.of(new URL("file:some-manifest.yaml"))); @@ -265,7 +265,7 @@ public void passShadowRepositories() throws Exception { Path channelsFile = temporaryFolder.newFile().toPath(); File installDir = temporaryFolder.newFolder(); - String testURL = installDir.toURI().toString(); + String testURL = installDir.toPath().toUri().toString(); MetadataTestUtils.prepareChannel(channelsFile, List.of(new URL("file:some-manifest.yaml")));