Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JBEAP-26296] Allow specifying --repositories … #569

Merged
merged 3 commits into from
May 13, 2024

Conversation

ChristinaDsl
Copy link
Contributor

Copy link
Collaborator

@spyrkob spyrkob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChristinaDsl that doesn't work, the local path has to be converted to an URL to be usable:

./prospero install --fpl org.wildfly.core:wildfly-core-galleon-pack:20.0.0.Beta3 \
  --manifest examples/wildfly-core-manifest.yaml --repositories test-repo \
  --dir installation-dir
Installing feature pack: org.wildfly.core:wildfly-core-galleon-pack:20.0.0.Beta3
Using channels:
# manifest: file:/Users/spyrkob/workspaces/set/prospero/prospero/examples/wildfly-core-manifest.yaml
  repositories:
    id: temp-repo-0
    url: test-repo



ERROR: The following artifacts could not be resolved: org.wildfly.core:wildfly-core-galleon-pack:zip:20.0.0.Beta3 (absent): Could not transfer artifact org.wildfly.core:wildfly-core-galleon-pack:zip:20.0.0.Beta3 from/to temp-repo-0 (test-repo): Cannot access test-repo with type default using the available connector factories: BasicRepositoryConnectorFactory

Also could you add unit tests to RepositoryDefinitionTest and an integration test to org.wildfly.prospero.it.cli.InstallTest to verify this change?

