Skip to content

Commit 2952150

Browse files
authored
Merge pull request wildfly-extras#569 from ChristinaDsl/JBEAP-26296
[JBEAP-26296] Allow specifying --repositories …
2 parents 7ff282c + 71b0328 commit 2952150

File tree

7 files changed

+226
-32
lines changed

7 files changed

+226
-32
lines changed

integration-tests/src/test/java/org/wildfly/prospero/it/cli/InstallTest.java

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,29 @@
1818
package org.wildfly.prospero.it.cli;
1919

2020
import java.io.File;
21-
import java.io.IOException;
21+
import java.net.URL;
2222
import java.nio.file.Path;
23+
import java.util.List;
2324
import java.util.concurrent.TimeUnit;
2425

26+
import org.apache.commons.io.FileUtils;
2527
import org.junit.Before;
26-
import org.junit.Rule;
2728
import org.junit.Test;
28-
import org.junit.rules.TemporaryFolder;
2929
import org.wildfly.prospero.cli.ReturnCodes;
3030
import org.wildfly.prospero.cli.commands.CliConstants;
3131
import org.wildfly.prospero.it.ExecutionUtils;
3232
import org.wildfly.prospero.test.MetadataTestUtils;
3333

34-
public class InstallTest {
34+
import static org.wildfly.prospero.test.MetadataTestUtils.upgradeStreamInManifest;
3535

36-
@Rule
37-
public TemporaryFolder tempDir = new TemporaryFolder();
36+
public class InstallTest extends CliTestBase {
3837

3938
private File targetDir;
4039

4140
@Before
42-
public void setUp() throws IOException {
43-
targetDir = tempDir.newFolder();
41+
public void setUp() throws Exception {
42+
super.setUp();
43+
targetDir = temp.newFolder();
4444
}
4545

4646
@Test
@@ -55,4 +55,35 @@ public void testInstallWithProvisionConfig() throws Exception {
5555
.execute()
5656
.assertReturnCode(ReturnCodes.SUCCESS);
5757
}
58+
59+
@Test
60+
public void testInstallWithLocalRepositories() throws Exception {
61+
final Path manifestPath = temp.newFile().toPath();
62+
final Path provisionConfig = temp.newFile().toPath();
63+
MetadataTestUtils.copyManifest("manifests/wfcore-base.yaml", manifestPath);
64+
MetadataTestUtils.prepareChannel(provisionConfig, List.of(manifestPath.toUri().toURL()));
65+
66+
install(provisionConfig, targetDir.toPath());
67+
68+
upgradeStreamInManifest(manifestPath, resolvedUpgradeArtifact);
69+
70+
final URL temporaryRepo = mockTemporaryRepo(true);
71+
72+
final Path currentDirectory = Path.of(".").toAbsolutePath().normalize();
73+
final Path testRepository = currentDirectory.resolve("test-repository");
74+
final Path relativePath = currentDirectory.relativize(testRepository);
75+
try {
76+
FileUtils.copyDirectory(Path.of(temporaryRepo.toURI()).toFile(), testRepository.toFile());
77+
78+
ExecutionUtils.prosperoExecution(CliConstants.Commands.UPDATE, CliConstants.Commands.PERFORM,
79+
CliConstants.REPOSITORIES, relativePath.toString(),
80+
CliConstants.Y,
81+
CliConstants.VERBOSE,
82+
CliConstants.DIR, targetDir.getAbsolutePath())
83+
.execute()
84+
.assertReturnCode(ReturnCodes.SUCCESS);
85+
} finally {
86+
FileUtils.deleteQuietly(testRepository.toFile());
87+
}
88+
}
5889
}

prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMessages.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,10 @@ default ArgumentParsingException invalidRepositoryDefinition(String repoKey) {
420420
return new ArgumentParsingException(format(bundle.getString("prospero.general.validation.repo_format"), repoKey));
421421
}
422422

423+
default ArgumentParsingException invalidFilePath(String invalidPath) {
424+
return new ArgumentParsingException(format(bundle.getString("prospero.general.validation.file_path.not_exists"), invalidPath));
425+
}
426+
423427
default IllegalArgumentException updateCandidateStateNotMatched(Path targetDir, Path updateDir) {
424428
return new IllegalArgumentException(format(bundle.getString("prospero.updates.apply.validation.candidate.outdated"), targetDir, updateDir));
425429
}

prospero-cli/src/main/java/org/wildfly/prospero/cli/RepositoryDefinition.java

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,68 @@
1717

1818
package org.wildfly.prospero.cli;
1919

20+
import org.jboss.logging.Logger;
2021
import org.wildfly.channel.Repository;
2122

2223
import java.net.MalformedURLException;
24+
import java.net.URI;
25+
import java.net.URISyntaxException;
2326
import java.net.URL;
27+
import java.nio.file.Files;
28+
import java.nio.file.InvalidPathException;
29+
import java.nio.file.Path;
2430
import java.util.ArrayList;
2531
import java.util.List;
2632

2733
public class RepositoryDefinition {
2834

35+
private static final Logger logger = Logger.getLogger(RepositoryDefinition.class.getName());
36+
2937
public static List<Repository> from(List<String> repos) throws ArgumentParsingException {
30-
ArrayList<Repository> repositories = new ArrayList<>(repos.size());
38+
final ArrayList<Repository> repositories = new ArrayList<>(repos.size());
3139
for (int i = 0; i < repos.size(); i++) {
32-
final String text = repos.get(i);
33-
if(text.contains("::")) {
34-
final String[] parts = text.split("::");
35-
if (parts.length != 2 || parts[0].isEmpty() || parts[1].isEmpty() || !isValidUrl(parts[1])) {
36-
throw CliMessages.MESSAGES.invalidRepositoryDefinition(text);
37-
}
40+
final String repoInfo = repos.get(i);
41+
final String repoId;
42+
final String repoUri;
3843

39-
repositories.add(new Repository(parts[0], parts[1]));
40-
} else {
41-
if (!isValidUrl(text)) {
42-
throw CliMessages.MESSAGES.invalidRepositoryDefinition(text);
44+
try {
45+
if (repoInfo.contains("::")) {
46+
final String[] parts = repoInfo.split("::");
47+
if (parts.length != 2 || parts[0].isEmpty() || parts[1].isEmpty()) {
48+
throw CliMessages.MESSAGES.invalidRepositoryDefinition(repoInfo);
49+
}
50+
repoId = parts[0];
51+
repoUri = parseRepositoryLocation(parts[1]);
52+
} else {
53+
repoId = "temp-repo-" + i;
54+
repoUri = parseRepositoryLocation(repoInfo);
4355
}
44-
45-
repositories.add(new Repository("temp-repo-" + i, text));
56+
repositories.add(new Repository(repoId, repoUri));
57+
} catch (URISyntaxException e) {
58+
logger.error("Unable to parse repository uri + " + repoInfo, e);
59+
throw CliMessages.MESSAGES.invalidRepositoryDefinition(repoInfo);
4660
}
61+
4762
}
4863
return repositories;
4964
}
5065

66+
private static String parseRepositoryLocation(String repoLocation) throws URISyntaxException, ArgumentParsingException {
67+
if (!isRemoteUrl(repoLocation) && !repoLocation.isEmpty()) {
68+
// the repoLocation contains either a file URI or a path
69+
// we need to convert it to a valid file IR
70+
repoLocation = getAbsoluteFileURI(repoLocation).toString();
71+
}
72+
if (!isValidUrl(repoLocation)){
73+
throw CliMessages.MESSAGES.invalidRepositoryDefinition(repoLocation);
74+
}
75+
return repoLocation;
76+
}
77+
78+
private static boolean isRemoteUrl(String repoInfo) {
79+
return repoInfo.startsWith("http://") || repoInfo.startsWith("https://");
80+
}
81+
5182
private static boolean isValidUrl(String text) {
5283
try {
5384
new URL(text);
@@ -56,4 +87,35 @@ private static boolean isValidUrl(String text) {
5687
return false;
5788
}
5889
}
90+
91+
public static URI getAbsoluteFileURI(String repoInfo) throws ArgumentParsingException, URISyntaxException {
92+
final Path repoPath = getPath(repoInfo).toAbsolutePath().normalize();
93+
if (Files.exists(repoPath)) {
94+
return repoPath.toUri();
95+
} else {
96+
throw CliMessages.MESSAGES.invalidFilePath(repoInfo);
97+
}
98+
}
99+
100+
public static Path getPath(String repoInfo) throws URISyntaxException, ArgumentParsingException {
101+
if (repoInfo.startsWith("file:")) {
102+
final URI inputUri = new URI(repoInfo);
103+
if (containsAbsolutePath(inputUri)) {
104+
return Path.of(inputUri);
105+
} else {
106+
return Path.of(inputUri.getSchemeSpecificPart());
107+
}
108+
} else {
109+
try {
110+
return Path.of(repoInfo);
111+
} catch (InvalidPathException e) {
112+
throw CliMessages.MESSAGES.invalidFilePath(repoInfo);
113+
}
114+
}
115+
}
116+
117+
private static boolean containsAbsolutePath(URI inputUri) {
118+
// absolute paths in URI (even on Windows) has to start with slash. If not we treat it as a relative path
119+
return inputUri.getSchemeSpecificPart().startsWith("/");
120+
}
59121
}

prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractInstallCommand.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.wildfly.prospero.api.MavenOptions;
2626
import org.wildfly.prospero.api.ProvisioningDefinition;
2727
import org.wildfly.prospero.api.exceptions.ChannelDefinitionException;
28-
import org.wildfly.prospero.api.exceptions.MetadataException;
2928
import org.wildfly.prospero.api.exceptions.NoChannelException;
3029
import org.wildfly.prospero.cli.ActionFactory;
3130
import org.wildfly.prospero.cli.ArgumentParsingException;
@@ -100,7 +99,7 @@ protected MavenOptions getMavenOptions() throws ArgumentParsingException {
10099
return mavenOptions.build();
101100
}
102101

103-
protected ProvisioningDefinition.Builder buildDefinition() throws MetadataException, NoChannelException, ArgumentParsingException {
102+
protected ProvisioningDefinition.Builder buildDefinition() throws ArgumentParsingException {
104103
return ProvisioningDefinition.builder()
105104
.setFpl(featurePackOrDefinition.fpl.orElse(null))
106105
.setProfile(featurePackOrDefinition.profile.orElse(null))

prospero-cli/src/main/resources/UsageMessages.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,8 @@ prospero.general.error.resolve.offline=offline
339339
prospero.general.error.resolve.streams.header=Required artifact streams are not available in any of the configured channels.
340340
prospero.general.validation.conflicting_options=Only one of %s and %s can be set.
341341
prospero.general.validation.local_repo.not_directory=Repository path `%s` is a file not a directory.
342-
prospero.general.validation.repo_format=Repository definition [%s] is invalid. The definition format should be [id::url]
342+
prospero.general.validation.repo_format=Repository definition [%s] is invalid. The definition format should be [id::url] or [url].
343+
prospero.general.validation.file_path.not_exists= The given file path [%s] is invalid.
343344
prospero.general.error.missing_file=Required file at `%s` cannot be opened.
344345
prospero.general.error.galleon.parse=Failed to parse provisioning configuration: %s
345346
prospero.general.error.feature_pack.not_found=The feature pack `%s` is not available in the subscribed channels.

prospero-cli/src/test/java/org/wildfly/prospero/cli/RepositoryDefinitionTest.java

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,31 @@
1818
package org.wildfly.prospero.cli;
1919

2020
import org.apache.commons.lang3.StringUtils;
21+
import org.junit.Before;
2122
import org.junit.Test;
2223
import org.wildfly.channel.Repository;
2324

25+
import java.io.File;
26+
import java.nio.file.Path;
2427
import java.util.List;
2528
import java.util.Set;
2629
import java.util.stream.Collectors;
2730

2831
import static org.assertj.core.api.Assertions.assertThat;
29-
import static org.junit.Assert.assertEquals;
30-
import static org.junit.Assert.assertThrows;
32+
import static org.junit.Assert.*;
3133
import static org.wildfly.prospero.cli.RepositoryDefinition.from;
3234

3335
public class RepositoryDefinitionTest {
3436

37+
private String tempRepoUrlNoHostForm;
38+
private String tempRepoUrlEmptyHostForm;
39+
40+
@Before
41+
public void setUp() throws Exception {
42+
tempRepoUrlEmptyHostForm = Path.of(".").normalize().toAbsolutePath().toUri().toString();
43+
tempRepoUrlNoHostForm = tempRepoUrlEmptyHostForm.replace("///","/");
44+
}
45+
3546
@Test
3647
public void generatesRepositoryIdsIfNotProvided() throws Exception {
3748
assertThat(from(List.of("http://test.te")))
@@ -75,5 +86,83 @@ public void throwsErrorIfFormatIsIncorrect() throws Exception {
7586
assertThrows(ArgumentParsingException.class, ()->from(List.of("foo::bar::http://test1.te")));
7687

7788
assertThrows(ArgumentParsingException.class, ()->from(List.of("imnoturl")));
89+
90+
}
91+
92+
@Test
93+
public void throwsErrorIfFormatIsIncorrectForFileURLorPathDoesNotExist() throws Exception {
94+
assertThrows(ArgumentParsingException.class, ()->from(List.of("::"+ tempRepoUrlNoHostForm)));
95+
96+
assertThrows(ArgumentParsingException.class, ()->from(List.of("repo-1::")));
97+
98+
assertThrows(ArgumentParsingException.class, ()->from(List.of("repo-1:::"+ tempRepoUrlNoHostForm)));
99+
100+
assertThrows(ArgumentParsingException.class, ()->from(List.of("foo::bar::"+ tempRepoUrlNoHostForm)));
101+
}
102+
103+
@Test
104+
public void testCorrectRelativeOrAbsolutePathForFileURL() throws Exception {
105+
Repository repository = new Repository("temp-repo-0", tempRepoUrlEmptyHostForm);
106+
List<Repository> actualList = from(List.of("file:../prospero-cli"));
107+
108+
assertNotNull(actualList);
109+
assertEquals(1, actualList.size());
110+
assertThat(actualList)
111+
.contains(repository);
112+
113+
actualList = from(List.of("temp-repo-0::file:../prospero-cli"));
114+
115+
assertNotNull(actualList);
116+
assertEquals(1, actualList.size());
117+
assertThat(actualList)
118+
.contains(repository);
119+
120+
actualList = from(List.of(("file:/"+(System.getProperty("user.dir").replaceAll("\\\\","/"))).replace("//","/")));
121+
122+
assertNotNull(actualList);
123+
assertEquals(1, actualList.size());
124+
assertTrue(actualList.contains(repository));
125+
126+
actualList = from(List.of(("temp-repo-0::file:/"+(System.getProperty("user.dir").replaceAll("\\\\","/"))).replace("//","/")));
127+
128+
assertNotNull(actualList);
129+
assertEquals(1, actualList.size());
130+
assertTrue(actualList.contains(repository));
131+
132+
actualList = from(List.of(("file:///"+(System.getProperty("user.dir").replaceAll("\\\\","/"))).replace("////","///")));
133+
134+
assertNotNull(actualList);
135+
assertEquals(1, actualList.size());
136+
assertTrue(actualList.contains(repository));
137+
138+
actualList = from(List.of(("temp-repo-0::file:///"+(System.getProperty("user.dir").replaceAll("\\\\","/"))).replace("////","///")));
139+
140+
assertNotNull(actualList);
141+
assertEquals(1, actualList.size());
142+
assertTrue(actualList.contains(repository));
143+
144+
actualList = from(List.of(System.getProperty("user.dir")));
145+
146+
assertNotNull(actualList);
147+
assertEquals(1, actualList.size());
148+
assertTrue(actualList.contains(repository));
149+
150+
actualList = from(List.of("temp-repo-0::" + System.getProperty("user.dir")));
151+
152+
assertNotNull(actualList);
153+
assertEquals(1, actualList.size());
154+
assertTrue(actualList.contains(repository));
155+
156+
actualList = from(List.of(".."+File.separator+"prospero-cli"));
157+
158+
assertNotNull(actualList);
159+
assertEquals(1, actualList.size());
160+
assertTrue(actualList.contains(repository));
161+
162+
actualList = from(List.of("temp-repo-0::.."+File.separator+"prospero-cli"));
163+
164+
assertNotNull(actualList);
165+
assertEquals(1, actualList.size());
166+
assertTrue(actualList.contains(repository));
78167
}
79168
}

0 commit comments

Comments
 (0)