from(List.of(fileURL));
from(List.of("file://"+filePath));
} catch (Exception e) {
fail("Provided URL's absolute or relative path is not correct");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChristinaDsl you don't need to catch the exception. If it fails the test fails. Also you should check that the returned value is correct. The method might run without exception, but the returned value might be wrong

@ChristinaDsl ChristinaDsl force-pushed the JBEAP-26296 branch 2 times, most recently from b4b7fb8 to 5e0742c Compare March 15, 2024 10:34
if (text.startsWith("file://..")){
return false;
} else if (text.startsWith("file")){
if (Pattern.compile("/[A-Z]:").matcher(text).find()){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChristinaDsl why do you need this check? Paths.get(url.toURI() should work on both Windows and Linux paths

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not work on relative paths. In windows and file URLs Paths.get() throws error and in Linux relative path cannot be converted initially in URL.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK thank you. Could you add this explanation in a comment in the code please?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course

new URL(text);
URL url = new URL(text);
if (text.startsWith("file://..")){
return false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a debug message why this is incorrect

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course

} else {
path = Paths.get(url.getPath()).toAbsolutePath();
}
return new File(String.valueOf(path)).exists();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return Files.exists(path) or return path.toFile().exists()

final URL temporaryRepo = mockTemporaryRepo(true);

ExecutionUtils.prosperoExecution(CliConstants.Commands.UPDATE, CliConstants.Commands.PERFORM,
CliConstants.REPOSITORIES, temporaryRepo.toString(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the temporaryRepo is an URL, for this test to really verify this functionality it would have to be a relative path

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your comment. This test is to verify that a local repo can be found and the update command is indeed working when an argument " --repositories" is passed along with the url of local repo. So, why should be a relative path here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There already are tests in UpdateWithAdditionalRepositoryTest that verify this use case. The new use case added in this issue should be that a user can pass a local path (e.g. ../test-repository or /home/user/test-repository) as an argument for --repositories

Copy link
Contributor Author

@ChristinaDsl ChristinaDsl Mar 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So check both for absolute and relative paths in this method?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally yes, but relative path would be enough

}

@Test
public void testCorrectRelativeOrAbsolutePathForFileURL() throws Exception {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about a relative path?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relative path is test in the first lines of this method with this url "file:../prospero-common"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a URI with relative path. A relative path would be ../prospero-common on its own

Copy link
Contributor Author

@ChristinaDsl ChristinaDsl Mar 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole method contains URLs and a URI, not just its absolute and relative paths. Should I change the whole method to contain only paths?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this verifies JBEAP-26295 as well so those are valid tests. Just adding some examples of paths will be enough.


final URL temporaryRepo = mockTemporaryRepo(true);

Path relativePath = Paths.get(System.getProperty("user.dir")).relativize(Path.of(Path.of(temporaryRepo.toURI()).toUri()));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nested Path.of is not needed

Path relativePath = Paths.get(System.getProperty("user.dir")).relativize(Path.of(Path.of(temporaryRepo.toURI()).toUri()));

ExecutionUtils.prosperoExecution(CliConstants.Commands.UPDATE, CliConstants.Commands.PERFORM,
CliConstants.REPOSITORIES, ".."+File.separator+"integration-tests"+File.separator+relativePath,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use Path.of(String...) to build the path instead of appending the strings.

Also, relativePath is already a relative path, so I don't think adding ../integration-tests" to it brings anything to the test. I'd keep it simple and just use the relativePath` here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding "../integration-tests" is important because if I just use relative path then I have a result "target/folder1/folder2" which is invalid for two reasons:
Firstly, is not a relative path
Secondly, the folder the test exists is "integration-tests". So, if I just put "../"+relative path would go out of integration-tests folder and search the target inside parent folder which is "prospero". I need too search inside "integration-tests" the target folder because there it is created.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

target/folder1/folder2 is a relative path. An absolute path starts with root directory (e.g. /home/jboss/ on linux or C:\Users\jboss on Windows). A relative path doesn't have a root folder and is relative to the current folder (e.g. target/foo is relative because it depends on where the user is)

@@ -418,6 +418,10 @@ default ArgumentParsingException invalidRepositoryDefinition(String repoKey) {
return new ArgumentParsingException(format(bundle.getString("prospero.general.validation.repo_format"), repoKey));
}

default ArgumentParsingException invalidFilePath(String repoKey) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/repoKey/path


public class RepositoryDefinition {

public static List<Repository> from(List<String> repos) throws ArgumentParsingException {
public static List<Repository> from(List<String> repos) throws ArgumentParsingException, MalformedURLException, URISyntaxException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you catch the new exceptions and wrap them in ArgumentParsingException with an explanation message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course


private static boolean isValidUrl(String text) throws ArgumentParsingException {
if (text.startsWith("file://..")) {
Logger.getLogger("'file://../path/to/repo' is invalid as the format of file URL should be " +
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean Logger.warn ?

whereas for Linux, Paths.get(url.getPath()).toAbsolutePath() is more suitable. */
private static Path getPathFromURL(String text) throws MalformedURLException, URISyntaxException, ArgumentParsingException {
URL url = new URL(text);
if (Pattern.compile("/[A-Z]:").matcher(text).find()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not going to correct, e.g. in Linux it's possible to create a folder with name A:

public static List<Repository> from(List<String> repos) throws ArgumentParsingException {
ArrayList<Repository> repositories = new ArrayList<>(repos.size());
for (int i = 0; i < repos.size(); i++) {
final String text = repos.get(i);
String text = repos.get(i);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable can be more descriptive than text. Maybe repoName?

@@ -56,4 +69,31 @@ private static boolean isValidUrl(String text) {
return false;
}
}

public static URI getAbsoluteFileURI(String text) throws ArgumentParsingException, URISyntaxException {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.


public static URI getAbsoluteFileURI(String text) throws ArgumentParsingException, URISyntaxException {
String path;
path = getPath(text);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the assignment on a separate line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will fix this

public static URI getAbsoluteFileURI(String text) throws ArgumentParsingException, URISyntaxException {
String path;
path = getPath(text);
File file = new File(path);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think file can be a one-liner.
File file = new File(getPath(text));, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If file does not exist, the error message should include the path, so it is used in more than one line.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean, throw CliMessages.MESSAGES.invalidFilePath(path);? If so, you are already using path instead of file.

Copy link
Contributor Author

@ChristinaDsl ChristinaDsl Apr 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean?
file is also used in two lines,
if (file.exists()) {
return file.toURI();

if that is your point..

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is that you don't need to create a new variable for the single purpose, path, to be used as a parameter for getPath() and then used to create a File object. You can simplify it with File file = new File(getPath(text)); for example.

}
}

public static String getPath(String text) throws URISyntaxException {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

text, same as above.

@@ -241,37 +241,45 @@ public void provisionConfigAndChannelSet() throws IOException {
@Test
public void provisionConfigAndRemoteRepoSet() throws Exception {
Path channelsFile = temporaryFolder.newFile().toPath();

File test = temporaryFolder.newFolder();
String testURL = test.toURI().toURL().toString();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why converting to URI, then to URL and then to String?

Copy link
Collaborator

@spyrkob spyrkob Apr 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To create a URL out of a file object. I guess we could skip last call .toURL()


File test = temporaryFolder.newFolder();
String testURL = test.toURI().toURL().toString();

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

@@ -241,37 +241,45 @@ public void provisionConfigAndChannelSet() throws IOException {
@Test
public void provisionConfigAndRemoteRepoSet() throws Exception {
Path channelsFile = temporaryFolder.newFile().toPath();

File test = temporaryFolder.newFolder();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable could have a more descriptive name

}

@SuppressWarnings("unchecked")
@Test
public void passShadowRepositories() throws Exception {
Path channelsFile = temporaryFolder.newFile().toPath();

File test = temporaryFolder.newFolder();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable could have a more descriptive name

}

public static String getPath(String text) throws URISyntaxException {
if (text.startsWith("file")) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be file: to make sure the user is inputting a URI and not a file named file_dir for example

final String text = repos.get(i);
if(text.contains("::")) {
final String[] parts = text.split("::");
String repoName = repos.get(i);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick - the repoName variable name is a bit misleading - the string can either contain repoName::repoLocation or just repoLocation

repositories.add(new Repository(parts[0], parts[1]));
} else {
if (!isValidUrl(text)) {
throw CliMessages.MESSAGES.invalidRepositoryDefinition(text);
if (!repoName.startsWith("http") && !repoName.isEmpty()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should check if it starts with either http:// or https://.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it starts with "https", it should be handled differently?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both http and https should be treated the same - as web URLs. The difference is that http://foo.bar is an URL http/foo/bar is a path

URI inputUri = new URI(repoName);
if (inputUri.getScheme().equals("file") &&
!inputUri.getSchemeSpecificPart().startsWith("/")) {
inputUri = new URI(("file:/" +
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC at this point this is a relative URI. In which case Path.of(inputUri.getSchemeSpecificPart()).toAbsolutePath() should be all you need to get the absolute path

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this already creates the Path from the URI, why does it need to be converted back to URI and then again to Path?

@@ -100,7 +102,7 @@ protected MavenOptions getMavenOptions() throws ArgumentParsingException {
return mavenOptions.build();
}

protected ProvisioningDefinition.Builder buildDefinition() throws MetadataException, NoChannelException, ArgumentParsingException {
protected ProvisioningDefinition.Builder buildDefinition() throws MetadataException, NoChannelException, ArgumentParsingException, MalformedURLException, URISyntaxException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those exceptions should be wrapped in ArgumentParsingException

@spyrkob
Copy link
Collaborator

spyrkob commented May 3, 2024

@ChristinaDsl please remove the [installation-manager] from commit description, and I think it'll be good to go.

@ChristinaDsl ChristinaDsl changed the title [JBEAP-26296] [installation-manager] Allow specifying --repositories … [JBEAP-26296] Allow specifying --repositories … May 8, 2024
@spyrkob spyrkob merged commit 2952150 into wildfly-extras:main May 13, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants