From 138a88fe188f996725f5a13b7966451d40e107c0 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Mon, 14 Feb 2022 17:40:20 +0100 Subject: [PATCH 01/30] Bump version --- gradle/libs.versions.toml | 2 +- native-maven-plugin/reproducers/issue-144/pom.xml | 4 ++-- samples/java-application-with-custom-tests/gradle.properties | 2 +- .../java-application-with-extra-sourceset/gradle.properties | 2 +- samples/java-application-with-reflection/gradle.properties | 2 +- samples/java-application-with-reflection/pom.xml | 4 ++-- samples/java-application-with-resources/gradle.properties | 2 +- samples/java-application-with-resources/pom.xml | 4 ++-- samples/java-application-with-tests/gradle.properties | 2 +- samples/java-application-with-tests/pom.xml | 4 ++-- samples/java-application/gradle.properties | 2 +- samples/java-application/pom.xml | 4 ++-- samples/java-library/gradle.properties | 2 +- samples/java-library/pom.xml | 4 ++-- samples/kotlin-application-with-tests/gradle.properties | 2 +- samples/multi-project-with-tests/gradle.properties | 2 +- 16 files changed, 22 insertions(+), 22 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2aa0b3259..bbd71df92 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # Project versions -nativeBuildTools = "0.9.10" +nativeBuildTools = "0.9.11-SNAPSHOT" # External dependencies spock = "2.0-groovy-3.0" diff --git a/native-maven-plugin/reproducers/issue-144/pom.xml b/native-maven-plugin/reproducers/issue-144/pom.xml index 1ece57a5e..24dca7164 100644 --- a/native-maven-plugin/reproducers/issue-144/pom.xml +++ b/native-maven-plugin/reproducers/issue-144/pom.xml @@ -56,8 +56,8 @@ 1.8 UTF-8 - 0.9.10 - 0.9.10 + 0.9.11-SNAPSHOT + 0.9.11-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-custom-tests/gradle.properties b/samples/java-application-with-custom-tests/gradle.properties index af2d4c275..030694402 100644 --- a/samples/java-application-with-custom-tests/gradle.properties +++ b/samples/java-application-with-custom-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.10 +native.gradle.plugin.version = 0.9.11-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-extra-sourceset/gradle.properties b/samples/java-application-with-extra-sourceset/gradle.properties index af2d4c275..030694402 100644 --- a/samples/java-application-with-extra-sourceset/gradle.properties +++ b/samples/java-application-with-extra-sourceset/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.10 +native.gradle.plugin.version = 0.9.11-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-reflection/gradle.properties b/samples/java-application-with-reflection/gradle.properties index af2d4c275..030694402 100644 --- a/samples/java-application-with-reflection/gradle.properties +++ b/samples/java-application-with-reflection/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.10 +native.gradle.plugin.version = 0.9.11-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-reflection/pom.xml b/samples/java-application-with-reflection/pom.xml index b4f9de150..96ab41d30 100644 --- a/samples/java-application-with-reflection/pom.xml +++ b/samples/java-application-with-reflection/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.8.1 - 0.9.10 - 0.9.10 + 0.9.11-SNAPSHOT + 0.9.11-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-resources/gradle.properties b/samples/java-application-with-resources/gradle.properties index af2d4c275..030694402 100644 --- a/samples/java-application-with-resources/gradle.properties +++ b/samples/java-application-with-resources/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.10 +native.gradle.plugin.version = 0.9.11-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-resources/pom.xml b/samples/java-application-with-resources/pom.xml index 3e2d57cc0..5e5ec9bad 100644 --- a/samples/java-application-with-resources/pom.xml +++ b/samples/java-application-with-resources/pom.xml @@ -51,9 +51,9 @@ 1.8 UTF-8 - 0.9.10 + 0.9.11-SNAPSHOT 5.8.1 - 0.9.10 + 0.9.11-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-tests/gradle.properties b/samples/java-application-with-tests/gradle.properties index af2d4c275..030694402 100644 --- a/samples/java-application-with-tests/gradle.properties +++ b/samples/java-application-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.10 +native.gradle.plugin.version = 0.9.11-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-tests/pom.xml b/samples/java-application-with-tests/pom.xml index 2915683bd..19ce7cde2 100644 --- a/samples/java-application-with-tests/pom.xml +++ b/samples/java-application-with-tests/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.8.1 - 0.9.10 - 0.9.10 + 0.9.11-SNAPSHOT + 0.9.11-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application/gradle.properties b/samples/java-application/gradle.properties index af2d4c275..030694402 100644 --- a/samples/java-application/gradle.properties +++ b/samples/java-application/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.10 +native.gradle.plugin.version = 0.9.11-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application/pom.xml b/samples/java-application/pom.xml index 4ae6f56bd..9fbda7706 100644 --- a/samples/java-application/pom.xml +++ b/samples/java-application/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.10 - 0.9.10 + 0.9.11-SNAPSHOT + 0.9.11-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-library/gradle.properties b/samples/java-library/gradle.properties index af2d4c275..030694402 100644 --- a/samples/java-library/gradle.properties +++ b/samples/java-library/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.10 +native.gradle.plugin.version = 0.9.11-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-library/pom.xml b/samples/java-library/pom.xml index 24b5acd8c..0c8ecbd90 100644 --- a/samples/java-library/pom.xml +++ b/samples/java-library/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.10 - 0.9.10 + 0.9.11-SNAPSHOT + 0.9.11-SNAPSHOT java-library diff --git a/samples/kotlin-application-with-tests/gradle.properties b/samples/kotlin-application-with-tests/gradle.properties index af2d4c275..030694402 100644 --- a/samples/kotlin-application-with-tests/gradle.properties +++ b/samples/kotlin-application-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.10 +native.gradle.plugin.version = 0.9.11-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/multi-project-with-tests/gradle.properties b/samples/multi-project-with-tests/gradle.properties index af2d4c275..030694402 100644 --- a/samples/multi-project-with-tests/gradle.properties +++ b/samples/multi-project-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.10 +native.gradle.plugin.version = 0.9.11-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 From 61499e8ecbd418390be6b62de42f1a2b54a75133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lazar=20Mitrovi=C4=87?= Date: Tue, 22 Feb 2022 11:40:59 +0100 Subject: [PATCH 02/30] Add issue templates Streamlines issue triaging and categorizing. --- .github/ISSUE_TEMPLATE/bug_report.md | 44 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 21 +++++++++++ .github/ISSUE_TEMPLATE/support-ticket.md | 24 +++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/support-ticket.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..aaa63565b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,44 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. +**Make sure that you have read [the documentation](https://graalvm.github.io/native-build-tools) and that you are using the latest plugin version.** + +**To Reproduce** +Steps to reproduce the behavior: +```xml + +``` +```bash +$ # command invocation +``` +Please use backticks to [properly format code](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting). +If possible please attach a complete reproducer here (either as [a zip file](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/attaching-files) or as a link to public repository/branch). + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Logs** +Add logs to help explain your problem. +Please use backticks to [properly format big logs](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#fenced-code-blocks). Example: +```` +``` + +``` +```` + +**System Info (please complete the following information):** + - OS: [e.g. `Windows`] + - GraalVM Version [e.g. `22.0 CE`] + - Java Version [e.g. `17`] + - Plugin version [e.g. `native-gradle-plugin:0.9.10`] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..ae4f9ce6c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] +**Please make sure that you are using the latest plugin version, and that similar feature hasn't been [requested before](https://github.com/graalvm/native-build-tools/issues).** + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/support-ticket.md b/.github/ISSUE_TEMPLATE/support-ticket.md new file mode 100644 index 000000000..109bf595e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/support-ticket.md @@ -0,0 +1,24 @@ +--- +name: Support ticket +about: Ask a question about proper usage +title: "[QUESTION]" +labels: question +assignees: '' + +--- + +**Describe the problem** +A clear and concise description of what the problem is. +**Make sure that you have read [the documentation](https://graalvm.github.io/native-build-tools) and that you are using the latest plugin version.** + +**Additional context** +Add any other context about the problem here. + +**System Info (please complete the following information):** + - OS: [e.g. `Windows`] + - GraalVM Version [e.g. `22.0 CE`] + - Java Version [e.g. `17`] + - Plugin version [e.g. `native-gradle-plugin:0.9.10`] + +**To Reproduce** +If possible please attach a complete reproducer here (either as [a zip file](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/attaching-files) or as a link to public repository/branch). From 1f931e8d3aaae01aade96b623cb03a4b495be7f2 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Mon, 21 Feb 2022 11:15:06 +0100 Subject: [PATCH 03/30] Fix @arg file not being used for tests in Maven --- .../org/graalvm/buildtools/maven/NativeTestMojo.java | 9 +++++---- .../maven/AbstractGraalVMMavenFunctionalTest.groovy | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java index 5439f90f9..c01c2f7be 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java @@ -51,6 +51,7 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.graalvm.buildtools.Utils; +import org.graalvm.buildtools.utils.NativeImageUtils; import org.graalvm.junit.platform.JUnitPlatformFeature; import java.io.File; @@ -139,7 +140,6 @@ private void buildImage(String classpath, Path targetFolder) throws MojoExecutio Path nativeImageExecutable = Utils.getNativeImage(); List command = new ArrayList<>(Arrays.asList( - nativeImageExecutable.toString(), "-cp", classpath, "--features=org.graalvm.junit.platform.JUnitPlatformFeature", "-Djunit.platform.listeners.uid.tracking.output.dir=" + NativeExtension.testIdsDirectory(buildDirectory.getAbsolutePath()), @@ -151,10 +151,11 @@ private void buildImage(String classpath, Path targetFolder) throws MojoExecutio command.addAll(buildArgs); } - command.add("org.graalvm.junit.platform.NativeImageJUnitLauncher"); - try { - ProcessBuilder processBuilder = new ProcessBuilder(command); + command = NativeImageUtils.convertToArgsFile(command); + ProcessBuilder processBuilder = new ProcessBuilder(nativeImageExecutable.toString()); + processBuilder.command().addAll(command); + processBuilder.command().add("org.graalvm.junit.platform.NativeImageJUnitLauncher"); processBuilder.directory(new File(project.getBuild().getDirectory())); processBuilder.inheritIO(); diff --git a/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy b/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy index 99eb80d1b..f5bfe2525 100644 --- a/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy +++ b/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy @@ -145,4 +145,14 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { private static String normalizeString(String input) { input.replace("\r\n", "\n") } + + String getArgFileContents() { + result.stdOut.lines().filter { + it.contains('Executing:') && it.contains('bin/native-image') + }.map { + new File(it.substring(it.lastIndexOf('@') + 1)) + }.findFirst() + .map { it.text } + .orElse("") + } } From 5a9e9ca9c795c48b7d641332b83840566fbb97a0 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Tue, 22 Feb 2022 16:26:01 +0100 Subject: [PATCH 04/30] Disable snapshot publication This has been broken for some time and needs rework --- .../{deploy-snapshots.yml => deploy-snapshots.yml.disabled} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{deploy-snapshots.yml => deploy-snapshots.yml.disabled} (100%) diff --git a/.github/workflows/deploy-snapshots.yml b/.github/workflows/deploy-snapshots.yml.disabled similarity index 100% rename from .github/workflows/deploy-snapshots.yml rename to .github/workflows/deploy-snapshots.yml.disabled From 4f02438a5da9e30d4352dc18c966bf789caf9486 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Tue, 22 Feb 2022 16:20:11 +0100 Subject: [PATCH 05/30] Make it possible to use environment variables in native tests Prior to this commit, it wasn't possible to expose environment variables (both Maven and Gradle) or system properties (Maven) to the native test execution. This commit makes it possible to use both. For Gradle, tests can be configured to use environment variables by using `tasks.named("nativeTest") { environment.put(...) }`. For Maven, environment variables and system properties are inherted from the surefire mojo. It's worth noting that the executable generated by native-image does not support @arg files itself. This means that if there are too many system properties, Windows users could have difficulties running native tests (because of long CLI issues). Fixes #215 Fixes #196 --- docs/src/docs/asciidoc/index.adoc | 10 +++ ...aApplicationWithTestsFunctionalTest.groovy | 32 +++++++++ .../gradle/tasks/NativeRunTask.java | 13 ++++ ...aApplicationWithTestsFunctionalTest.groovy | 17 +++++ .../buildtools/maven/NativeTestMojo.java | 66 +++++++++++++++++-- .../AbstractGraalVMMavenFunctionalTest.groovy | 5 ++ samples/java-application-with-tests/pom.xml | 22 ++++++- .../java/org/graalvm/demo/Calculator.java | 9 +++ 8 files changed, 168 insertions(+), 6 deletions(-) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 911b6a123..a6d4f7281 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -14,6 +14,16 @@ If you are interested in contributing, please refer to our https://github.com/gr [[changelog]] == Changelog +=== Release 0.9.11 + +==== Maven plugin + +* Fix long classpath issue under Windows when running native tests +* Inherit environment variables and system properties from the surefire plugin configuration when executing tests + +==== Gradle plugin + +* Add support for environment variables in native test execution === Release 0.9.10 diff --git a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithTestsFunctionalTest.groovy b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithTestsFunctionalTest.groovy index 1b16caea8..fc6ab60bf 100644 --- a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithTestsFunctionalTest.groovy +++ b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithTestsFunctionalTest.groovy @@ -143,6 +143,38 @@ class JavaApplicationWithTestsFunctionalTest extends AbstractFunctionalTest { junitVersion = System.getProperty('versions.junit') } + @Issue("https://github.com/graalvm/native-build-tools/issues/215") + @Unroll("can pass environment variables to native test execution with JUnit Platform #junitVersion") + def "can pass environment variables to native test execution"() { + given: + withSample("java-application-with-tests") + buildFile << """ + tasks.named("nativeTest") { + environment.put("TEST_ENV", "test-value") + } + + """ + + when: + run 'nativeTest' + + then: + tasks { + succeeded ':testClasses', + ':nativeTestCompile', + ':test', // there should probably not be a dependency here + ':nativeTest' + doesNotContain ':build' + } + + then: + outputDoesNotContain "Running in 'test discovery' mode. Note that this is a fallback mode." + outputContains "TEST_ENV = test-value" + + where: + junitVersion = System.getProperty('versions.junit') + } + @Issue("https://github.com/graalvm/native-build-tools/issues/133") @Unroll("can disable test support with JUnit Platform #junitVersion") def "can disable test support"() { diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/NativeRunTask.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/NativeRunTask.java index f232d54a1..4129bc83e 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/NativeRunTask.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/NativeRunTask.java @@ -45,12 +45,15 @@ import org.gradle.api.file.RegularFileProperty; import org.gradle.api.plugins.ApplicationPlugin; import org.gradle.api.provider.ListProperty; +import org.gradle.api.provider.MapProperty; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFile; +import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.TaskAction; import org.gradle.process.ExecOperations; import javax.inject.Inject; +import java.util.Map; @SuppressWarnings("unused") public abstract class NativeRunTask extends DefaultTask { @@ -62,6 +65,10 @@ public abstract class NativeRunTask extends DefaultTask { @Input public abstract ListProperty getRuntimeArgs(); + @Input + @Optional + public abstract MapProperty getEnvironment(); + @Inject protected abstract ExecOperations getExecOperations(); @@ -76,6 +83,12 @@ public void exec() { getExecOperations().exec(spec -> { spec.setExecutable(getImage().get().getAsFile().getAbsolutePath()); spec.args(getRuntimeArgs().get()); + if (getEnvironment().isPresent()) { + Map env = (Map) getEnvironment().get(); + for (Map.Entry entry : env.entrySet()) { + spec.environment(entry.getKey(), entry.getValue()); + } + } }); } } diff --git a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationWithTestsFunctionalTest.groovy b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationWithTestsFunctionalTest.groovy index 0830d9e9c..9e0b15e95 100644 --- a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationWithTestsFunctionalTest.groovy +++ b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationWithTestsFunctionalTest.groovy @@ -123,4 +123,21 @@ class JavaApplicationWithTestsFunctionalTest extends AbstractGraalVMMavenFunctio outputDoesNotContain "containers found" } + @Issue("https://github.com/graalvm/native-build-tools/issues/215") + def "can pass environment variables to native test execution"() { + given: + withSample("java-application-with-tests") + + when: + mvn '-Pnative', '-Ptest-variables', 'test' + + then: + buildSucceeded + outputContains "[junit-platform-native] Running in 'test listener' mode" + def nativeImageExecResult = after("JUnit Platform on Native Image - report") + nativeImageExecResult.contains "TEST_ENV = test-value" + nativeImageExecResult.contains "test-property = test-value" + + } + } diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java index c01c2f7be..70508e656 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java @@ -44,12 +44,14 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.model.FileSet; +import org.apache.maven.model.Plugin; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; +import org.codehaus.plexus.util.xml.Xpp3Dom; import org.graalvm.buildtools.Utils; import org.graalvm.buildtools.utils.NativeImageUtils; import org.graalvm.junit.platform.JUnitPlatformFeature; @@ -64,7 +66,9 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -91,12 +95,19 @@ public class NativeTestMojo extends AbstractNativeMojo { @Parameter(property = "project.build.directory") private File buildDirectory; + @Parameter(property = "environmentVariables") + private Map environment; + + @Parameter(property = "systemPropertyVariables") + private Map systemProperties; + @Override public void execute() throws MojoExecutionException, MojoFailureException { if (skipTests || skipNativeTests) { logger.info("Skipping native-image tests (parameter 'skipTests' or 'skipNativeTests' is true)."); return; } + configureEnvironment(); if (!hasTests()) { return; } @@ -124,6 +135,37 @@ public void execute() throws MojoExecutionException, MojoFailureException { runTests(targetFolder); } + private void configureEnvironment() { + // inherit from surefire mojo + Plugin plugin = project.getPlugin("org.apache.maven.plugins:maven-surefire-plugin"); + if (plugin != null) { + Object configuration = plugin.getConfiguration(); + if (configuration instanceof Xpp3Dom) { + Xpp3Dom dom = (Xpp3Dom) configuration; + Xpp3Dom environmentVariables = dom.getChild("environmentVariables"); + if (environmentVariables != null) { + Xpp3Dom[] children = environmentVariables.getChildren(); + if (environment == null) { + environment = new HashMap<>(children.length); + } + for (Xpp3Dom child : children) { + environment.put(child.getName(), child.getValue()); + } + } + Xpp3Dom systemProps = dom.getChild("systemPropertyVariables"); + if (systemProps != null) { + Xpp3Dom[] children = systemProps.getChildren(); + if (systemProperties == null) { + systemProperties = new HashMap<>(children.length); + } + for (Xpp3Dom child : children) { + systemProperties.put(child.getName(), child.getValue()); + } + } + } + } + } + private boolean hasTests() { Path testOutputPath = Paths.get(project.getBuild().getTestOutputDirectory()); if (Files.exists(testOutputPath) && Files.isDirectory(testOutputPath)) { @@ -152,13 +194,13 @@ private void buildImage(String classpath, Path targetFolder) throws MojoExecutio } try { - command = NativeImageUtils.convertToArgsFile(command); ProcessBuilder processBuilder = new ProcessBuilder(nativeImageExecutable.toString()); + prepareVariables(processBuilder, command); + command = NativeImageUtils.convertToArgsFile(command); processBuilder.command().addAll(command); processBuilder.command().add("org.graalvm.junit.platform.NativeImageJUnitLauncher"); processBuilder.directory(new File(project.getBuild().getDirectory())); processBuilder.inheritIO(); - String commandString = String.join(" ", processBuilder.command()); getLog().info("Executing: " + commandString); Process imageBuildProcess = processBuilder.start(); @@ -176,10 +218,13 @@ private void runTests(Path targetFolder) throws MojoExecutionException { try { ProcessBuilder processBuilder = new ProcessBuilder( - targetFolder.resolve(NATIVE_TESTS_EXE).toAbsolutePath().toString(), - "--xml-output-dir", xmlLocation.toString()); + targetFolder.resolve(NATIVE_TESTS_EXE).toAbsolutePath().toString()); processBuilder.inheritIO(); - + List command = new ArrayList<>(); + prepareVariables(processBuilder, command); + command.add("--xml-output-dir"); + command.add(xmlLocation.toString()); + processBuilder.command().addAll(command); String commandString = String.join(" ", processBuilder.command()); getLog().info("Executing: " + commandString); Process imageBuildProcess = processBuilder.start(); @@ -191,6 +236,17 @@ private void runTests(Path targetFolder) throws MojoExecutionException { } } + private void prepareVariables(ProcessBuilder processBuilder, List command) { + if (environment != null) { + processBuilder.environment().putAll(environment); + } + if (systemProperties != null) { + for (Map.Entry entry : systemProperties.entrySet()) { + command.add("-D" + entry.getKey() + "=" + entry.getValue()); + } + } + } + private String getClassPath() throws MojoFailureException { if (classpath != null && !classpath.isEmpty()) { return String.join(File.pathSeparator, classpath); diff --git a/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy b/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy index f5bfe2525..0f9c60087 100644 --- a/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy +++ b/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy @@ -134,6 +134,11 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { normalizeString(result.stdOut).contains(normalizeString(text)) } + String after(String text) { + def out = normalizeString(result.stdOut) + out.substring(out.indexOf(normalizeString(text))) + } + boolean outputDoesNotContain(String text) { !normalizeString(result.stdOut).contains(normalizeString(text)) } diff --git a/samples/java-application-with-tests/pom.xml b/samples/java-application-with-tests/pom.xml index 19ce7cde2..ca6d171af 100644 --- a/samples/java-application-with-tests/pom.xml +++ b/samples/java-application-with-tests/pom.xml @@ -83,7 +83,7 @@ native-maven-plugin ${native.maven.plugin.version} true - + test-native @@ -216,6 +216,26 @@ + + test-variables + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + test-value + + + test-value + + + + + + diff --git a/samples/java-application-with-tests/src/main/java/org/graalvm/demo/Calculator.java b/samples/java-application-with-tests/src/main/java/org/graalvm/demo/Calculator.java index 41e072c9b..b1facd323 100644 --- a/samples/java-application-with-tests/src/main/java/org/graalvm/demo/Calculator.java +++ b/samples/java-application-with-tests/src/main/java/org/graalvm/demo/Calculator.java @@ -2,6 +2,15 @@ public class Calculator { + public Calculator() { + if (System.getenv("TEST_ENV") != null) { + System.out.println("TEST_ENV = " + System.getenv("TEST_ENV")); + } + if (System.getProperty("test-property") != null) { + System.out.println("test-property = " + System.getProperty("test-property")); + } + } + public int add(int a, int b) { return a + b; } From aa743feebd37180babf9459ddf4875686273362d Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Fri, 25 Feb 2022 18:06:38 +0100 Subject: [PATCH 06/30] Fix incorrect declaration of output directory This commit fixes an issue with the Gradle plugin where the directory where test ids are generated was incorrectly declared as an output of the test task. This caused independent test tasks to be out-of-date when they shouldn't. Fixes #218 --- ...aApplicationWithTestsFunctionalTest.groovy | 34 +++++++++++++++++++ .../buildtools/gradle/NativeImagePlugin.java | 14 ++++---- .../fixtures/AbstractFunctionalTest.groovy | 7 ++++ 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithTestsFunctionalTest.groovy b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithTestsFunctionalTest.groovy index fc6ab60bf..733ff48bd 100644 --- a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithTestsFunctionalTest.groovy +++ b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithTestsFunctionalTest.groovy @@ -253,4 +253,38 @@ class JavaApplicationWithTestsFunctionalTest extends AbstractFunctionalTest { where: junitVersion = System.getProperty('versions.junit') } + + @Issue("https://github.com/graalvm/native-build-tools/issues/218") + def "test list directory output is properly configured"() { + given: + withSample("java-application-with-tests") + + buildFile << """ + tasks.register("otherTest", Test) { + classpath = tasks.test.classpath + testClassesDirs = tasks.test.testClassesDirs + } + """ + + when: + run 'test' + + then: + file("build/test-results/test/testlist").isDirectory() + !file("build/test-results/otherTest/testlist").isDirectory() + + when: + run 'otherTest' + + then: + !file("build/test-results/otherTest/testlist").isDirectory() + + when: + run 'test' + + then: + tasks { + upToDate(':test') + } + } } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java index 72ff61bd3..1dc8e2d17 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java @@ -83,10 +83,8 @@ import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; -import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.JavaExec; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; +import org.gradle.api.tasks.OutputDirectory; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.TaskContainer; @@ -96,8 +94,8 @@ import org.gradle.api.tasks.testing.Test; import org.gradle.jvm.toolchain.JavaToolchainService; import org.gradle.language.base.plugins.LifecycleBasePlugin; -import org.gradle.process.ExecOperations; import org.gradle.process.CommandLineArgumentProvider; +import org.gradle.process.ExecOperations; import org.gradle.process.JavaForkOptions; import org.gradle.util.GFileUtils; @@ -380,8 +378,9 @@ public void registerTestBinary(Project project, TaskProvider testTask = config.validate().getTestTask(); testOptions.getAgent().getInstrumentedTask().set(testTask); testTask.configure(test -> { - testListDirectory.set(new File(testResultsDir, test.getName() + "/testlist")); - test.getOutputs().dir(testResultsDir); + File testList = new File(testResultsDir, test.getName() + "/testlist"); + testListDirectory.set(testList); + test.getOutputs().dir(testList); // Set system property read by the UniqueIdTrackingListener. test.systemProperty(JUNIT_PLATFORM_LISTENERS_UID_TRACKING_ENABLED, true); TrackingDirectorySystemPropertyProvider directoryProvider = project.getObjects().newInstance(TrackingDirectorySystemPropertyProvider.class); @@ -588,8 +587,7 @@ public void execute(Task task) { } public abstract static class TrackingDirectorySystemPropertyProvider implements CommandLineArgumentProvider { - @InputFiles - @PathSensitive(PathSensitivity.RELATIVE) + @OutputDirectory public abstract DirectoryProperty getDirectory(); /** diff --git a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy index 2df145387..6a4638603 100644 --- a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy +++ b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy @@ -231,6 +231,13 @@ abstract class AbstractFunctionalTest extends Specification { } } + void upToDate(String... tasks) { + tasks.each { task -> + contains(task) + assert result.task(task).outcome == TaskOutcome.UP_TO_DATE + } + } + void contains(String... tasks) { tasks.each { task -> assert result.task(task) != null: "Expected to find task $task in the graph but it was missing" From 5577e30e01d2f564031f336bfca4bb7ad1459a1c Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 9 Feb 2022 15:21:52 +0100 Subject: [PATCH 07/30] Rename directory for consistency --- common/junit-platform-native/settings.gradle | 2 +- common/utils/settings.gradle.kts | 2 +- native-gradle-plugin/settings.gradle | 2 +- native-maven-plugin/settings.gradle.kts | 2 +- {build-logic => shared-build-logic}/README.md | 0 {build-logic => shared-build-logic}/build.gradle.kts | 0 {build-logic => shared-build-logic}/settings.gradle.kts | 0 .../main/kotlin/org.graalvm.build.common.settings.gradle.kts | 2 -- .../src/main/kotlin/org.graalvm.build.java.gradle.kts | 0 .../src/main/kotlin/org.graalvm.build.publishing.gradle.kts | 0 .../src/main/kotlin/org/graalvm/build/MavenExtension.kt | 0 {build-logic => shared-build-logic}/src/main/kotlin/utils.kt | 0 12 files changed, 4 insertions(+), 6 deletions(-) rename {build-logic => shared-build-logic}/README.md (100%) rename {build-logic => shared-build-logic}/build.gradle.kts (100%) rename {build-logic => shared-build-logic}/settings.gradle.kts (100%) rename {build-logic => shared-build-logic}/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts (98%) rename {build-logic => shared-build-logic}/src/main/kotlin/org.graalvm.build.java.gradle.kts (100%) rename {build-logic => shared-build-logic}/src/main/kotlin/org.graalvm.build.publishing.gradle.kts (100%) rename {build-logic => shared-build-logic}/src/main/kotlin/org/graalvm/build/MavenExtension.kt (100%) rename {build-logic => shared-build-logic}/src/main/kotlin/utils.kt (100%) diff --git a/common/junit-platform-native/settings.gradle b/common/junit-platform-native/settings.gradle index b035f2ddd..1a5db1aa3 100644 --- a/common/junit-platform-native/settings.gradle +++ b/common/junit-platform-native/settings.gradle @@ -40,7 +40,7 @@ */ pluginManagement { - includeBuild("../../build-logic") + includeBuild("../../shared-build-logic") } plugins { diff --git a/common/utils/settings.gradle.kts b/common/utils/settings.gradle.kts index 71f4aa2c0..26f08c0a4 100644 --- a/common/utils/settings.gradle.kts +++ b/common/utils/settings.gradle.kts @@ -40,7 +40,7 @@ */ pluginManagement { - includeBuild("../../build-logic") + includeBuild("../../shared-build-logic") } plugins { diff --git a/native-gradle-plugin/settings.gradle b/native-gradle-plugin/settings.gradle index 5200113e3..c7981424f 100644 --- a/native-gradle-plugin/settings.gradle +++ b/native-gradle-plugin/settings.gradle @@ -40,7 +40,7 @@ */ pluginManagement { - includeBuild("../build-logic") + includeBuild("../shared-build-logic") } plugins { diff --git a/native-maven-plugin/settings.gradle.kts b/native-maven-plugin/settings.gradle.kts index 2dfa2116a..46ca9f49d 100644 --- a/native-maven-plugin/settings.gradle.kts +++ b/native-maven-plugin/settings.gradle.kts @@ -40,7 +40,7 @@ */ pluginManagement { - includeBuild("../build-logic") + includeBuild("../shared-build-logic") includeBuild("build-plugins") } diff --git a/build-logic/README.md b/shared-build-logic/README.md similarity index 100% rename from build-logic/README.md rename to shared-build-logic/README.md diff --git a/build-logic/build.gradle.kts b/shared-build-logic/build.gradle.kts similarity index 100% rename from build-logic/build.gradle.kts rename to shared-build-logic/build.gradle.kts diff --git a/build-logic/settings.gradle.kts b/shared-build-logic/settings.gradle.kts similarity index 100% rename from build-logic/settings.gradle.kts rename to shared-build-logic/settings.gradle.kts diff --git a/build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts b/shared-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts similarity index 98% rename from build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts rename to shared-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts index 41f936f11..c95cca3b1 100644 --- a/build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts +++ b/shared-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts @@ -39,8 +39,6 @@ * SOFTWARE. */ -enableFeaturePreview("VERSION_CATALOGS") - val catalogFile = file(".").let { var baseDir = it var cur = File(baseDir, "gradle/libs.versions.toml") diff --git a/build-logic/src/main/kotlin/org.graalvm.build.java.gradle.kts b/shared-build-logic/src/main/kotlin/org.graalvm.build.java.gradle.kts similarity index 100% rename from build-logic/src/main/kotlin/org.graalvm.build.java.gradle.kts rename to shared-build-logic/src/main/kotlin/org.graalvm.build.java.gradle.kts diff --git a/build-logic/src/main/kotlin/org.graalvm.build.publishing.gradle.kts b/shared-build-logic/src/main/kotlin/org.graalvm.build.publishing.gradle.kts similarity index 100% rename from build-logic/src/main/kotlin/org.graalvm.build.publishing.gradle.kts rename to shared-build-logic/src/main/kotlin/org.graalvm.build.publishing.gradle.kts diff --git a/build-logic/src/main/kotlin/org/graalvm/build/MavenExtension.kt b/shared-build-logic/src/main/kotlin/org/graalvm/build/MavenExtension.kt similarity index 100% rename from build-logic/src/main/kotlin/org/graalvm/build/MavenExtension.kt rename to shared-build-logic/src/main/kotlin/org/graalvm/build/MavenExtension.kt diff --git a/build-logic/src/main/kotlin/utils.kt b/shared-build-logic/src/main/kotlin/utils.kt similarity index 100% rename from build-logic/src/main/kotlin/utils.kt rename to shared-build-logic/src/main/kotlin/utils.kt From 39c5a53da5814b005e1711c2f52dfbd58f16ace5 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 9 Feb 2022 15:26:23 +0100 Subject: [PATCH 08/30] Split the settings plugins into their own included build --- common/junit-platform-native/settings.gradle | 1 + common/utils/settings.gradle.kts | 1 + native-gradle-plugin/settings.gradle | 1 + native-maven-plugin/settings.gradle.kts | 1 + settings-build-logic/README.md | 3 ++ settings-build-logic/build.gradle.kts | 49 +++++++++++++++++++ settings-build-logic/settings.gradle.kts | 42 ++++++++++++++++ ...g.graalvm.build.common.settings.gradle.kts | 0 settings.gradle.kts | 4 ++ 9 files changed, 102 insertions(+) create mode 100644 settings-build-logic/README.md create mode 100644 settings-build-logic/build.gradle.kts create mode 100644 settings-build-logic/settings.gradle.kts rename {shared-build-logic => settings-build-logic}/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts (100%) diff --git a/common/junit-platform-native/settings.gradle b/common/junit-platform-native/settings.gradle index 1a5db1aa3..75caea370 100644 --- a/common/junit-platform-native/settings.gradle +++ b/common/junit-platform-native/settings.gradle @@ -40,6 +40,7 @@ */ pluginManagement { + includeBuild("../../settings-build-logic") includeBuild("../../shared-build-logic") } diff --git a/common/utils/settings.gradle.kts b/common/utils/settings.gradle.kts index 26f08c0a4..3bef54118 100644 --- a/common/utils/settings.gradle.kts +++ b/common/utils/settings.gradle.kts @@ -40,6 +40,7 @@ */ pluginManagement { + includeBuild("../../settings-build-logic") includeBuild("../../shared-build-logic") } diff --git a/native-gradle-plugin/settings.gradle b/native-gradle-plugin/settings.gradle index c7981424f..6ec92327f 100644 --- a/native-gradle-plugin/settings.gradle +++ b/native-gradle-plugin/settings.gradle @@ -40,6 +40,7 @@ */ pluginManagement { + includeBuild("../settings-build-logic") includeBuild("../shared-build-logic") } diff --git a/native-maven-plugin/settings.gradle.kts b/native-maven-plugin/settings.gradle.kts index 46ca9f49d..18268a7fb 100644 --- a/native-maven-plugin/settings.gradle.kts +++ b/native-maven-plugin/settings.gradle.kts @@ -40,6 +40,7 @@ */ pluginManagement { + includeBuild("../settings-build-logic") includeBuild("../shared-build-logic") includeBuild("build-plugins") } diff --git a/settings-build-logic/README.md b/settings-build-logic/README.md new file mode 100644 index 000000000..6f840b1f3 --- /dev/null +++ b/settings-build-logic/README.md @@ -0,0 +1,3 @@ +## Settings build logic + +This folder contains settings plugins used by the different Gradle builds in this repository. diff --git a/settings-build-logic/build.gradle.kts b/settings-build-logic/build.gradle.kts new file mode 100644 index 000000000..e1fc239a9 --- /dev/null +++ b/settings-build-logic/build.gradle.kts @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() + gradlePluginPortal() +} diff --git a/settings-build-logic/settings.gradle.kts b/settings-build-logic/settings.gradle.kts new file mode 100644 index 000000000..3b58b5ad9 --- /dev/null +++ b/settings-build-logic/settings.gradle.kts @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +rootProject.name = "settings-build-logic" diff --git a/shared-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts b/settings-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts similarity index 100% rename from shared-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts rename to settings-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts diff --git a/settings.gradle.kts b/settings.gradle.kts index 4f198c5be..4a17fa04d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -39,6 +39,10 @@ * SOFTWARE. */ +pluginManagement { + includeBuild("settings-build-logic") +} + rootProject.name = "native-build-tools" includeBuild("common/junit-platform-native") From 058122263b13475073f600acbc0bfa5cf9192c55 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 9 Feb 2022 15:50:11 +0100 Subject: [PATCH 09/30] Replace main build buildSrc with included build --- build.gradle.kts | 125 +----------- gradle/wrapper/gradle-wrapper.properties | 2 +- .../build.gradle.kts | 0 .../settings.gradle.kts | 15 +- .../org.graalvm.build.aggregator.gradle.kts | 180 ++++++++++++++++++ .../build/samples/SamplesUpdateTask.kt | 0 .../graalvm/build/tasks/AbstractGitTask.kt | 0 .../kotlin/org/graalvm/build/tasks/GitAdd.kt | 0 .../org/graalvm/build/tasks/GitClone.kt | 0 .../org/graalvm/build/tasks/GitCommit.kt | 0 .../kotlin/org/graalvm/build/tasks/GitPush.kt | 0 .../org/graalvm/build/tasks/GitReset.kt | 0 ...g.graalvm.build.common.settings.gradle.kts | 2 + settings.gradle.kts | 1 + 14 files changed, 192 insertions(+), 133 deletions(-) rename {buildSrc => main-build-logic}/build.gradle.kts (100%) rename {buildSrc => main-build-logic}/settings.gradle.kts (91%) create mode 100644 main-build-logic/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts rename {buildSrc => main-build-logic}/src/main/kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt (100%) rename {buildSrc => main-build-logic}/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt (100%) rename {buildSrc => main-build-logic}/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt (100%) rename {buildSrc => main-build-logic}/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt (100%) rename {buildSrc => main-build-logic}/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt (100%) rename {buildSrc => main-build-logic}/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt (100%) rename {buildSrc => main-build-logic}/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt (100%) diff --git a/build.gradle.kts b/build.gradle.kts index fa5b53ee5..eb56a0a89 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -40,128 +40,5 @@ */ plugins { - base -} - -tasks.named("clean") { - gradle.includedBuilds.forEach { - dependsOn(it.task(":clean")) - } -} - -tasks.register("test") { - gradle.includedBuilds.forEach { - dependsOn(it.task(":test")) - } -} - -tasks.register("inspections") { - gradle.includedBuilds.forEach { - dependsOn(it.task(":inspections")) - } -} - -tasks.named("check") { - gradle.includedBuilds.forEach { - dependsOn(it.task(":check")) - } -} - -listOf( - "publishTo" to "MavenLocal", - "publishAllPublicationsTo" to "CommonRepository", - "publishAllPublicationsTo" to "SnapshotsRepository", -).forEach { entry -> - val (taskPrefix, repo) = entry - tasks.register("$taskPrefix$repo") { - description = "Publishes all artifacts to the ${repo.decapitalize()} repository" - group = PublishingPlugin.PUBLISH_TASK_GROUP - gradle.includedBuilds.forEach { - if (it.name != "docs") { - dependsOn(it.task(":$taskPrefix$repo")) - } - } - doFirst { - if (gradle.startParameter.isParallelProjectExecutionEnabled) { - throw RuntimeException("Publishing should be done using --no-parallel") - } - } - } -} - -val commonRepo = layout.buildDirectory.dir("common-repo") -val snapshotsRepo = layout.buildDirectory.dir("snapshots") - -val pruneCommonRepo = tasks.register("pruneCommonRepository") { - delete(commonRepo) -} - -tasks.register("releaseZip") { - archiveVersion.set(libs.versions.nativeBuildTools) - dependsOn(pruneCommonRepo, "publishAllPublicationsToCommonRepository") - from(commonRepo) { - exclude("**/*.sha256") - exclude("**/*.sha512") - } -} - -val updateSamples by tasks.registering - -mapOf( - "updateSamplesDir" to "samples", - "updateMavenReprosDir" to "native-maven-plugin/reproducers" -).forEach { taskName, dir -> - val t = tasks.register(taskName) { - inputDirectory.set(layout.projectDirectory.dir(dir)) - versions.put("native.gradle.plugin.version", libs.versions.nativeBuildTools.get()) - versions.put("native.maven.plugin.version", libs.versions.nativeBuildTools.get()) - versions.put("junit.jupiter.version", libs.versions.junitJupiter.get()) - versions.put("junit.platform.version", libs.versions.junitPlatform.get()) - versions.put("junit.platform.native.version", libs.versions.nativeBuildTools.get()) - } - updateSamples.configure { - dependsOn(t) - } -} - - -val cloneSnapshots = tasks.register("cloneSnapshotRepository") { - repositoryUri.set("git@github.com:graalvm/native-build-tools.git") -// repositoryUri.set(file(".").absolutePath) - repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) - branch.set("snapshots") -} - -val prepareRepository = tasks.register("resetHead") { - dependsOn(cloneSnapshots) - repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) - mode.set(org.eclipse.jgit.api.ResetCommand.ResetType.HARD) - ref.set("25ecdec020f57dbe980eeb052c71659ccd0d9bcc") -} - -val addSnapshots = tasks.register("addSnapshots") { - dependsOn(prepareRepository) - repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) - pattern.set("org/") -} - -val commitSnapshots = tasks.register("commitSnapshots") { - dependsOn(addSnapshots) - repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) - message.set("Publishing new snapshot") - amend.set(false) -} - -val pushSnapshots = tasks.register("pushSnapshots") { - dependsOn(commitSnapshots) - repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) - force.set(true) -} - -tasks.named("publishAllPublicationsToSnapshotsRepository") { - dependsOn(prepareRepository) - finalizedBy(pushSnapshots) - onlyIf { - libs.versions.nativeBuildTools.get().endsWith("-SNAPSHOT") - } + id("org.graalvm.build.aggregator") } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 41dfb8790..0f80bbf51 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/buildSrc/build.gradle.kts b/main-build-logic/build.gradle.kts similarity index 100% rename from buildSrc/build.gradle.kts rename to main-build-logic/build.gradle.kts diff --git a/buildSrc/settings.gradle.kts b/main-build-logic/settings.gradle.kts similarity index 91% rename from buildSrc/settings.gradle.kts rename to main-build-logic/settings.gradle.kts index 7c698df20..91c99da1d 100644 --- a/buildSrc/settings.gradle.kts +++ b/main-build-logic/settings.gradle.kts @@ -39,13 +39,12 @@ * SOFTWARE. */ +pluginManagement { + includeBuild("../settings-build-logic") +} -enableFeaturePreview("VERSION_CATALOGS") - -dependencyResolutionManagement { - versionCatalogs { - create("libs") { - from(files("../gradle/libs.versions.toml")) - } - } +plugins { + id("org.graalvm.build.common") } + +rootProject.name = "main-build-logic" diff --git a/main-build-logic/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts b/main-build-logic/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts new file mode 100644 index 000000000..6e753ca45 --- /dev/null +++ b/main-build-logic/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts @@ -0,0 +1,180 @@ +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.api.publish.plugins.PublishingPlugin +import org.gradle.api.tasks.Delete +import org.gradle.api.tasks.bundling.Zip +import org.gradle.kotlin.dsl.* + +/* + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +plugins { + base +} + +tasks.named("clean") { + gradle.includedBuilds.forEach { + dependsOn(it.task(":clean")) + } +} + +tasks.register("test") { + gradle.includedBuilds.forEach { + dependsOn(it.task(":test")) + } +} + +tasks.register("inspections") { + gradle.includedBuilds.forEach { + dependsOn(it.task(":inspections")) + } +} + +tasks.named("check") { + gradle.includedBuilds.forEach { + dependsOn(it.task(":check")) + } +} + +listOf( + "publishTo" to "MavenLocal", + "publishAllPublicationsTo" to "CommonRepository", + "publishAllPublicationsTo" to "SnapshotsRepository", +).forEach { entry -> + val (taskPrefix, repo) = entry + tasks.register("$taskPrefix$repo") { + description = "Publishes all artifacts to the ${repo.decapitalize()} repository" + group = PublishingPlugin.PUBLISH_TASK_GROUP + gradle.includedBuilds.forEach { + if (it.name != "docs") { + dependsOn(it.task(":$taskPrefix$repo")) + } + } + doFirst { + if (gradle.startParameter.isParallelProjectExecutionEnabled) { + throw RuntimeException("Publishing should be done using --no-parallel") + } + } + } +} + +val commonRepo = layout.buildDirectory.dir("common-repo") +val snapshotsRepo = layout.buildDirectory.dir("snapshots") + +val pruneCommonRepo = tasks.register("pruneCommonRepository") { + delete(commonRepo) +} + +val catalogs = extensions.getByType() +val libs = catalogs.named("libs") + +val nativeBuildToolsVersion = libs.findVersion("nativeBuildTools").get().requiredVersion +val junitJupiterVersion = libs.findVersion("junitJupiter").get().requiredVersion +val junitPlatformVersion = libs.findVersion("junitPlatform").get().requiredVersion + +tasks.register("releaseZip") { + archiveVersion.set(nativeBuildToolsVersion) + dependsOn(pruneCommonRepo, "publishAllPublicationsToCommonRepository") + from(commonRepo) { + exclude("**/*.sha256") + exclude("**/*.sha512") + } +} + +val updateSamples by tasks.registering + +mapOf( + "updateSamplesDir" to "samples", + "updateMavenReprosDir" to "native-maven-plugin/reproducers" +).forEach { taskName, dir -> + val t = tasks.register(taskName) { + inputDirectory.set(layout.projectDirectory.dir(dir)) + versions.put("native.gradle.plugin.version", nativeBuildToolsVersion) + versions.put("native.maven.plugin.version", nativeBuildToolsVersion) + versions.put("junit.jupiter.version", junitJupiterVersion) + versions.put("junit.platform.version", junitPlatformVersion) + versions.put("junit.platform.native.version", nativeBuildToolsVersion) + } + updateSamples.configure { + dependsOn(t) + } +} + + +val cloneSnapshots = tasks.register("cloneSnapshotRepository") { + repositoryUri.set("git@github.com:graalvm/native-build-tools.git") +// repositoryUri.set(file(".").absolutePath) + repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) + branch.set("snapshots") +} + +val prepareRepository = tasks.register("resetHead") { + dependsOn(cloneSnapshots) + repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) + mode.set(org.eclipse.jgit.api.ResetCommand.ResetType.HARD) + ref.set("25ecdec020f57dbe980eeb052c71659ccd0d9bcc") +} + +val addSnapshots = tasks.register("addSnapshots") { + dependsOn(prepareRepository) + repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) + pattern.set("org/") +} + +val commitSnapshots = tasks.register("commitSnapshots") { + dependsOn(addSnapshots) + repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) + message.set("Publishing new snapshot") + amend.set(false) +} + +val pushSnapshots = tasks.register("pushSnapshots") { + dependsOn(commitSnapshots) + repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) + force.set(true) +} + +tasks.named("publishAllPublicationsToSnapshotsRepository") { + dependsOn(prepareRepository) + finalizedBy(pushSnapshots) + onlyIf { + nativeBuildToolsVersion.endsWith("-SNAPSHOT") + } +} diff --git a/buildSrc/src/main/kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt b/main-build-logic/src/main/kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt similarity index 100% rename from buildSrc/src/main/kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt rename to main-build-logic/src/main/kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt diff --git a/buildSrc/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt b/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt similarity index 100% rename from buildSrc/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt rename to main-build-logic/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt diff --git a/buildSrc/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt b/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt similarity index 100% rename from buildSrc/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt rename to main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt diff --git a/buildSrc/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt b/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt similarity index 100% rename from buildSrc/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt rename to main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt diff --git a/buildSrc/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt b/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt similarity index 100% rename from buildSrc/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt rename to main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt diff --git a/buildSrc/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt b/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt similarity index 100% rename from buildSrc/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt rename to main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt diff --git a/buildSrc/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt b/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt similarity index 100% rename from buildSrc/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt rename to main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt diff --git a/settings-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts b/settings-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts index c95cca3b1..41f936f11 100644 --- a/settings-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts +++ b/settings-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts @@ -39,6 +39,8 @@ * SOFTWARE. */ +enableFeaturePreview("VERSION_CATALOGS") + val catalogFile = file(".").let { var baseDir = it var cur = File(baseDir, "gradle/libs.versions.toml") diff --git a/settings.gradle.kts b/settings.gradle.kts index 4a17fa04d..e222add9d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -41,6 +41,7 @@ pluginManagement { includeBuild("settings-build-logic") + includeBuild("main-build-logic") } rootProject.name = "native-build-tools" From 86f82645e9160ae583b5b87d717dc9728de20412 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 9 Feb 2022 16:00:00 +0100 Subject: [PATCH 10/30] Move build logic into their own subdirectory This makes it easier to spot the Gradle plugin logic from regular modules. --- {main-build-logic => build-logic/aggregator}/build.gradle.kts | 0 .../aggregator}/settings.gradle.kts | 4 ++-- .../src/main/kotlin/org.graalvm.build.aggregator.gradle.kts | 0 .../kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt | 0 .../main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt | 0 .../src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt | 0 .../src/main/kotlin/org/graalvm/build/tasks/GitClone.kt | 0 .../src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt | 0 .../src/main/kotlin/org/graalvm/build/tasks/GitPush.kt | 0 .../src/main/kotlin/org/graalvm/build/tasks/GitReset.kt | 0 {shared-build-logic => build-logic/common-plugins}/README.md | 0 .../common-plugins}/build.gradle.kts | 0 .../common-plugins}/settings.gradle.kts | 2 +- .../src/main/kotlin/org.graalvm.build.java.gradle.kts | 0 .../src/main/kotlin/org.graalvm.build.publishing.gradle.kts | 0 .../src/main/kotlin/org/graalvm/build/MavenExtension.kt | 0 .../common-plugins}/src/main/kotlin/utils.kt | 0 .../settings-plugins}/README.md | 0 .../settings-plugins}/build.gradle.kts | 0 .../settings-plugins}/settings.gradle.kts | 2 +- .../main/kotlin/org.graalvm.build.common.settings.gradle.kts | 0 common/junit-platform-native/settings.gradle | 4 ++-- common/utils/settings.gradle.kts | 4 ++-- native-gradle-plugin/settings.gradle | 4 ++-- native-maven-plugin/settings.gradle.kts | 4 ++-- settings.gradle.kts | 4 ++-- 26 files changed, 14 insertions(+), 14 deletions(-) rename {main-build-logic => build-logic/aggregator}/build.gradle.kts (100%) rename {main-build-logic => build-logic/aggregator}/settings.gradle.kts (96%) rename {main-build-logic => build-logic/aggregator}/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts (100%) rename {main-build-logic => build-logic/aggregator}/src/main/kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt (100%) rename {main-build-logic => build-logic/aggregator}/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt (100%) rename {main-build-logic => build-logic/aggregator}/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt (100%) rename {main-build-logic => build-logic/aggregator}/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt (100%) rename {main-build-logic => build-logic/aggregator}/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt (100%) rename {main-build-logic => build-logic/aggregator}/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt (100%) rename {main-build-logic => build-logic/aggregator}/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt (100%) rename {shared-build-logic => build-logic/common-plugins}/README.md (100%) rename {settings-build-logic => build-logic/common-plugins}/build.gradle.kts (100%) rename {shared-build-logic => build-logic/common-plugins}/settings.gradle.kts (98%) rename {shared-build-logic => build-logic/common-plugins}/src/main/kotlin/org.graalvm.build.java.gradle.kts (100%) rename {shared-build-logic => build-logic/common-plugins}/src/main/kotlin/org.graalvm.build.publishing.gradle.kts (100%) rename {shared-build-logic => build-logic/common-plugins}/src/main/kotlin/org/graalvm/build/MavenExtension.kt (100%) rename {shared-build-logic => build-logic/common-plugins}/src/main/kotlin/utils.kt (100%) rename {settings-build-logic => build-logic/settings-plugins}/README.md (100%) rename {shared-build-logic => build-logic/settings-plugins}/build.gradle.kts (100%) rename {settings-build-logic => build-logic/settings-plugins}/settings.gradle.kts (97%) rename {settings-build-logic => build-logic/settings-plugins}/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts (100%) diff --git a/main-build-logic/build.gradle.kts b/build-logic/aggregator/build.gradle.kts similarity index 100% rename from main-build-logic/build.gradle.kts rename to build-logic/aggregator/build.gradle.kts diff --git a/main-build-logic/settings.gradle.kts b/build-logic/aggregator/settings.gradle.kts similarity index 96% rename from main-build-logic/settings.gradle.kts rename to build-logic/aggregator/settings.gradle.kts index 91c99da1d..fa0b001d6 100644 --- a/main-build-logic/settings.gradle.kts +++ b/build-logic/aggregator/settings.gradle.kts @@ -40,11 +40,11 @@ */ pluginManagement { - includeBuild("../settings-build-logic") + includeBuild("../settings-plugins") } plugins { id("org.graalvm.build.common") } -rootProject.name = "main-build-logic" +rootProject.name = "aggregator" diff --git a/main-build-logic/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts b/build-logic/aggregator/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts similarity index 100% rename from main-build-logic/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts rename to build-logic/aggregator/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts diff --git a/main-build-logic/src/main/kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt similarity index 100% rename from main-build-logic/src/main/kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt rename to build-logic/aggregator/src/main/kotlin/org/graalvm/build/samples/SamplesUpdateTask.kt diff --git a/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt similarity index 100% rename from main-build-logic/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt rename to build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt diff --git a/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt similarity index 100% rename from main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt rename to build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt diff --git a/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt similarity index 100% rename from main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt rename to build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt diff --git a/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt similarity index 100% rename from main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt rename to build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt diff --git a/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt similarity index 100% rename from main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt rename to build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt diff --git a/main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt similarity index 100% rename from main-build-logic/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt rename to build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt diff --git a/shared-build-logic/README.md b/build-logic/common-plugins/README.md similarity index 100% rename from shared-build-logic/README.md rename to build-logic/common-plugins/README.md diff --git a/settings-build-logic/build.gradle.kts b/build-logic/common-plugins/build.gradle.kts similarity index 100% rename from settings-build-logic/build.gradle.kts rename to build-logic/common-plugins/build.gradle.kts diff --git a/shared-build-logic/settings.gradle.kts b/build-logic/common-plugins/settings.gradle.kts similarity index 98% rename from shared-build-logic/settings.gradle.kts rename to build-logic/common-plugins/settings.gradle.kts index 6ff2fa7b1..f1a9e711e 100644 --- a/shared-build-logic/settings.gradle.kts +++ b/build-logic/common-plugins/settings.gradle.kts @@ -39,4 +39,4 @@ * SOFTWARE. */ -rootProject.name = "shared-build-logic" +rootProject.name = "common-plugins" diff --git a/shared-build-logic/src/main/kotlin/org.graalvm.build.java.gradle.kts b/build-logic/common-plugins/src/main/kotlin/org.graalvm.build.java.gradle.kts similarity index 100% rename from shared-build-logic/src/main/kotlin/org.graalvm.build.java.gradle.kts rename to build-logic/common-plugins/src/main/kotlin/org.graalvm.build.java.gradle.kts diff --git a/shared-build-logic/src/main/kotlin/org.graalvm.build.publishing.gradle.kts b/build-logic/common-plugins/src/main/kotlin/org.graalvm.build.publishing.gradle.kts similarity index 100% rename from shared-build-logic/src/main/kotlin/org.graalvm.build.publishing.gradle.kts rename to build-logic/common-plugins/src/main/kotlin/org.graalvm.build.publishing.gradle.kts diff --git a/shared-build-logic/src/main/kotlin/org/graalvm/build/MavenExtension.kt b/build-logic/common-plugins/src/main/kotlin/org/graalvm/build/MavenExtension.kt similarity index 100% rename from shared-build-logic/src/main/kotlin/org/graalvm/build/MavenExtension.kt rename to build-logic/common-plugins/src/main/kotlin/org/graalvm/build/MavenExtension.kt diff --git a/shared-build-logic/src/main/kotlin/utils.kt b/build-logic/common-plugins/src/main/kotlin/utils.kt similarity index 100% rename from shared-build-logic/src/main/kotlin/utils.kt rename to build-logic/common-plugins/src/main/kotlin/utils.kt diff --git a/settings-build-logic/README.md b/build-logic/settings-plugins/README.md similarity index 100% rename from settings-build-logic/README.md rename to build-logic/settings-plugins/README.md diff --git a/shared-build-logic/build.gradle.kts b/build-logic/settings-plugins/build.gradle.kts similarity index 100% rename from shared-build-logic/build.gradle.kts rename to build-logic/settings-plugins/build.gradle.kts diff --git a/settings-build-logic/settings.gradle.kts b/build-logic/settings-plugins/settings.gradle.kts similarity index 97% rename from settings-build-logic/settings.gradle.kts rename to build-logic/settings-plugins/settings.gradle.kts index 3b58b5ad9..4522ec5a5 100644 --- a/settings-build-logic/settings.gradle.kts +++ b/build-logic/settings-plugins/settings.gradle.kts @@ -39,4 +39,4 @@ * SOFTWARE. */ -rootProject.name = "settings-build-logic" +rootProject.name = "settings-plugins" diff --git a/settings-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts b/build-logic/settings-plugins/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts similarity index 100% rename from settings-build-logic/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts rename to build-logic/settings-plugins/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts diff --git a/common/junit-platform-native/settings.gradle b/common/junit-platform-native/settings.gradle index 75caea370..2282a95b7 100644 --- a/common/junit-platform-native/settings.gradle +++ b/common/junit-platform-native/settings.gradle @@ -40,8 +40,8 @@ */ pluginManagement { - includeBuild("../../settings-build-logic") - includeBuild("../../shared-build-logic") + includeBuild("../../build-logic/settings-plugins") + includeBuild("../../build-logic/common-plugins") } plugins { diff --git a/common/utils/settings.gradle.kts b/common/utils/settings.gradle.kts index 3bef54118..c52c277c8 100644 --- a/common/utils/settings.gradle.kts +++ b/common/utils/settings.gradle.kts @@ -40,8 +40,8 @@ */ pluginManagement { - includeBuild("../../settings-build-logic") - includeBuild("../../shared-build-logic") + includeBuild("../../build-logic/settings-plugins") + includeBuild("../../build-logic/common-plugins") } plugins { diff --git a/native-gradle-plugin/settings.gradle b/native-gradle-plugin/settings.gradle index 6ec92327f..430f855e1 100644 --- a/native-gradle-plugin/settings.gradle +++ b/native-gradle-plugin/settings.gradle @@ -40,8 +40,8 @@ */ pluginManagement { - includeBuild("../settings-build-logic") - includeBuild("../shared-build-logic") + includeBuild("../build-logic/settings-plugins") + includeBuild("../build-logic/common-plugins") } plugins { diff --git a/native-maven-plugin/settings.gradle.kts b/native-maven-plugin/settings.gradle.kts index 18268a7fb..e9bc7eba9 100644 --- a/native-maven-plugin/settings.gradle.kts +++ b/native-maven-plugin/settings.gradle.kts @@ -40,8 +40,8 @@ */ pluginManagement { - includeBuild("../settings-build-logic") - includeBuild("../shared-build-logic") + includeBuild("../build-logic/settings-plugins") + includeBuild("../build-logic/common-plugins") includeBuild("build-plugins") } diff --git a/settings.gradle.kts b/settings.gradle.kts index e222add9d..d47487278 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -40,8 +40,8 @@ */ pluginManagement { - includeBuild("settings-build-logic") - includeBuild("main-build-logic") + includeBuild("build-logic/settings-plugins") + includeBuild("build-logic/aggregator") } rootProject.name = "native-build-tools" From c5519203b9651a35682e09882539d6666a010f8a Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 9 Feb 2022 16:08:39 +0100 Subject: [PATCH 11/30] Move docs buildSrc into an included build --- .../documentation-plugins}/build.gradle.kts | 0 .../documentation-plugins/settings.gradle.kts | 42 +++++++++++++++++++ ...org.graalvm.build.documentation.gradle.kts | 0 docs/settings.gradle.kts | 18 ++++---- 4 files changed, 51 insertions(+), 9 deletions(-) rename {docs/buildSrc => build-logic/documentation-plugins}/build.gradle.kts (100%) create mode 100644 build-logic/documentation-plugins/settings.gradle.kts rename {docs/buildSrc => build-logic/documentation-plugins}/src/main/kotlin/org.graalvm.build.documentation.gradle.kts (100%) diff --git a/docs/buildSrc/build.gradle.kts b/build-logic/documentation-plugins/build.gradle.kts similarity index 100% rename from docs/buildSrc/build.gradle.kts rename to build-logic/documentation-plugins/build.gradle.kts diff --git a/build-logic/documentation-plugins/settings.gradle.kts b/build-logic/documentation-plugins/settings.gradle.kts new file mode 100644 index 000000000..28cc07a6a --- /dev/null +++ b/build-logic/documentation-plugins/settings.gradle.kts @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +rootProject.name = "documentation-plugins" diff --git a/docs/buildSrc/src/main/kotlin/org.graalvm.build.documentation.gradle.kts b/build-logic/documentation-plugins/src/main/kotlin/org.graalvm.build.documentation.gradle.kts similarity index 100% rename from docs/buildSrc/src/main/kotlin/org.graalvm.build.documentation.gradle.kts rename to build-logic/documentation-plugins/src/main/kotlin/org.graalvm.build.documentation.gradle.kts diff --git a/docs/settings.gradle.kts b/docs/settings.gradle.kts index f322595fe..97a4660ea 100644 --- a/docs/settings.gradle.kts +++ b/docs/settings.gradle.kts @@ -39,16 +39,16 @@ * SOFTWARE. */ -rootProject.name = "docs" - -enableFeaturePreview("VERSION_CATALOGS") +pluginManagement { + includeBuild("../build-logic/settings-plugins") + includeBuild("../build-logic/documentation-plugins") +} -dependencyResolutionManagement { - versionCatalogs { - create("libs") { - from(files("../gradle/libs.versions.toml")) - } - } +plugins { + id("org.graalvm.build.common") } +rootProject.name = "docs" + includeBuild("../native-gradle-plugin") +includeBuild("../native-maven-plugin") From a05cdccedd3db90851e3542695ac16dfc9bae706 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 9 Feb 2022 16:55:54 +0100 Subject: [PATCH 12/30] Move utils buildSrc into an included build --- .../kotlin/org.graalvm.build.java.gradle.kts | 17 ++-- .../utils-plugins}/build.gradle.kts | 12 ++- build-logic/utils-plugins/settings.gradle.kts | 52 ++++++++++++ .../graalvm/build/GenerateVersionClass.java | 0 .../org.graalvm.build.utils-module.gradle.kts | 83 +++++++++++++++++++ .../resources/org/graalvm/build/header.txt | 0 common/utils/build.gradle.kts | 33 +------- common/utils/settings.gradle.kts | 1 + 8 files changed, 157 insertions(+), 41 deletions(-) rename {common/utils/buildSrc => build-logic/utils-plugins}/build.gradle.kts (93%) create mode 100644 build-logic/utils-plugins/settings.gradle.kts rename {common/utils/buildSrc => build-logic/utils-plugins}/src/main/java/org/graalvm/build/GenerateVersionClass.java (100%) create mode 100644 build-logic/utils-plugins/src/main/kotlin/org.graalvm.build.utils-module.gradle.kts rename {common/utils/buildSrc => build-logic/utils-plugins}/src/main/resources/org/graalvm/build/header.txt (100%) diff --git a/build-logic/common-plugins/src/main/kotlin/org.graalvm.build.java.gradle.kts b/build-logic/common-plugins/src/main/kotlin/org.graalvm.build.java.gradle.kts index bbef2d9df..f7d4ae4d3 100644 --- a/build-logic/common-plugins/src/main/kotlin/org.graalvm.build.java.gradle.kts +++ b/build-logic/common-plugins/src/main/kotlin/org.graalvm.build.java.gradle.kts @@ -61,15 +61,16 @@ repositories { mavenCentral() } -val versionFromCatalog = extensions.getByType() - .named("libs") - .findVersion("nativeBuildTools") - group = "org.graalvm.buildtools" -if (versionFromCatalog.isPresent()) { - version = versionFromCatalog.get().requiredVersion -} else { - throw GradleException("Version catalog doesn't define project version 'nativeBuildTools'") + +extensions.findByType()?.also { catalogs -> + val versionFromCatalog = catalogs.named("libs") + .findVersion("nativeBuildTools") + if (versionFromCatalog.isPresent()) { + version = versionFromCatalog.get().requiredVersion + } else { + throw GradleException("Version catalog doesn't define project version 'nativeBuildTools'") + } } tasks.javadoc { diff --git a/common/utils/buildSrc/build.gradle.kts b/build-logic/utils-plugins/build.gradle.kts similarity index 93% rename from common/utils/buildSrc/build.gradle.kts rename to build-logic/utils-plugins/build.gradle.kts index fb014c67e..9b5dc2dd0 100644 --- a/common/utils/buildSrc/build.gradle.kts +++ b/build-logic/utils-plugins/build.gradle.kts @@ -40,5 +40,15 @@ */ plugins { - `java-gradle-plugin` + java + `kotlin-dsl` +} + +repositories { + mavenCentral() + gradlePluginPortal() +} + +dependencies { + implementation(":common-plugins") } diff --git a/build-logic/utils-plugins/settings.gradle.kts b/build-logic/utils-plugins/settings.gradle.kts new file mode 100644 index 000000000..3d2a504db --- /dev/null +++ b/build-logic/utils-plugins/settings.gradle.kts @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +rootProject.name = "utils-plugins" + +pluginManagement { + includeBuild("../settings-plugins") +} + +includeBuild("../common-plugins") + +plugins { + id("org.graalvm.build.common") +} diff --git a/common/utils/buildSrc/src/main/java/org/graalvm/build/GenerateVersionClass.java b/build-logic/utils-plugins/src/main/java/org/graalvm/build/GenerateVersionClass.java similarity index 100% rename from common/utils/buildSrc/src/main/java/org/graalvm/build/GenerateVersionClass.java rename to build-logic/utils-plugins/src/main/java/org/graalvm/build/GenerateVersionClass.java diff --git a/build-logic/utils-plugins/src/main/kotlin/org.graalvm.build.utils-module.gradle.kts b/build-logic/utils-plugins/src/main/kotlin/org.graalvm.build.utils-module.gradle.kts new file mode 100644 index 000000000..1eca1254c --- /dev/null +++ b/build-logic/utils-plugins/src/main/kotlin/org.graalvm.build.utils-module.gradle.kts @@ -0,0 +1,83 @@ +import org.gradle.api.plugins.quality.Checkstyle +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.tasks.testing.Test +import org.gradle.kotlin.dsl.* + +/* + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +plugins { + checkstyle + id("org.graalvm.build.java") + id("org.graalvm.build.publishing") +} + +tasks.withType().configureEach { + useJUnitPlatform() +} + +extensions.findByType()?.also { catalogs -> + val libs = catalogs.named("libs") + val generateVersionInfo = tasks.register("generateVersionInfo", org.graalvm.build.GenerateVersionClass::class.java) { + versions.put("junitPlatformNative", libs.findVersion("nativeBuildTools").get().requiredVersion) + outputDirectory.set(layout.buildDirectory.dir("generated/sources/versions")) + } + + sourceSets { + main { + java { + srcDir(generateVersionInfo) + } + } + } +} + +publishing { + publications { + create("maven") { + from(components["java"]) + } + } +} + +tasks.withType().configureEach { + setConfigFile(layout.projectDirectory.dir("../../config/checkstyle.xml").asFile) +} diff --git a/common/utils/buildSrc/src/main/resources/org/graalvm/build/header.txt b/build-logic/utils-plugins/src/main/resources/org/graalvm/build/header.txt similarity index 100% rename from common/utils/buildSrc/src/main/resources/org/graalvm/build/header.txt rename to build-logic/utils-plugins/src/main/resources/org/graalvm/build/header.txt diff --git a/common/utils/build.gradle.kts b/common/utils/build.gradle.kts index c13ecad8f..d13cf9137 100644 --- a/common/utils/build.gradle.kts +++ b/common/utils/build.gradle.kts @@ -40,9 +40,7 @@ */ plugins { - checkstyle - id("org.graalvm.build.java") - id("org.graalvm.build.publishing") + id("org.graalvm.build.utils-module") } maven { @@ -55,32 +53,3 @@ dependencies { implementation(platform(libs.test.junit.bom)) implementation(libs.test.junit.jupiter.core) } - -tasks.withType().configureEach { - useJUnitPlatform() -} - -val generateVersionInfo = tasks.register("generateVersionInfo", org.graalvm.build.GenerateVersionClass::class.java) { - versions.put("junitPlatformNative", libs.versions.nativeBuildTools) - outputDirectory.set(layout.buildDirectory.dir("generated/sources/versions")) -} - -sourceSets { - main { - java { - srcDir(generateVersionInfo) - } - } -} - -publishing { - publications { - create("maven") { - from(components["java"]) - } - } -} - -tasks.withType().configureEach { - setConfigFile(layout.projectDirectory.dir("../../config/checkstyle.xml").asFile) -} diff --git a/common/utils/settings.gradle.kts b/common/utils/settings.gradle.kts index c52c277c8..47bad796b 100644 --- a/common/utils/settings.gradle.kts +++ b/common/utils/settings.gradle.kts @@ -42,6 +42,7 @@ pluginManagement { includeBuild("../../build-logic/settings-plugins") includeBuild("../../build-logic/common-plugins") + includeBuild("../../build-logic/utils-plugins") } plugins { From 6839fef765215620afa3ea7e6304795698c730be Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 9 Feb 2022 17:45:33 +0100 Subject: [PATCH 13/30] Move the native-gradle-plugin buildSrc directory into a composite build --- .../gradle-functional-testing}/build.gradle | 0 build-logic/gradle-functional-testing/settings.gradle | 1 + .../src/main/groovy/org.graalvm.build.functional-testing.gradle | 1 + native-gradle-plugin/settings.gradle | 1 + 4 files changed, 3 insertions(+) rename {native-gradle-plugin/buildSrc => build-logic/gradle-functional-testing}/build.gradle (100%) create mode 100644 build-logic/gradle-functional-testing/settings.gradle rename {native-gradle-plugin/buildSrc => build-logic/gradle-functional-testing}/src/main/groovy/org.graalvm.build.functional-testing.gradle (99%) diff --git a/native-gradle-plugin/buildSrc/build.gradle b/build-logic/gradle-functional-testing/build.gradle similarity index 100% rename from native-gradle-plugin/buildSrc/build.gradle rename to build-logic/gradle-functional-testing/build.gradle diff --git a/build-logic/gradle-functional-testing/settings.gradle b/build-logic/gradle-functional-testing/settings.gradle new file mode 100644 index 000000000..210a9caaf --- /dev/null +++ b/build-logic/gradle-functional-testing/settings.gradle @@ -0,0 +1 @@ +rootProject.name = "gradle-functional-testing" diff --git a/native-gradle-plugin/buildSrc/src/main/groovy/org.graalvm.build.functional-testing.gradle b/build-logic/gradle-functional-testing/src/main/groovy/org.graalvm.build.functional-testing.gradle similarity index 99% rename from native-gradle-plugin/buildSrc/src/main/groovy/org.graalvm.build.functional-testing.gradle rename to build-logic/gradle-functional-testing/src/main/groovy/org.graalvm.build.functional-testing.gradle index 54e4c8078..459302f56 100644 --- a/native-gradle-plugin/buildSrc/src/main/groovy/org.graalvm.build.functional-testing.gradle +++ b/build-logic/gradle-functional-testing/src/main/groovy/org.graalvm.build.functional-testing.gradle @@ -49,6 +49,7 @@ */ plugins { + id 'java-gradle-plugin' id 'groovy' } diff --git a/native-gradle-plugin/settings.gradle b/native-gradle-plugin/settings.gradle index 430f855e1..165d7091d 100644 --- a/native-gradle-plugin/settings.gradle +++ b/native-gradle-plugin/settings.gradle @@ -42,6 +42,7 @@ pluginManagement { includeBuild("../build-logic/settings-plugins") includeBuild("../build-logic/common-plugins") + includeBuild("../build-logic/gradle-functional-testing") } plugins { From b02e84fd5f94d13f9b2c658d8bd96d69bc00ee6d Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 9 Feb 2022 17:48:28 +0100 Subject: [PATCH 14/30] Restore upgrade to Gradle 7.4 Now that everything uses composites and no `buildSrc` anymore, import of the project into IntelliJ works again. --- .../main/kotlin/org.graalvm.build.common.settings.gradle.kts | 2 -- .../buildtools/model/resources/ClassPathDirectoryAnalyzer.java | 3 +-- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/build-logic/settings-plugins/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts b/build-logic/settings-plugins/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts index 41f936f11..c95cca3b1 100644 --- a/build-logic/settings-plugins/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts +++ b/build-logic/settings-plugins/src/main/kotlin/org.graalvm.build.common.settings.gradle.kts @@ -39,8 +39,6 @@ * SOFTWARE. */ -enableFeaturePreview("VERSION_CATALOGS") - val catalogFile = file(".").let { var baseDir = it var cur = File(baseDir, "gradle/libs.versions.toml") diff --git a/common/utils/src/main/java/org/graalvm/buildtools/model/resources/ClassPathDirectoryAnalyzer.java b/common/utils/src/main/java/org/graalvm/buildtools/model/resources/ClassPathDirectoryAnalyzer.java index b7c016516..39a7f7bbf 100644 --- a/common/utils/src/main/java/org/graalvm/buildtools/model/resources/ClassPathDirectoryAnalyzer.java +++ b/common/utils/src/main/java/org/graalvm/buildtools/model/resources/ClassPathDirectoryAnalyzer.java @@ -68,8 +68,7 @@ protected List initialize() throws IOException { DirectoryVisitor visitor = new DirectoryVisitor(); Files.walkFileTree(root, visitor); return visitor.hasNativeImageResourceFile && !ignoreExistingResourcesConfig ? Collections.emptyList() : visitor.resources; - } - else { + } else { return Collections.emptyList(); } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0f80bbf51..41dfb8790 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 72d3ef92e283d8a7d5ff1ab0f434566dc8b8e53c Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 9 Feb 2022 18:06:10 +0100 Subject: [PATCH 15/30] Fix included builds participating in publishing --- .../src/main/kotlin/org.graalvm.build.aggregator.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-logic/aggregator/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts b/build-logic/aggregator/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts index 6e753ca45..d6fc7c607 100644 --- a/build-logic/aggregator/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts +++ b/build-logic/aggregator/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts @@ -83,7 +83,7 @@ listOf( description = "Publishes all artifacts to the ${repo.decapitalize()} repository" group = PublishingPlugin.PUBLISH_TASK_GROUP gradle.includedBuilds.forEach { - if (it.name != "docs") { + if (it.name != "docs" && !it.projectDir.path.contains("build-logic")) { dependsOn(it.task(":$taskPrefix$repo")) } } From 86fcc283a2d786640ae407c43a9edcac0553334d Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Tue, 8 Feb 2022 10:59:38 +0100 Subject: [PATCH 16/30] Initial support for a configuration repository This commit introduces a new module, `native-config`, which is a support library for the GraalVM native configuration repository. It makes it possible to use a file-system based repository which contains native configuration directories for a set of modules. --- common/native-config/LICENSE | 38 ++++++ common/native-config/build.gradle.kts | 73 +++++++++++ common/native-config/settings.gradle.kts | 50 +++++++ .../NativeConfigurationRepository.java | 88 +++++++++++++ .../internal/FileSystemRepository.java | 77 +++++++++++ .../internal/UncheckedIOException.java | 49 +++++++ .../internal/index/artifacts/Artifact.java | 80 ++++++++++++ ...duleJsonVersionToConfigDirectoryIndex.java | 121 +++++++++++++++++ .../VersionToConfigDirectoryIndex.java | 63 +++++++++ ...ileSystemModuleToConfigDirectoryIndex.java | 75 +++++++++++ .../JsonModuleToConfigDirectoryIndex.java | 122 ++++++++++++++++++ .../internal/index/modules/ModuleEntry.java | 74 +++++++++++ .../modules/ModuleToConfigDirectoryIndex.java | 54 ++++++++ ...dLocationModuleToConfigDirectoryIndex.java | 63 +++++++++ .../internal/FileSystemRepositoryTest.java | 121 +++++++++++++++++ ...JsonVersionToConfigDirectoryIndexTest.java | 97 ++++++++++++++ ...ystemModuleToConfigDirectoryIndexTest.java | 93 +++++++++++++ .../JsonModuleToConfigDirectoryIndexTest.java | 90 +++++++++++++ ...ationModuleToConfigDirectoryIndexTest.java | 78 +++++++++++ .../test/resources/json/artifact-1/index.json | 5 + .../json/modules/multi-dirs/index.json | 7 + .../modules/multi-dirs/jline/placeholder.txt | 0 .../multi-dirs/netty-core/placeholder.txt | 0 .../multi-dirs/org/bar/placeholder.txt | 0 .../json/modules/single-dir/index.json | 7 + .../io/netty/netty-core/placeholder.txt | 0 .../modules/single-dir/jline/placeholder.txt | 0 .../single-dir/org/bar/placeholder.txt | 0 .../src/test/resources/repos/repo1/index.json | 3 + .../repos/repo1/org/foo/1/reflect-config.json | 0 .../repos/repo1/org/foo/2/reflect-config.json | 0 .../resources/repos/repo1/org/foo/index.json | 17 +++ .../src/test/resources/repos/repo2/index.json | 6 + .../repos/repo2/org/foo/1/reflect-config.json | 0 .../repos/repo2/org/foo/2/reflect-config.json | 0 .../resources/repos/repo2/org/foo/index.json | 5 + settings.gradle.kts | 1 + 37 files changed, 1557 insertions(+) create mode 100644 common/native-config/LICENSE create mode 100644 common/native-config/build.gradle.kts create mode 100644 common/native-config/settings.gradle.kts create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/UncheckedIOException.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndex.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleToConfigDirectoryIndex.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java create mode 100644 common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java create mode 100644 common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java create mode 100644 common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java create mode 100644 common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java create mode 100644 common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java create mode 100644 common/native-config/src/test/resources/json/artifact-1/index.json create mode 100644 common/native-config/src/test/resources/json/modules/multi-dirs/index.json create mode 100644 common/native-config/src/test/resources/json/modules/multi-dirs/jline/placeholder.txt create mode 100644 common/native-config/src/test/resources/json/modules/multi-dirs/netty-core/placeholder.txt create mode 100644 common/native-config/src/test/resources/json/modules/multi-dirs/org/bar/placeholder.txt create mode 100644 common/native-config/src/test/resources/json/modules/single-dir/index.json create mode 100644 common/native-config/src/test/resources/json/modules/single-dir/io/netty/netty-core/placeholder.txt create mode 100644 common/native-config/src/test/resources/json/modules/single-dir/jline/placeholder.txt create mode 100644 common/native-config/src/test/resources/json/modules/single-dir/org/bar/placeholder.txt create mode 100644 common/native-config/src/test/resources/repos/repo1/index.json create mode 100644 common/native-config/src/test/resources/repos/repo1/org/foo/1/reflect-config.json create mode 100644 common/native-config/src/test/resources/repos/repo1/org/foo/2/reflect-config.json create mode 100644 common/native-config/src/test/resources/repos/repo1/org/foo/index.json create mode 100644 common/native-config/src/test/resources/repos/repo2/index.json create mode 100644 common/native-config/src/test/resources/repos/repo2/org/foo/1/reflect-config.json create mode 100644 common/native-config/src/test/resources/repos/repo2/org/foo/2/reflect-config.json create mode 100644 common/native-config/src/test/resources/repos/repo2/org/foo/index.json diff --git a/common/native-config/LICENSE b/common/native-config/LICENSE new file mode 100644 index 000000000..33bafe109 --- /dev/null +++ b/common/native-config/LICENSE @@ -0,0 +1,38 @@ +Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or +data (collectively the "Software"), free of charge and under any and all +copyright rights in the Software, and any and all patent rights owned or +freely licensable by each licensor hereunder covering either (i) the +unmodified Software as contributed to or provided by such licensor, or (ii) +the Larger Works (as defined below), to deal in both + +(a) the Software, and + +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +one is included with the Software each a "Larger Work" to which the Software +is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: + +The above copyright notice and either this complete permission notice or at a +minimum a reference to the UPL must be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/common/native-config/build.gradle.kts b/common/native-config/build.gradle.kts new file mode 100644 index 000000000..648f54166 --- /dev/null +++ b/common/native-config/build.gradle.kts @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +plugins { + checkstyle + id("org.graalvm.build.java") + id("org.graalvm.build.publishing") +} + +maven { + name.set("GraalVM Native Configuration support") + description.set("A library to help dealing with the GraaVM native configuration repository") +} + +dependencies { + implementation(libs.jackson.databind) + implementation(platform(libs.test.junit.bom)) + implementation(libs.test.junit.jupiter.core) +} + +tasks.withType().configureEach { + useJUnitPlatform() +} + +publishing { + publications { + create("maven") { + from(components["java"]) + } + } +} + +tasks.withType().configureEach { + setConfigFile(layout.projectDirectory.dir("../../config/checkstyle.xml").asFile) +} diff --git a/common/native-config/settings.gradle.kts b/common/native-config/settings.gradle.kts new file mode 100644 index 000000000..a666a5c17 --- /dev/null +++ b/common/native-config/settings.gradle.kts @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +pluginManagement { + includeBuild("../../build-logic") +} + +plugins { + id("org.graalvm.build.common") +} + +rootProject.name = "native-config" diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java new file mode 100644 index 000000000..d78c20bda --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig; + +import java.nio.file.Path; +import java.util.Collection; +import java.util.Set; +import java.util.stream.Collectors; + +public interface NativeConfigurationRepository { + /** + * Returns a list of configuration directories for the specified artifact. + * There may be more than one configuration directory for a given artifact, + * but the list may also be empty if the repository doesn't contain any. + * Never null. + * @param groupId the group id + * @param artifactId the artifac id + * @param version the version of the artifact + * @return a list of configuration directories + */ + Set findConfigurationDirectoriesFor(String groupId, String artifactId, String version); + + /** + * Returns a list of configuration directories for the specified artifact. + * There may be more than one configuration directory for a given artifact, + * but the list may also be empty if the repository doesn't contain any. + * Never null. + * @param gavCoordinates the artifact GAV coordinates (group:artifact:version) + * @return a list of configuration directories + */ + default Set findConfigurationDirectoriesFor(String gavCoordinates) { + String[] gav = gavCoordinates.split(":"); + if (gav.length != 3) { + throw new IllegalArgumentException("Invalid GAV coordinates: " + gavCoordinates + " (expected format: groupId:artifactId:version)"); + } + return findConfigurationDirectoriesFor(gav[0], gav[1], gav[2]); + } + + /** + * Returns the set of configuration directories for all the modules supplied + * as an argument. + * @param modules the list of modules + * @return the set of configuration directories + */ + default Set findConfigurationDirectoriesFor(Collection modules) { + return modules.stream() + .flatMap(m -> findConfigurationDirectoriesFor(m).stream()) + .collect(Collectors.toSet()); + } +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java new file mode 100644 index 000000000..d9e939abd --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal; + +import org.graalvm.nativeconfig.NativeConfigurationRepository; +import org.graalvm.nativeconfig.internal.index.artifacts.SingleModuleJsonVersionToConfigDirectoryIndex; +import org.graalvm.nativeconfig.internal.index.artifacts.VersionToConfigDirectoryIndex; +import org.graalvm.nativeconfig.internal.index.modules.FileSystemModuleToConfigDirectoryIndex; + +import java.nio.file.Path; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +public class FileSystemRepository implements NativeConfigurationRepository { + private final FileSystemModuleToConfigDirectoryIndex moduleIndex; + private final Map artifactIndexes; + + public FileSystemRepository(Path rootDirectory) { + this.moduleIndex = new FileSystemModuleToConfigDirectoryIndex(rootDirectory); + this.artifactIndexes = new ConcurrentHashMap<>(); + } + + @Override + public Set findConfigurationDirectoriesFor(String groupId, String artifactId, String version) { + return moduleIndex.findConfigurationDirectories(groupId, artifactId) + .stream() + .map(dir -> { + VersionToConfigDirectoryIndex index = artifactIndexes.computeIfAbsent(dir, SingleModuleJsonVersionToConfigDirectoryIndex::new); + return index.findConfigurationDirectory(groupId, artifactId, version); + }) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toSet()); + } + +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/UncheckedIOException.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/UncheckedIOException.java new file mode 100644 index 000000000..6a56bca52 --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/UncheckedIOException.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal; + +import java.io.IOException; + +public class UncheckedIOException extends RuntimeException { + public UncheckedIOException(IOException e) { + super(e); + } +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java new file mode 100644 index 000000000..3fa727c5a --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal.index.artifacts; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Set; + +public class Artifact { + private final String module; + private final Set versions; + private final String directory; + private final boolean latest; + + @JsonCreator + public Artifact(@JsonProperty("module") String module, + @JsonProperty("tested-versions") Set versions, + @JsonProperty("config-version") String directory, + @JsonProperty(value = "latest", defaultValue = "false") boolean latest) { + this.module = module; + this.versions = versions; + this.directory = directory; + this.latest = latest; + } + + public String getModule() { + return module; + } + + public Set getVersions() { + return versions; + } + + public String getDirectory() { + return directory; + } + + public boolean isLatest() { + return latest; + } +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java new file mode 100644 index 000000000..04da47621 --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal.index.artifacts; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; +import org.graalvm.nativeconfig.internal.UncheckedIOException; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class SingleModuleJsonVersionToConfigDirectoryIndex implements VersionToConfigDirectoryIndex { + private final Path moduleRoot; + private final Map> index; + + public SingleModuleJsonVersionToConfigDirectoryIndex(Path moduleRoot) { + this.moduleRoot = moduleRoot; + this.index = parseIndexFile(moduleRoot); + } + + private Map> parseIndexFile(Path rootPath) { + Path indexFile = rootPath.resolve("index.json"); + ObjectMapper objectMapper = new ObjectMapper(); + TypeFactory typeFactory = objectMapper.getTypeFactory(); + try (BufferedReader reader = Files.newBufferedReader(indexFile)) { + List entries = objectMapper.readValue( + reader, + typeFactory.constructCollectionType(List.class, Artifact.class) + ); + return entries.stream() + .collect(Collectors.groupingBy(Artifact::getModule)); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + } + + + /** + * Returns the configuration directory for the requested artifact. + * + * @param groupId the group ID of the artifact + * @param artifactId the artifact ID of the artifact + * @param version the version of the artifact + * @return a configuration directory, or empty if no configuration directory is available + */ + @Override + public Optional findConfigurationDirectory(String groupId, String artifactId, String version) { + return findConfigurationFor(groupId, artifactId, artifact -> artifact.getVersions().contains(version)); + } + + /** + * Returns the latest configuration directory for the requested artifact. + * + * @param groupId the group ID of the artifact + * @param artifactId the artifact ID of the artifact + * @return a configuration directory, or empty if no configuration directory is available + */ + @Override + public Optional findLatestConfigurationFor(String groupId, String artifactId) { + return findConfigurationFor(groupId, artifactId, Artifact::isLatest); + } + + private Optional findConfigurationFor(String groupId, String artifactId, Predicate predicate) { + String module = groupId + ":" + artifactId; + List artifacts = index.get(module); + if (artifacts == null) { + return Optional.empty(); + } + return artifacts.stream() + .filter(artifact -> artifact.getModule().equals(module)) + .filter(predicate) + .findFirst() + .map(artifact -> moduleRoot.resolve(artifact.getDirectory())); + } +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java new file mode 100644 index 000000000..3eebc187f --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal.index.artifacts; + +import java.nio.file.Path; +import java.util.Optional; + +public interface VersionToConfigDirectoryIndex { + /** + * Returns the configuration directory for the requested artifact. + * @param groupId the group ID of the artifact + * @param artifactId the artifact ID of the artifact + * @param version the version of the artifact + * @return a configuration directory, or empty if no configuration directory is available + */ + Optional findConfigurationDirectory(String groupId, String artifactId, String version); + + /** + * Returns the latest configuration directory for the requested artifact. + * @param groupId the group ID of the artifact + * @param artifactId the artifact ID of the artifact + * @return a configuration directory, or empty if no configuration directory is available + */ + Optional findLatestConfigurationFor(String groupId, String artifactId); +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java new file mode 100644 index 000000000..c2233453b --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal.index.modules; + +import java.nio.file.Path; +import java.util.Set; + +/** + * This is the default index from module to configuration directory, which first + * looks into the JSON index file, and if a module isn't found there, would try + * to find it in the standard FS location. + */ +public class FileSystemModuleToConfigDirectoryIndex implements ModuleToConfigDirectoryIndex { + private final JsonModuleToConfigDirectoryIndex jsonIndex; + private final StandardLocationModuleToConfigDirectoryIndex fsIndex; + + public FileSystemModuleToConfigDirectoryIndex(Path rootPath) { + this.jsonIndex = new JsonModuleToConfigDirectoryIndex(rootPath); + this.fsIndex = new StandardLocationModuleToConfigDirectoryIndex(rootPath); + } + + /** + * Returns the directory containing the candidate configurations for the given module. + * + * @param groupId the group of the module + * @param artifactId the artifact of the module + * @return the configuration directory + */ + @Override + public Set findConfigurationDirectories(String groupId, String artifactId) { + Set fromIndex = jsonIndex.findConfigurationDirectories(groupId, artifactId); + if (!fromIndex.isEmpty()) { + return fromIndex; + } + return fsIndex.findConfigurationDirectories(groupId, artifactId); + } +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndex.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndex.java new file mode 100644 index 000000000..fa72ad7ba --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndex.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal.index.modules; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; +import org.graalvm.nativeconfig.internal.UncheckedIOException; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class JsonModuleToConfigDirectoryIndex implements ModuleToConfigDirectoryIndex { + private final Path rootPath; + private final Map> index; + + public JsonModuleToConfigDirectoryIndex(Path rootPath) { + this.rootPath = rootPath; + this.index = parseIndexFile(rootPath); + } + + private Map> parseIndexFile(Path rootPath) { + Path indexFile = rootPath.resolve("index.json"); + ObjectMapper objectMapper = new ObjectMapper(); + TypeFactory typeFactory = objectMapper.getTypeFactory(); + try (BufferedReader reader = Files.newBufferedReader(indexFile)) { + List entries = objectMapper.readValue( + reader, + typeFactory.constructCollectionType(List.class, ModuleEntry.class) + ); + Map> moduleToEntries = entries.stream() + .collect(Collectors.groupingBy(ModuleEntry::getModule)); + Map> index = new HashMap<>(moduleToEntries.size()); + for (Map.Entry> entry : moduleToEntries.entrySet()) { + String key = entry.getKey(); + Set dirs = entry.getValue() + .stream() + .flatMap(module -> Stream.concat( + Stream.of(module.getModuleDirectory()), + module.getRequires().stream().flatMap(e -> { + List moduleEntries = moduleToEntries.get(e); + if (moduleEntries == null) { + throw new IllegalStateException("Module " + module.getModule() + " requires module " + e + " which is not found in index"); + } + return moduleEntries.stream().map(ModuleEntry::getModuleDirectory); + }) + )) + .filter(Objects::nonNull) + .map(rootPath::resolve) + .collect(Collectors.toSet()); + index.put(key, dirs); + } + return index; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + } + + /** + * Returns the directory containing the candidate configurations for the given module. + * + * @param groupId the group of the module + * @param artifactId the artifact of the module + * @return the configuration directory + */ + @Override + public Set findConfigurationDirectories(String groupId, String artifactId) { + String key = groupId + ":" + artifactId; + if (!index.containsKey(key)) { + return Collections.emptySet(); + } + return index.get(key); + } +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java new file mode 100644 index 000000000..ba44f2d27 --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal.index.modules; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Collections; +import java.util.List; + +public class ModuleEntry { + private final String module; + private final String moduleDirectory; + private final List requires; + + @JsonCreator + public ModuleEntry(@JsonProperty("module") String module, + @JsonProperty("directory") String moduleDirectory, + @JsonProperty("requires") List requires) { + this.module = module; + this.moduleDirectory = moduleDirectory; + this.requires = requires == null ? Collections.emptyList() : requires; + } + + public String getModule() { + return module; + } + + public String getModuleDirectory() { + return moduleDirectory; + } + + public List getRequires() { + return requires; + } +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleToConfigDirectoryIndex.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleToConfigDirectoryIndex.java new file mode 100644 index 000000000..057d4d5a1 --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleToConfigDirectoryIndex.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal.index.modules; + +import java.nio.file.Path; +import java.util.Set; + +public interface ModuleToConfigDirectoryIndex { + /** + * Returns the directories containing the candidate configurations for the given module. + * @param groupId the group of the module + * @param artifactId the artifact of the module + * @return the configuration directory + */ + Set findConfigurationDirectories(String groupId, String artifactId); +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java new file mode 100644 index 000000000..c43aa59e0 --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal.index.modules; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.Set; + +public class StandardLocationModuleToConfigDirectoryIndex implements ModuleToConfigDirectoryIndex { + private final Path rootPath; + + public StandardLocationModuleToConfigDirectoryIndex(Path rootPath) { + this.rootPath = rootPath; + } + + @Override + public Set findConfigurationDirectories(String groupId, String artifactId) { + Path candidate = rootPath.resolve(groupId.replace('.', '/') + "/" + artifactId); + if (Files.isDirectory(candidate)) { + return Collections.singleton(candidate); + } + return Collections.emptySet(); + } +} diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java new file mode 100644 index 000000000..d6f0e7b4c --- /dev/null +++ b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.graalvm.nativeconfig.internal; + +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class FileSystemRepositoryTest { + private FileSystemRepository repository; + private Path repoPath; + private Result result; + + @Test + void testRepo1() { + // when: + withRepo("repo1"); + lookup("org:foo:1.0"); + + // then: + result.hasSinglePath("org/foo/1"); + + // when: + lookup("org:foo:1.1"); + + // then: + result.hasSinglePath("org/foo/2"); + + // when: + lookup("org:foo:1.2"); + + // then: + result.isEmpty(); + } + + @Test + void testRepo2() { + // when: + withRepo("repo2"); + lookup("org:bar:2.1"); + + // then: + result.hasSinglePath("org/foo/2"); + } + + private void lookup(String gav) { + result = new Result(repository.findConfigurationDirectoriesFor(gav), repoPath); + } + + private void withRepo(String id) { + try { + repoPath = new File(FileSystemRepositoryTest.class.getResource("/repos/" + id).toURI()).toPath(); + repository = new FileSystemRepository(repoPath); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + private static class Result { + private final Path repoPath; + private final Set configDirs; + + private Result(Set configDirs, Path repoPath) { + this.configDirs = configDirs; + this.repoPath = repoPath; + } + + public void isEmpty() { + assertEquals(0, configDirs.size()); + } + + public void hasSinglePath(String path) { + assertEquals(1, configDirs.size()); + assertEquals(repoPath.resolve(path), configDirs.iterator().next()); + } + } +} diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java new file mode 100644 index 000000000..8d5cb1ce9 --- /dev/null +++ b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.graalvm.nativeconfig.internal.index.artifacts; + +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SingleModuleJsonVersionToConfigDirectoryIndexTest { + private Path repoPath; + + private SingleModuleJsonVersionToConfigDirectoryIndex index; + + @Test + void checkIndex() throws URISyntaxException { + withIndex("artifact-1"); + + Optional configDir = index.findConfigurationDirectory("com.foo", "bar", "1.0"); + assertTrue(configDir.isPresent()); + assertEquals(repoPath.resolve("1"), configDir.get()); + + configDir = index.findConfigurationDirectory("com.foo", "bar", "1.3"); + assertTrue(configDir.isPresent()); + assertEquals(repoPath.resolve("1"), configDir.get()); + + configDir = index.findConfigurationDirectory("com.foo", "bar", "2.0"); + assertTrue(configDir.isPresent()); + assertEquals(repoPath.resolve("2"), configDir.get()); + + configDir = index.findConfigurationDirectory("com.foo", "bar", "2.5"); + assertFalse(configDir.isPresent()); + + configDir = index.findConfigurationDirectory("com.foo", "bar-all", "2.0"); + assertTrue(configDir.isPresent()); + assertEquals(repoPath.resolve("2"), configDir.get()); + + configDir = index.findConfigurationDirectory("com.foo", "nope", "1.0"); + assertFalse(configDir.isPresent()); + + Optional latest = index.findLatestConfigurationFor("com.foo", "bar"); + assertTrue(latest.isPresent()); + assertEquals(repoPath.resolve("2"), latest.get()); + + } + + private void withIndex(String json) throws URISyntaxException { + repoPath = new File(SingleModuleJsonVersionToConfigDirectoryIndexTest.class.getResource("/json/" + json).toURI()).toPath(); + index = new SingleModuleJsonVersionToConfigDirectoryIndex(repoPath); + } + +} diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java new file mode 100644 index 000000000..80a57813a --- /dev/null +++ b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.graalvm.nativeconfig.internal.index.modules; + +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; + +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class FileSystemModuleToConfigDirectoryIndexTest { + private Path repoPath; + + private FileSystemModuleToConfigDirectoryIndex index; + + @Test + void returnsSingleDirectory() throws IOException, URISyntaxException { + writeIndex("single-dir"); + Set configurationDirectories = index.findConfigurationDirectories("io.netty", "netty-core"); + assertEquals(singleton(repoPath.resolve("io/netty/netty-core")), configurationDirectories); + + configurationDirectories = index.findConfigurationDirectories("io.netty", "netty-all"); + assertEquals(singleton(repoPath.resolve("io/netty/netty-core")), configurationDirectories); + + configurationDirectories = index.findConfigurationDirectories("org", "bar"); + assertEquals(singleton(repoPath.resolve("org/bar")), configurationDirectories); + } + + @Test + void returnsMultipleDirectories() throws IOException, URISyntaxException { + writeIndex("multi-dirs"); + Set configurationDirectories = index.findConfigurationDirectories("io.netty", "netty-all"); + assertEquals(new HashSet<>(asList( + repoPath.resolve("io/netty/netty-core"), + repoPath.resolve("jline") + )), configurationDirectories); + + configurationDirectories = index.findConfigurationDirectories("org", "bar"); + assertEquals(singleton(repoPath.resolve("org/bar")), configurationDirectories); + } + + private void writeIndex(String json) throws URISyntaxException { + repoPath = new File(FileSystemModuleToConfigDirectoryIndexTest.class.getResource("/json/modules/" + json).toURI()).toPath(); + index = new FileSystemModuleToConfigDirectoryIndex(repoPath); + } + +} diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java new file mode 100644 index 000000000..0ae9033b2 --- /dev/null +++ b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.graalvm.nativeconfig.internal.index.modules; + +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class JsonModuleToConfigDirectoryIndexTest { + private Path repoPath; + + private JsonModuleToConfigDirectoryIndex index; + + @Test + void returnsSingleDirectory() throws URISyntaxException { + writeIndex("single-dir"); + Set configurationDirectories = index.findConfigurationDirectories("io.netty", "netty-core"); + assertEquals(singleton(repoPath.resolve("io/netty/netty-core")), configurationDirectories); + + configurationDirectories = index.findConfigurationDirectories("io.netty", "netty-all"); + assertEquals(singleton(repoPath.resolve("io/netty/netty-core")), configurationDirectories); + + configurationDirectories = index.findConfigurationDirectories("org", "bar"); + assertEquals(emptySet(), configurationDirectories); + } + + @Test + void returnsMultipleDirectories() throws URISyntaxException { + writeIndex("multi-dirs"); + Set configurationDirectories = index.findConfigurationDirectories("io.netty", "netty-all"); + assertEquals(new HashSet<>(asList( + repoPath.resolve("io/netty/netty-core"), + repoPath.resolve("jline") + )), configurationDirectories); + + } + + private void writeIndex(String json) throws URISyntaxException { + repoPath = new File(FileSystemModuleToConfigDirectoryIndexTest.class.getResource("/json/modules/" + json).toURI()).toPath(); + index = new JsonModuleToConfigDirectoryIndex(repoPath); + } +} diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java new file mode 100644 index 000000000..189607e59 --- /dev/null +++ b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.graalvm.nativeconfig.internal.index.modules; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; + +import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class StandardLocationModuleToConfigDirectoryIndexTest { + @TempDir + private Path tempDir; + + private StandardLocationModuleToConfigDirectoryIndex index; + + @BeforeEach + void setUp() { + index = new StandardLocationModuleToConfigDirectoryIndex(tempDir); + } + + @Test + void returnsConventionalConfigLocation() throws IOException { + Path localDir = tempDir.resolve("org/module/foo"); + Files.createDirectories(localDir); + Set configurationDirectories = index.findConfigurationDirectories("org.module", "foo"); + assertEquals(singleton(localDir), configurationDirectories); + + configurationDirectories = index.findConfigurationDirectories("org", "bar"); + assertEquals(emptySet(), configurationDirectories); + } +} diff --git a/common/native-config/src/test/resources/json/artifact-1/index.json b/common/native-config/src/test/resources/json/artifact-1/index.json new file mode 100644 index 000000000..0dca61c23 --- /dev/null +++ b/common/native-config/src/test/resources/json/artifact-1/index.json @@ -0,0 +1,5 @@ +[ + { "module": "com.foo:bar", "tested-versions": ["1.0", "1.1", "1.2", "1.3"], "config-version": "1" }, + { "module": "com.foo:bar", "tested-versions": ["2.0", "2.1"], "config-version": "2", "latest": true }, + { "module": "com.foo:bar-all", "tested-versions": ["2.0", "2.1"], "config-version": "2" } +] diff --git a/common/native-config/src/test/resources/json/modules/multi-dirs/index.json b/common/native-config/src/test/resources/json/modules/multi-dirs/index.json new file mode 100644 index 000000000..b6e62fcce --- /dev/null +++ b/common/native-config/src/test/resources/json/modules/multi-dirs/index.json @@ -0,0 +1,7 @@ +[ + { "module": "io.netty:netty-core", "directory": "io/netty/netty-core"}, + { "module": "org.jline:jline", "directory": "jline"}, + { + "module": "io.netty:netty-all", "requires": ["io.netty:netty-core", "org.jline:jline"] + } +] diff --git a/common/native-config/src/test/resources/json/modules/multi-dirs/jline/placeholder.txt b/common/native-config/src/test/resources/json/modules/multi-dirs/jline/placeholder.txt new file mode 100644 index 000000000..e69de29bb diff --git a/common/native-config/src/test/resources/json/modules/multi-dirs/netty-core/placeholder.txt b/common/native-config/src/test/resources/json/modules/multi-dirs/netty-core/placeholder.txt new file mode 100644 index 000000000..e69de29bb diff --git a/common/native-config/src/test/resources/json/modules/multi-dirs/org/bar/placeholder.txt b/common/native-config/src/test/resources/json/modules/multi-dirs/org/bar/placeholder.txt new file mode 100644 index 000000000..e69de29bb diff --git a/common/native-config/src/test/resources/json/modules/single-dir/index.json b/common/native-config/src/test/resources/json/modules/single-dir/index.json new file mode 100644 index 000000000..12872860b --- /dev/null +++ b/common/native-config/src/test/resources/json/modules/single-dir/index.json @@ -0,0 +1,7 @@ +[ + { "module": "io.netty:netty-core", "directory": "io/netty/netty-core"}, + { "module": "org.jline:jline", "directory": "jline"}, + { + "module": "io.netty:netty-all", "requires": ["io.netty:netty-core"] + } +] diff --git a/common/native-config/src/test/resources/json/modules/single-dir/io/netty/netty-core/placeholder.txt b/common/native-config/src/test/resources/json/modules/single-dir/io/netty/netty-core/placeholder.txt new file mode 100644 index 000000000..e69de29bb diff --git a/common/native-config/src/test/resources/json/modules/single-dir/jline/placeholder.txt b/common/native-config/src/test/resources/json/modules/single-dir/jline/placeholder.txt new file mode 100644 index 000000000..e69de29bb diff --git a/common/native-config/src/test/resources/json/modules/single-dir/org/bar/placeholder.txt b/common/native-config/src/test/resources/json/modules/single-dir/org/bar/placeholder.txt new file mode 100644 index 000000000..e69de29bb diff --git a/common/native-config/src/test/resources/repos/repo1/index.json b/common/native-config/src/test/resources/repos/repo1/index.json new file mode 100644 index 000000000..41b42e677 --- /dev/null +++ b/common/native-config/src/test/resources/repos/repo1/index.json @@ -0,0 +1,3 @@ +[ + +] diff --git a/common/native-config/src/test/resources/repos/repo1/org/foo/1/reflect-config.json b/common/native-config/src/test/resources/repos/repo1/org/foo/1/reflect-config.json new file mode 100644 index 000000000..e69de29bb diff --git a/common/native-config/src/test/resources/repos/repo1/org/foo/2/reflect-config.json b/common/native-config/src/test/resources/repos/repo1/org/foo/2/reflect-config.json new file mode 100644 index 000000000..e69de29bb diff --git a/common/native-config/src/test/resources/repos/repo1/org/foo/index.json b/common/native-config/src/test/resources/repos/repo1/org/foo/index.json new file mode 100644 index 000000000..ffd7c5bcb --- /dev/null +++ b/common/native-config/src/test/resources/repos/repo1/org/foo/index.json @@ -0,0 +1,17 @@ +[ + { + "module": "org:foo", + "tested-versions": [ + "1.0" + ], + "config-version": "1" + }, + { + "module": "org:foo", + "tested-versions": [ + "1.1" + ], + "config-version": "2", + "latest": true + } +] diff --git a/common/native-config/src/test/resources/repos/repo2/index.json b/common/native-config/src/test/resources/repos/repo2/index.json new file mode 100644 index 000000000..5ffe83bb0 --- /dev/null +++ b/common/native-config/src/test/resources/repos/repo2/index.json @@ -0,0 +1,6 @@ +[ + { + "module": "org:bar", + "directory": "org/foo" + } +] diff --git a/common/native-config/src/test/resources/repos/repo2/org/foo/1/reflect-config.json b/common/native-config/src/test/resources/repos/repo2/org/foo/1/reflect-config.json new file mode 100644 index 000000000..e69de29bb diff --git a/common/native-config/src/test/resources/repos/repo2/org/foo/2/reflect-config.json b/common/native-config/src/test/resources/repos/repo2/org/foo/2/reflect-config.json new file mode 100644 index 000000000..e69de29bb diff --git a/common/native-config/src/test/resources/repos/repo2/org/foo/index.json b/common/native-config/src/test/resources/repos/repo2/org/foo/index.json new file mode 100644 index 000000000..6a6e12db7 --- /dev/null +++ b/common/native-config/src/test/resources/repos/repo2/org/foo/index.json @@ -0,0 +1,5 @@ +[ + { "module": "org:foo", "tested-versions": ["1.0"], "config-version": "1" }, + { "module": "org:foo", "tested-versions": ["1.1"], "config-version": "2" }, + { "module": "org:bar", "tested-versions": ["2.1"], "config-version": "2" } +] diff --git a/settings.gradle.kts b/settings.gradle.kts index d47487278..bee7f3039 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -48,6 +48,7 @@ rootProject.name = "native-build-tools" includeBuild("common/junit-platform-native") includeBuild("common/utils") +includeBuild("common/native-config") includeBuild("native-gradle-plugin") includeBuild("native-maven-plugin") includeBuild("docs") From f85f05c3a950898bd65bc369381c16299922b12d Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Tue, 8 Feb 2022 11:55:52 +0100 Subject: [PATCH 17/30] Introduce the ability to configure queries Instead of simply querying by artifact GAV coordinates, the configuration repository can now be queried with an advanced query model which supports falling back to a default configuration directory, or overriding a particular version. --- .github/workflows/native-config.yml | 44 +++++ common/native-config/build.gradle.kts | 4 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + common/native-config/gradlew | 185 ++++++++++++++++++ common/native-config/gradlew.bat | 89 +++++++++ common/native-config/settings.gradle.kts | 3 +- .../NativeConfigurationRepository.java | 39 ++-- .../java/org/graalvm/nativeconfig/Query.java | 62 ++++++ .../internal/DefaultArtifactQuery.java | 103 ++++++++++ .../nativeconfig/internal/DefaultQuery.java | 83 ++++++++ .../internal/FileSystemRepository.java | 33 +++- ...duleJsonVersionToConfigDirectoryIndex.java | 5 + .../VersionToConfigDirectoryIndex.java | 9 + .../internal/FileSystemRepositoryTest.java | 84 +++++++- 15 files changed, 718 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/native-config.yml create mode 100644 common/native-config/gradle/wrapper/gradle-wrapper.jar create mode 100644 common/native-config/gradle/wrapper/gradle-wrapper.properties create mode 100755 common/native-config/gradlew create mode 100644 common/native-config/gradlew.bat create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/Query.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultArtifactQuery.java create mode 100644 common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultQuery.java diff --git a/.github/workflows/native-config.yml b/.github/workflows/native-config.yml new file mode 100644 index 000000000..86186f36c --- /dev/null +++ b/.github/workflows/native-config.yml @@ -0,0 +1,44 @@ +name: Native Configuration Repository + +on: + push: + paths: + - 'common/native-config/**' + pull_request: + paths: + - 'common/native-config/**' + workflow_dispatch: + +jobs: + test-native-config: + name: + runs-on: ubuntu-18.04 + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 1 + - name: Get GraalVM Nightly + run: | + source common/scripts/downloadGraalVM.sh + echo "$GRAALVM_HOME/bin" >> $GITHUB_PATH + echo "JAVA_HOME=$JAVA_HOME" >> $GITHUB_ENV + echo "GRAALVM_HOME=$GRAALVM_HOME" >> $GITHUB_ENV + - name: Checkstyle + run: | + pushd common/native-config + ./gradlew checkstyleMain + ./gradlew checkstyleTest + popd + - name: JVM test + run: | + pushd common/native-config + ./gradlew test + popd + - name: Tests results + if: always() + uses: actions/upload-artifact@v2 + with: + name: tests-results + path: common/native-config/build/reports/tests/ diff --git a/common/native-config/build.gradle.kts b/common/native-config/build.gradle.kts index 648f54166..bf363f36e 100644 --- a/common/native-config/build.gradle.kts +++ b/common/native-config/build.gradle.kts @@ -52,8 +52,8 @@ maven { dependencies { implementation(libs.jackson.databind) - implementation(platform(libs.test.junit.bom)) - implementation(libs.test.junit.jupiter.core) + testImplementation(platform(libs.test.junit.bom)) + testImplementation(libs.test.junit.jupiter.core) } tasks.withType().configureEach { diff --git a/common/native-config/gradle/wrapper/gradle-wrapper.jar b/common/native-config/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f GIT binary patch literal 59203 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

K7UpUK$>l@ zw`1S}(D?mUXu_C{wupRS-jiX~w=Uqqhf|Vb3Cm9L=T+w91Cu^ z*&Ty%sN?x*h~mJc4g~k{xD4ZmF%FXZNC;oVDwLZ_WvrnzY|{v8hc1nmx4^}Z;yriXsAf+Lp+OFLbR!&Ox?xABwl zu8w&|5pCxmu#$?Cv2_-Vghl2LZ6m7}VLEfR5o2Ou$x02uA-%QB2$c(c1rH3R9hesc zfpn#oqpbKuVsdfV#cv@5pV4^f_!WS+F>SV6N0JQ9E!T90EX((_{bSSFv9ld%I0&}9 zH&Jd4MEX1e0iqDtq~h?DBrxQX1iI0lIs<|kB$Yrh&cpeK0-^K%=FBsCBT46@h#yi!AyDq1V(#V}^;{{V*@T4WJ&U-NTq43w=|K>z8%pr_nC>%C(Wa_l78Ufib$r8Od)IIN=u>417 z`Hl{9A$mI5A(;+-Q&$F&h-@;NR>Z<2U;Y21>>Z;s@0V@SbkMQQj%_;~+qTuQ?c|AV zcWm3XZQHhP&R%QWarS%mJ!9R^&!_)*s(v+VR@I#QrAT}`17Y+l<`b-nvmDNW`De%y zrwTZ9EJrj1AFA>B`1jYDow}~*dfPs}IZMO3=a{Fy#IOILc8F0;JS4x(k-NSpbN@qM z`@aE_e}5{!$v3+qVs7u?sOV(y@1Os*Fgu`fCW9=G@F_#VQ%xf$hj0~wnnP0$hFI+@ zkQj~v#V>xn)u??YutKsX>pxKCl^p!C-o?+9;!Nug^ z{rP!|+KsP5%uF;ZCa5F;O^9TGac=M|=V z_H(PfkV1rz4jl?gJ(ArXMyWT4y(86d3`$iI4^l9`vLdZkzpznSd5Ikfrs8qcSy&>z zTIZgWZGXw0n9ibQxYWE@gI0(3#KA-dAdPcsL_|hg2@~C!VZDM}5;v_Nykfq!*@*Zf zE_wVgx82GMDryKO{U{D>vSzSc%B~|cjDQrt5BN=Ugpsf8H8f1lR4SGo#hCuXPL;QQ z#~b?C4MoepT3X`qdW2dNn& zo8)K}%Lpu>0tQei+{>*VGErz|qjbK#9 zvtd8rcHplw%YyQCKR{kyo6fgg!)6tHUYT(L>B7er5)41iG`j$qe*kSh$fY!PehLcD zWeKZHn<492B34*JUQh=CY1R~jT9Jt=k=jCU2=SL&&y5QI2uAG2?L8qd2U(^AW#{(x zThSy=C#>k+QMo^7caQcpU?Qn}j-`s?1vXuzG#j8(A+RUAY})F@=r&F(8nI&HspAy4 z4>(M>hI9c7?DCW8rw6|23?qQMSq?*Vx?v30U%luBo)B-k2mkL)Ljk5xUha3pK>EEj z@(;tH|M@xkuN?gsz;*bygizwYR!6=(Xgcg^>WlGtRYCozY<rFX2E>kaZo)O<^J7a`MX8Pf`gBd4vrtD|qKn&B)C&wp0O-x*@-|m*0egT=-t@%dD zgP2D+#WPptnc;_ugD6%zN}Z+X4=c61XNLb7L1gWd8;NHrBXwJ7s0ce#lWnnFUMTR& z1_R9Fin4!d17d4jpKcfh?MKRxxQk$@)*hradH2$3)nyXep5Z;B z?yX+-Bd=TqO2!11?MDtG0n(*T^!CIiF@ZQymqq1wPM_X$Iu9-P=^}v7npvvPBu!d$ z7K?@CsA8H38+zjA@{;{kG)#AHME>Ix<711_iQ@WWMObXyVO)a&^qE1GqpP47Q|_AG zP`(AD&r!V^MXQ^e+*n5~Lp9!B+#y3#f8J^5!iC@3Y@P`;FoUH{G*pj*q7MVV)29+j z>BC`a|1@U_v%%o9VH_HsSnM`jZ-&CDvbiqDg)tQEnV>b%Ptm)T|1?TrpIl)Y$LnG_ zzKi5j2Fx^K^PG1=*?GhK;$(UCF-tM~^=Z*+Wp{FSuy7iHt9#4n(sUuHK??@v+6*|10Csdnyg9hAsC5_OrSL;jVkLlf zHXIPukLqbhs~-*oa^gqgvtpgTk_7GypwH><53riYYL*M=Q@F-yEPLqQ&1Sc zZB%w}T~RO|#jFjMWcKMZccxm-SL)s_ig?OC?y_~gLFj{n8D$J_Kw%{r0oB8?@dWzn zB528d-wUBQzrrSSLq?fR!K%59Zv9J4yCQhhDGwhptpA5O5U?Hjqt>8nOD zi{)0CI|&Gu%zunGI*XFZh(ix)q${jT8wnnzbBMPYVJc4HX*9d^mz|21$=R$J$(y7V zo0dxdbX3N#=F$zjstTf*t8vL)2*{XH!+<2IJ1VVFa67|{?LP&P41h$2i2;?N~RA30LV`BsUcj zfO9#Pg1$t}7zpv#&)8`mis3~o+P(DxOMgz-V*(?wWaxi?R=NhtW}<#^Z?(BhSwyar zG|A#Q7wh4OfK<|DAcl9THc-W4*>J4nTevsD%dkj`U~wSUCh15?_N@uMdF^Kw+{agk zJ`im^wDqj`Ev)W3k3stasP`88-M0ZBs7;B6{-tSm3>I@_e-QfT?7|n0D~0RRqDb^G zyHb=is;IwuQ&ITzL4KsP@Z`b$d%B0Wuhioo1CWttW8yhsER1ZUZzA{F*K=wmi-sb#Ju+j z-l@In^IKnb{bQG}Ps>+Vu_W#grNKNGto+yjA)?>0?~X`4I3T@5G1)RqGUZuP^NJCq&^HykuYtMDD8qq+l8RcZNJsvN(10{ zQ1$XcGt}QH-U^WU!-wRR1d--{B$%vY{JLWIV%P4-KQuxxDeJaF#{eu&&r!3Qu{w}0f--8^H|KwE>)ORrcR+2Qf zb})DRcH>k0zWK8@{RX}NYvTF;E~phK{+F;MkIP$)T$93Ba2R2TvKc>`D??#mv9wg$ zd~|-`Qx5LwwsZ2hb*Rt4S9dsF%Cny5<1fscy~)d;0m2r$f=83<->c~!GNyb!U)PA; zq^!`@@)UaG)Ew(9V?5ZBq#c%dCWZrplmuM`o~TyHjAIMh0*#1{B>K4po-dx$Tk-Cq z=WZDkP5x2W&Os`N8KiYHRH#UY*n|nvd(U>yO=MFI-2BEp?x@=N<~CbLJBf6P)}vLS?xJXYJ2^<3KJUdrwKnJnTp{ zjIi|R=L7rn9b*D#Xxr4*R<3T5AuOS+#U8hNlfo&^9JO{VbH!v9^JbK=TCGR-5EWR@ zN8T-_I|&@A}(hKeL4_*eb!1G8p~&_Im8|wc>Cdir+gg90n1dw?QaXcx6Op_W1r=axRw>4;rM*UOpT#Eb9xU1IiWo@h?|5uP zka>-XW0Ikp@dIe;MN8B01a7+5V@h3WN{J=HJ*pe0uwQ3S&MyWFni47X32Q7SyCTNQ z+sR!_9IZa5!>f&V$`q!%H8ci!a|RMx5}5MA_kr+bhtQy{-^)(hCVa@I!^TV4RBi zAFa!Nsi3y37I5EK;0cqu|9MRj<^r&h1lF}u0KpKQD^5Y+LvFEwM zLU@@v4_Na#Axy6tn3P%sD^5P#<7F;sd$f4a7LBMk zGU^RZHBcxSA%kCx*eH&wgA?Qwazm8>9SCSz_!;MqY-QX<1@p$*T8lc?@`ikEqJ>#w zcG``^CoFMAhdEXT9qt47g0IZkaU)4R7wkGs^Ax}usqJ5HfDYAV$!=6?>J6+Ha1I<5 z|6=9soU4>E))tW$<#>F ziZ$6>KJf0bPfbx_)7-}tMINlc=}|H+$uX)mhC6-Hz+XZxsKd^b?RFB6et}O#+>Wmw9Ec9) z{q}XFWp{3@qmyK*Jvzpyqv57LIR;hPXKsrh{G?&dRjF%Zt5&m20Ll?OyfUYC3WRn{cgQ?^V~UAv+5 z&_m#&nIwffgX1*Z2#5^Kl4DbE#NrD&Hi4|7SPqZ}(>_+JMz=s|k77aEL}<=0Zfb)a z%F(*L3zCA<=xO)2U3B|pcTqDbBoFp>QyAEU(jMu8(jLA61-H!ucI804+B!$E^cQQa z)_ERrW3g!B9iLb3nn3dlkvD7KsY?sRvls3QC0qPi>o<)GHx%4Xb$5a3GBTJ(k@`e@ z$RUa^%S15^1oLEmA=sayrP5;9qtf!Z1*?e$ORVPsXpL{jL<6E)0sj&swP3}NPmR%FM?O>SQgN5XfHE< zo(4#Cv11(%Nnw_{_Ro}r6=gKd{k?NebJ~<~Kv0r(r0qe4n3LFx$5%x(BKvrz$m?LG zjLIc;hbj0FMdb9aH9Lpsof#yG$(0sG2%RL;d(n>;#jb!R_+dad+K;Ccw!|RY?uS(a zj~?=&M!4C(5LnlH6k%aYvz@7?xRa^2gml%vn&eKl$R_lJ+e|xsNfXzr#xuh(>`}9g zLHSyiFwK^-p!;p$yt7$F|3*IfO3Mlu9e>Dpx8O`37?fA`cj`C0B-m9uRhJjs^mRp# zWB;Aj6|G^1V6`jg7#7V9UFvnB4((nIwG?k%c7h`?0tS8J3Bn0t#pb#SA}N-|45$-j z$R>%7cc2ebAClXc(&0UtHX<>pd)akR3Kx_cK+n<}FhzmTx!8e9^u2e4%x{>T6pQ`6 zO182bh$-W5A3^wos0SV_TgPmF4WUP-+D25KjbC{y_6W_9I2_vNKwU(^qSdn&>^=*t z&uvp*@c8#2*paD!ZMCi3;K{Na;I4Q35zw$YrW5U@Kk~)&rw;G?d7Q&c9|x<Hg|CNMsxovmfth*|E*GHezPTWa^Hd^F4!B3sF;)? z(NaPyAhocu1jUe(!5Cy|dh|W2=!@fNmuNOzxi^tE_jAtzNJ0JR-avc_H|ve#KO}#S z#a(8secu|^Tx553d4r@3#6^MHbH)vmiBpn0X^29xEv!Vuh1n(Sr5I0V&`jA2;WS|Y zbf0e}X|)wA-Pf5gBZ>r4YX3Mav1kKY(ulAJ0Q*jB)YhviHK)w!TJsi3^dMa$L@^{` z_De`fF4;M87vM3Ph9SzCoCi$#Fsd38u!^0#*sPful^p5oI(xGU?yeYjn;Hq1!wzFk zG&2w}W3`AX4bxoVm03y>ts{KaDf!}b&7$(P4KAMP=vK5?1In^-YYNtx1f#}+2QK@h zeSeAI@E6Z8a?)>sZ`fbq9_snl6LCu6g>o)rO;ijp3|$vig+4t} zylEo7$SEW<_U+qgVcaVhk+4k+C9THI5V10qV*dOV6pPtAI$)QN{!JRBKh-D zk2^{j@bZ}yqW?<#VVuI_27*cI-V~sJiqQv&m07+10XF+#ZnIJdr8t`9s_EE;T2V;B z4UnQUH9EdX%zwh-5&wflY#ve!IWt0UE-My3?L#^Bh%kcgP1q{&26eXLn zTkjJ*w+(|_>Pq0v8{%nX$QZbf)tbJaLY$03;MO=Ic-uqYUmUCuXD>J>o6BCRF=xa% z3R4SK9#t1!K4I_d>tZgE>&+kZ?Q}1qo4&h%U$GfY058s%*=!kac{0Z+4Hwm!)pFLR zJ+5*OpgWUrm0FPI2ib4NPJ+Sk07j(`diti^i#kh&f}i>P4~|d?RFb#!JN)~D@)beox}bw?4VCf^y*`2{4`-@%SFTry2h z>9VBc9#JxEs1+0i2^LR@B1J`B9Ac=#FW=(?2;5;#U$0E0UNag_!jY$&2diQk_n)bT zl5Me_SUvqUjwCqmVcyb`igygB_4YUB*m$h5oeKv3uIF0sk}~es!{D>4r%PC*F~FN3owq5e0|YeUTSG#Vq%&Gk7uwW z0lDo#_wvflqHeRm*}l?}o;EILszBt|EW*zNPmq#?4A+&i0xx^?9obLyY4xx=Y9&^G;xYXYPxG)DOpPg!i_Ccl#3L}6xAAZzNhPK1XaC_~ z!A|mlo?Be*8Nn=a+FhgpOj@G7yYs(Qk(8&|h@_>w8Y^r&5nCqe0V60rRz?b5%J;GYeBqSAjo|K692GxD4` zRZyM2FdI+-jK2}WAZTZ()w_)V{n5tEb@>+JYluDozCb$fA4H)$bzg(Ux{*hXurjO^ zwAxc+UXu=&JV*E59}h3kzQPG4M)X8E*}#_&}w*KEgtX)cU{vm9b$atHa;s>| z+L6&cn8xUL*OSjx4YGjf6{Eq+Q3{!ZyhrL&^6Vz@jGbI%cAM9GkmFlamTbcQGvOlL zmJ?(FI)c86=JEs|*;?h~o)88>12nXlpMR4@yh%qdwFNpct;vMlc=;{FSo*apJ;p}! zAX~t;3tb~VuP|ZW;z$=IHf->F@Ml)&-&Bnb{iQyE#;GZ@C$PzEf6~q}4D>9jic@mTO5x76ulDz@+XAcm35!VSu zT*Gs>;f0b2TNpjU_BjHZ&S6Sqk6V1370+!eppV2H+FY!q*n=GHQ!9Rn6MjY!Jc77A zG7Y!lFp8?TIHN!LXO?gCnsYM-gQxsm=Ek**VmZu7vnuufD7K~GIxfxbsQ@qv2T zPa`tvHB$fFCyZl>3oYg?_wW)C>^_iDOc^B7klnTOoytQH18WkOk)L2BSD0r%xgRSW zQS9elF^?O=_@|58zKLK;(f77l-Zzu}4{fXed2saq!5k#UZAoDBqYQS{sn@j@Vtp|$ zG%gnZ$U|9@u#w1@11Sjl8ze^Co=)7yS(}=;68a3~g;NDe_X^}yJj;~s8xq9ahQ5_r zxAlTMnep*)w1e(TG%tWsjo3RR;yVGPEO4V{Zp?=a_0R#=V^ioQu4YL=BO4r0$$XTX zZfnw#_$V}sDAIDrezGQ+h?q24St0QNug_?{s-pI(^jg`#JRxM1YBV;a@@JQvH8*>> zIJvku74E0NlXkYe_624>znU0J@L<-c=G#F3k4A_)*;ky!C(^uZfj%WB3-*{*B$?9+ zDm$WFp=0(xnt6`vDQV3Jl5f&R(Mp};;q8d3I%Kn>Kx=^;uSVCw0L=gw53%Bp==8Sw zxtx=cs!^-_+i{2OK`Q;913+AXc_&Z5$@z3<)So0CU3;JAv=H?@Zpi~riQ{z-zLtVL z!oF<}@IgJp)Iyz1zVJ42!SPHSkjYNS4%ulVVIXdRuiZ@5Mx8LJS}J#qD^Zi_xQ@>DKDr-_e#>5h3dtje*NcwH_h;i{Sx7}dkdpuW z(yUCjckQsagv*QGMSi9u1`Z|V^}Wjf7B@q%j2DQXyd0nOyqg%m{CK_lAoKlJ7#8M} z%IvR?Vh$6aDWK2W!=i?*<77q&B8O&3?zP(Cs@kapc)&p7En?J;t-TX9abGT#H?TW? ztO5(lPKRuC7fs}zwcUKbRh=7E8wzTsa#Z{a`WR}?UZ%!HohN}d&xJ=JQhpO1PI#>X zHkb>pW04pU%Bj_mf~U}1F1=wxdBZu1790>3Dm44bQ#F=T4V3&HlOLsGH)+AK$cHk6 zia$=$kog?)07HCL*PI6}DRhpM^*%I*kHM<#1Se+AQ!!xyhcy6j7`iDX7Z-2i73_n# zas*?7LkxS-XSqv;YBa zW_n*32D(HTYQ0$feV_Fru1ZxW0g&iwqixPX3=9t4o)o|kOo79V$?$uh?#8Q8e>4e)V6;_(x&ViUVxma+i25qea;d-oK7ouuDsB^ab{ zu1qjQ%`n56VtxBE#0qAzb7lph`Eb-}TYpXB!H-}3Ykqyp`otprp7{VEuW*^IR2n$Fb99*nAtqT&oOFIf z@w*6>YvOGw@Ja?Pp1=whZqydzx@9X4n^2!n83C5{C?G@|E?&$?p*g68)kNvUTJ)I6 z1Q|(#UuP6pj78GUxq11m-GSszc+)X{C2eo-?8ud9sB=3(D47v?`JAa{V(IF zPZQ_0AY*9M97>Jf<o%#O_%Wq}8>YM=q0|tGY+hlXcpE=Z4Od z`NT7Hu2hnvRoqOw@g1f=bv`+nba{GwA$Ak0INlqI1k<9!x_!sL()h?hEWoWrdU3w` zZ%%)VR+Bc@_v!C#koM1p-3v_^L6)_Ktj4HE>aUh%2XZE@JFMOn)J~c`_7VWNb9c-N z2b|SZMR4Z@E7j&q&9(6H3yjEu6HV7{2!1t0lgizD;mZ9$r(r7W5G$ky@w(T_dFnOD z*p#+z$@pKE+>o@%eT(2-p_C}wbQ5s(%Sn_{$HDN@MB+Ev?t@3dPy`%TZ!z}AThZSu zN<1i$siJhXFdjV zP*y|V<`V8t=h#XTRUR~5`c`Z9^-`*BZf?WAehGdg)E2Je)hqFa!k{V(u+(hTf^Yq& zoruUh2(^3pe)2{bvt4&4Y9CY3js)PUHtd4rVG57}uFJL)D(JfSIo^{P=7liFXG zq5yqgof0V8paQcP!gy+;^pp-DA5pj=gbMN0eW=-eY+N8~y+G>t+x}oa!5r>tW$xhI zPQSv=pi;~653Gvf6~*JcQ%t1xOrH2l3Zy@8AoJ+wz@daW@m7?%LXkr!bw9GY@ns3e zSfuWF_gkWnesv?s3I`@}NgE2xwgs&rj?kH-FEy82=O8`+szN ziHch`vvS`zNfap14!&#i9H@wF7}yIPm=UB%(o(}F{wsZ(wA0nJ2aD^@B41>>o-_U6 zUqD~vdo48S8~FTb^+%#zcbQiiYoDKYcj&$#^;Smmb+Ljp(L=1Kt_J!;0s%1|JK}Wi z;={~oL!foo5n8=}rs6MmUW~R&;SIJO3TL4Ky?kh+b2rT9B1Jl4>#Uh-Bec z`Hsp<==#UEW6pGPhNk8H!!DUQR~#F9jEMI6T*OWfN^Ze&X(4nV$wa8QUJ>oTkruH# zm~O<`J7Wxseo@FqaZMl#Y(mrFW9AHM9Kb|XBMqaZ2a)DvJgYipkDD_VUF_PKd~dT7 z#02}bBfPn9a!X!O#83=lbJSK#E}K&yx-HI#T6ua)6o0{|={*HFusCkHzs|Fn&|C3H zBck1cmfcWVUN&i>X$YU^Sn6k2H;r3zuXbJFz)r5~3$d$tUj(l1?o={MM){kjgqXRO zc5R*#{;V7AQh|G|)jLM@wGAK&rm2~@{Pewv#06pHbKn#wL0P6F1!^qw9g&cW3Z=9} zj)POhOlwsh@eF=>z?#sIs*C-Nl(yU!#DaiaxhEs#iJqQ8w%(?+6lU02MYSeDkr!B- zPjMv+on6OLXgGnAtl(ao>|X2Y8*Hb}GRW5}-IzXnoo-d0!m4Vy$GS!XOLy>3_+UGs z2D|YcQx@M#M|}TDOetGi{9lGo9m-=0-^+nKE^*?$^uHkxZh}I{#UTQd;X!L+W@jm( zDg@N4+lUqI92o_rNk{3P>1gxAL=&O;x)ZT=q1mk0kLlE$WeWuY_$0`0jY-Kkt zP*|m3AF}Ubd=`<>(Xg0har*_@x2YH}bn0Wk*OZz3*e5;Zc;2uBdnl8?&XjupbkOeNZsNh6pvsq_ydmJI+*z**{I{0K)-;p1~k8cpJXL$^t!-`E}=*4G^-E8>H!LjTPxSx zcF+cS`ommfKMhNSbas^@YbTpH1*RFrBuATUR zt{oFWSk^$xU&kbFQ;MCX22RAN5F6eq9UfR$ut`Jw--p2YX)A*J69m^!oYfj2y7NYcH6&r+0~_sH^c^nzeN1AU4Ga7=FlR{S|Mm~MpzY0$Z+p2W(a={b-pR9EO1Rs zB%KY|@wLcAA@)KXi!d2_BxrkhDn`DT1=Dec}V!okd{$+wK z4E{n8R*xKyci1(CnNdhf$Dp2(Jpof0-0%-38X=Dd9PQgT+w%Lshx9+loPS~MOm%ZT zt%2B2iL_KU_ita%N>xjB!#71_3=3c}o zgeW~^U_ZTJQ2!PqXulQd=3b=XOQhwATK$y(9$#1jOQ4}4?~l#&nek)H(04f(Sr=s| zWv7Lu1=%WGk4FSw^;;!8&YPM)pQDCY9DhU`hMty1@sq1=Tj7bFsOOBZOFlpR`W>-J$-(kezWJj;`?x-v>ev{*8V z8p|KXJPV$HyQr1A(9LVrM47u-XpcrIyO`yWvx1pVYc&?154aneRpLqgx)EMvRaa#|9?Wwqs2+W8n5~79G z(}iCiLk;?enn}ew`HzhG+tu+Ru@T+K5juvZN)wY;x6HjvqD!&!)$$;1VAh~7fg0K| zEha#aN=Yv|3^~YFH}cc38ovVb%L|g@9W6fo(JtT6$fa?zf@Ct88e}m?i)b*Jgc{fl zExfdvw-BYDmH6>(4QMt#p0;FUIQqkhD}aH?a7)_%JtA~soqj{ppP_82yi9kaxuK>~ ze_)Zt>1?q=ZH*kF{1iq9sr*tVuy=u>Zev}!gEZx@O6-fjyu9X00gpIl-fS_pzjpqJ z1yqBmf9NF!jaF<+YxgH6oXBdK)sH(>VZ)1siyA$P<#KDt;8NT*l_0{xit~5j1P)FN zI8hhYKhQ)i z37^aP13B~u65?sg+_@2Kr^iWHN=U;EDSZ@2W2!5ALhGNWXnFBY%7W?1 z=HI9JzQ-pLKZDYTv<0-lt|6c-RwhxZ)mU2Os{bsX_i^@*fKUj8*aDO5pks=qn3Dv6 zwggpKLuyRCTVPwmw1r}B#AS}?X7b837UlXwp~E2|PJw2SGVueL7){Y&z!jL!XN=0i zU^Eig`S2`{+gU$68aRdWx?BZ{sU_f=8sn~>s~M?GU~`fH5kCc; z8ICp+INM3(3{#k32RZdv6b9MQYdZXNuk7ed8;G?S2nT+NZBG=Tar^KFl2SvhW$bGW#kdWL-I)s_IqVnCDDM9fm8g;P;8 z7t4yZn3^*NQfx7SwmkzP$=fwdC}bafQSEF@pd&P8@H#`swGy_rz;Z?Ty5mkS%>m#% zp_!m9e<()sfKiY(nF<1zBz&&`ZlJf6QLvLhl`_``%RW&{+O>Xhp;lwSsyRqGf=RWd zpftiR`={2(siiPAS|p}@q=NhVc0ELprt%=fMXO3B)4ryC2LT(o=sLM7hJC!}T1@)E zA3^J$3&1*M6Xq>03FX`R&w*NkrZE?FwU+Muut;>qNhj@bX17ZJxnOlPSZ=Zeiz~T_ zOu#yc3t6ONHB;?|r4w+pI)~KGN;HOGC)txxiUN8#mexj+W(cz%9a4sx|IRG=}ia zuEBuba3AHsV2feqw-3MvuL`I+2|`Ud4~7ZkN=JZ;L20|Oxna5vx1qbIh#k2O4$RQF zo`tL()zxaqibg^GbB+BS5#U{@K;WWQj~GcB1zb}zJkPwH|5hZ9iH2308!>_;%msji zJHSL~s)YHBR=Koa1mLEOHos*`gp=s8KA-C zu0aE+W!#iJ*0xqKm3A`fUGy#O+X+5W36myS>Uh2!R*s$aCU^`K&KKLCCDkejX2p=5 z%o7-fl03x`gaSNyr?3_JLv?2RLS3F*8ub>Jd@^Cc17)v8vYEK4aqo?OS@W9mt%ITJ z9=S2%R8M){CugT@k~~0x`}Vl!svYqX=E)c_oU6o}#Hb^%G1l3BudxA{F*tbjG;W_>=xV73pKY53v%>I)@D36I_@&p$h|Aw zonQS`07z_F#@T-%@-Tb|)7;;anoD_WH>9ewFy(ZcEOM$#Y)8>qi7rCnsH9GO-_7zF zu*C87{Df1P4TEOsnzZ@H%&lvV(3V@;Q!%+OYRp`g05PjY^gL$^$-t0Y>H*CDDs?FZly*oZ&dxvsxaUWF!{em4{A>n@vpXg$dwvt@_rgmHF z-MER`ABa8R-t_H*kv>}CzOpz;!>p^^9ztHMsHL|SRnS<-y5Z*r(_}c4=fXF`l^-i}>e7v!qs_jv zqvWhX^F=2sDNWA9c@P0?lUlr6ecrTKM%pNQ^?*Lq?p-0~?_j50xV%^(+H>sMul#Tw zeciF*1=?a7cI(}352%>LO96pD+?9!fNyl^9v3^v&Y4L)mNGK0FN43&Xf8jUlxW1Bw zyiu2;qW-aGNhs=zbuoxnxiwZ3{PFZM#Kw)9H@(hgX23h(`Wm~m4&TvoZoYp{plb^> z_#?vXcxd>r7K+1HKJvhed>gtK`TAbJUazUWQY6T~t2af%#<+Veyr%7-#*A#@&*;@g58{i|E%6yC_InGXCOd{L0;$)z#?n7M`re zh!kO{6=>7I?*}czyF7_frt#)s1CFJ_XE&VrDA?Dp3XbvF{qsEJgb&OLSNz_5g?HpK z9)8rsr4JN!Af3G9!#Qn(6zaUDqLN(g2g8*M)Djap?WMK9NKlkC)E2|-g|#-rp%!Gz zAHd%`iq|81efi93m3yTBw3g0j#;Yb2X{mhRAI?&KDmbGqou(2xiRNb^sV}%%Wu0?< z?($L>(#BO*)^)rSgyNRni$i`R4v;GhlCZ8$@e^ROX(p=2_v6Y!%^As zu022)fHdv_-~Yu_H6WVPLpHQx!W%^6j)cBhS`O3QBW#x(eX54d&I22op(N59b*&$v zFiSRY6rOc^(dgSV1>a7-5C;(5S5MvKcM2Jm-LD9TGqDpP097%52V+0>Xqq!! zq4e3vj53SE6i8J`XcQB|MZPP8j;PAOnpGnllH6#Ku~vS42xP*Nz@~y%db7Xi8s09P z1)e%8ys6&M8D=Dt6&t`iKG_4X=!kgRQoh%Z`dc&mlOUqXk-k`jKv9@(a^2-Upw>?< zt5*^DV~6Zedbec4NVl($2T{&b)zA@b#dUyd>`2JC0=xa_fIm8{5um zr-!ApXZhC8@=vC2WyxO|!@0Km)h8ep*`^he92$@YwP>VcdoS5OC^s38e#7RPsg4j+ zbVGG}WRSET&ZfrcR(x~k8n1rTP%CnfUNKUonD$P?FtNFF#cn!wEIab-;jU=B1dHK@ z(;(yAQJ`O$sMn>h;pf^8{JISW%d+@v6@CnXh9n5TXGC}?FI9i-D0OMaIg&mAg=0Kn zNJ7oz5*ReJukD55fUsMuaP+H4tDN&V9zfqF@ zr=#ecUk9wu{0;!+gl;3Bw=Vn^)z$ahVhhw)io!na&9}LmWurLb0zubxK=UEnU*{5P z+SP}&*(iBKSO4{alBHaY^)5Q=mZ+2OwIooJ7*Q5XJ+2|q`9#f?6myq!&oz?klihLq z4C)$XP!BNS0G_Z1&TM>?Jk{S~{F3n83ioli=IO6f%wkvCl(RFFw~j0tb{GvXTx>*sB0McY0s&SNvj4+^h`9nJ_wM>F!Uc>X}9PifQekn0sKI2SAJP!a4h z5cyGTuCj3ZBM^&{dRelIlT^9zcfaAuL5Y~bl!ppSf`wZbK$z#6U~rdclk``e+!qhe z6Qspo*%<)eu6?C;Bp<^VuW6JI|Ncvyn+LlSl;Mp22Bl7ARQ0Xc24%29(ZrdsIPw&-=yHQ7_Vle|5h>AST0 zUGX2Zk34vp?U~IHT|;$U86T+UUHl_NE4m|}>E~6q``7hccCaT^#y+?wD##Q%HwPd8 zV3x4L4|qqu`B$4(LXqDJngNy-{&@aFBvVsywt@X^}iH7P%>bR?ciC$I^U-4Foa`YKI^qDyGK7k%E%c_P=yzAi`YnxGA%DeNd++j3*h^ z=rn>oBd0|~lZ<6YvmkKY*ZJlJ;Im0tqgWu&E92eqt;+NYdxx`eS(4Hw_Jb5|yVvBg z*tbdY^!AN;luEyN4VRhS@-_DC{({ziH{&Z}iGElSV~qvT>L-8G%+yEL zX#MFOhj{InyKG=mvW-<1B@c-}x$vA(nU?>S>0*eN#!SLzQ)Ex7fvQ)S4D<8|I#N$3 zT5Ei`Z?cxBODHX8(Xp73v`IsAYC@9b;t}z0wxVuQSY1J^GRwDPN@qbM-ZF48T$GZ< z8WU+;Pqo?{ghI-KZ-i*ydXu`Ep0Xw^McH_KE9J0S7G;x8Fe`DVG?j3Pv=0YzJ}yZR z%2=oqHiUjvuk0~Ca>Kol4CFi0_xQT~;_F?=u+!kIDl-9g`#ZNZ9HCy17Ga1v^Jv9# z{T4Kb1-AzUxq*MutfOWWZgD*HnFfyYg0&e9f(5tZ>krPF6{VikNeHoc{linPPt#Si z&*g>(c54V8rT_AX!J&bNm-!umPvOR}vDai#`CX___J#=zeB*{4<&2WpaDncZsOkp* zsg<%@@rbrMkR_ux9?LsQxzoBa1s%$BBn6vk#{&&zUwcfzeCBJUwFYSF$08qDsB;gWQN*g!p8pxjofWbqNSZOEKOaTx@+* zwdt5*Q47@EOZ~EZL9s?1o?A%9TJT=Ob_13yyugvPg*e&ZU(r6^k4=2+D-@n=Hv5vu zSXG|hM(>h9^zn=eQ=$6`JO&70&2|%V5Lsx>)(%#;pcOfu>*nk_3HB_BNaH$`jM<^S zcSftDU1?nL;jy)+sfonQN}(}gUW?d_ikr*3=^{G)=tjBtEPe>TO|0ddVB zTklrSHiW+!#26frPXQQ(YN8DG$PZo?(po(QUCCf_OJC`pw*uey00%gmH!`WJkrKXj2!#6?`T25mTu9OJp2L8z3! z=arrL$ZqxuE{%yV)14Kd>k}j7pxZ6#$Dz8$@WV5p8kTqN<-7W)Q7Gt2{KoOPK_tZ| zf2WG~O5@{qPI+W<4f_;reuFVdO^5`ADC1!JQE|N`s3cq@(0WB!n0uh@*c{=LAd;~} zyGK@hbF-Oo+!nN)@i*O(`@FA#u?o=~e{`4O#5}z&=UkU*50fOrzi11D^&FOqe>wii z?*k+2|EcUs;Gx{!@KBT~>PAwLrIDT7Th=Utu?~?np@t^gFs?zgX=D${RwOY^WGh-+ z+#4$066ISh8eYW#FXWp~S`<*%O^ZuItL1Tyqt8#tZ zY120E;^VG`!lZn&3sPd$RkdHpU#|w+bYV)pJC|SH9g%|5IkxVTQcBA4CL0}$&}ef@ zW^Vtj%M;;_1xxP9x#ex17&4N*{ksO*_4O}xYu(p*JkL#yr}@7b)t5X?%CY<+s5_MJ zuiqt+N_;A(_)%lumoyRFixWa-M7qK_9s6<1X?JDa9fP!+_6u~~M$5L=ipB=7(j#f< zZ34J%=bs549%~_mA(|={uZNs_0?o7;-LBP(ZRnkd{-^|2|=4vUTmtByHL8 zEph`(LSEzQj68a+`d$V<45J7cyv^#|^|%fD#si1Nx!4NW*`l*{->HEWNh6-|g>-=r zXmQ|-i}Ku$ndUeHQ^&ieT!Lf}vf6GaqW9$DJ2NWrqwPY%%4nip$@vK$nRp*_C-v<| zuKz~ZyN&<%!NS26&x?jhy+@awJipMQ-8(X4#Ae5??U<1QMt1l9R=w9fAnEF}NYu$2 z>6}Vkc zIb*A?G*z8^IvibmBKn_u^5&T_1oey0gZS2~obf(#xk=erZGTEdQnt3DMGM+0oPwss zj5zXD;(oWhB_T@~Ig#9@v)AKtXu3>Inmgf@A|-lD-1U>cNyl3h?ADD9)GG4}zUGPk zZzaXe!~Kf?<~@$G?Uql3t8jy9{2!doq4=J}j9ktTxss{p6!9UdjyDERlA*xZ!=Q)KDs5O)phz>Vq3BNGoM(H|=1*Q4$^2fTZw z(%nq1P|5Rt81}SYJpEEzMPl5VJsV5&4e)ZWKDyoZ>1EwpkHx-AQVQc8%JMz;{H~p{=FXV>jIxvm4X*qv52e?Y-f%DJ zxEA165GikEASQ^fH6K#d!Tpu2HP{sFs%E=e$gYd$aj$+xue6N+Wc(rAz~wUsk2`(b z8Kvmyz%bKQxpP}~baG-rwYcYCvkHOi zlkR<=>ZBTU*8RF_d#Bl@zZsRIhx<%~Z@Z=ik z>adw3!DK(8R|q$vy{FTxw%#xliD~6qXmY^7_9kthVPTF~Xy1CfBqbU~?1QmxmU=+k z(ggxvEuA;0e&+ci-zQR{-f7aO{O(Pz_OsEjLh_K>MbvoZ4nxtk5u{g@nPv)cgW_R} z9}EA4K4@z0?7ue}Z(o~R(X&FjejUI2g~08PH1E4w>9o{)S(?1>Z0XMvTb|;&EuyOE zGvWNpYX)Nv<8|a^;1>bh#&znEcl-r!T#pn= z4$?Yudha6F%4b>*8@=BdtXXY4N+`U4Dmx$}>HeVJk-QdTG@t!tVT#0(LeV0gvqyyw z2sEp^9eY0N`u10Tm4n8No&A=)IeEC|gnmEXoNSzu!1<4R<%-9kY_8~5Ej?zRegMn78wuMs#;i&eUA0Zk_RXQ3b&TT} z;SCI=7-FUB@*&;8|n>(_g^HGf3@QODE3LpmX~ELnymQm{Sx9xrKS zK29p~?v@R$0=v6Dr5aW>-!{+h@?Q58|Kz8{{W`%J+lDAdb&M5VHrX_mDY;1-JLnf)ezmPau$)1;=`-FU=-r-83tX=C`S#}GZufju zQ>sXNT0Ny=k@nc%cFnvA_i4SC)?_ORXHq8B4D%el1uPX`c~uG#S1M7C+*MMqLw78E zhY2dI8@+N^qrMI1+;TUda(vGqGSRyU{Fnm`aqrr7bz42c5xsOO-~oZpkzorD1g}Y<6rk&3>PsSGy}W?MtqFky@A(X# zIuNZK0cK?^=;PUAu>j0#HtjbHCV*6?jzA&OoE$*Jlga*}LF`SF?WLhv1O|zqC<>*> zYB;#lsYKx0&kH@BFpW8n*yDcc6?;_zaJs<-jPSkCsSX-!aV=P5kUgF@Nu<{a%#K*F z134Q{9|YX7X(v$62_cY3^G%t~rD>Q0z@)1|zs)vjJ6Jq9;7#Ki`w+eS**En?7;n&7 zu==V3T&eFboN3ZiMx3D8qYc;VjFUk_H-WWCau(VFXSQf~viH0L$gwD$UfFHqNcgN`x}M+YQ6RnN<+@t>JUp#)9YOkqst-Ga?{FsDpEeX0(5v{0J~SEbWiL zXC2}M4?UH@u&|;%0y`eb33ldo4~z-x8zY!oVmV=c+f$m?RfDC35mdQ2E>Pze7KWP- z>!Bh<&57I+O_^s}9Tg^k)h7{xx@0a0IA~GAOt2yy!X%Q$1rt~LbTB6@Du!_0%HV>N zlf)QI1&gvERKwso23mJ!Ou6ZS#zCS5W`gxE5T>C#E|{i<1D35C222I33?Njaz`On7 zi<+VWFP6D{e-{yiN#M|Jgk<44u1TiMI78S5W`Sdb5f+{zu34s{CfWN7a3Cf^@L%!& zN$?|!!9j2c)j$~+R6n#891w-z8(!oBpL2K=+%a$r2|~8-(vQj5_XT`<0Ksf;oP+tz z9CObS!0m)Tgg`K#xBM8B(|Z)Wb&DYL{WTYv`;A=q6~Nnx2+!lTIXtj8J7dZE!P_{z z#f8w6F}^!?^KE#+ZDv+xd5O&3EmomZzsv?>E-~ygGum45fk!SBN&|eo1rKw^?aZJ4 E2O(~oYXATM literal 0 HcmV?d00001 diff --git a/common/native-config/gradle/wrapper/gradle-wrapper.properties b/common/native-config/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..41dfb8790 --- /dev/null +++ b/common/native-config/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/common/native-config/gradlew b/common/native-config/gradlew new file mode 100755 index 000000000..4f906e0c8 --- /dev/null +++ b/common/native-config/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/common/native-config/gradlew.bat b/common/native-config/gradlew.bat new file mode 100644 index 000000000..107acd32c --- /dev/null +++ b/common/native-config/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/common/native-config/settings.gradle.kts b/common/native-config/settings.gradle.kts index a666a5c17..79d87f443 100644 --- a/common/native-config/settings.gradle.kts +++ b/common/native-config/settings.gradle.kts @@ -40,7 +40,8 @@ */ pluginManagement { - includeBuild("../../build-logic") + includeBuild("../../build-logic/settings-plugins") + includeBuild("../../build-logic/common-plugins") } plugins { diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java index d78c20bda..0eb980a47 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java @@ -43,20 +43,29 @@ import java.nio.file.Path; import java.util.Collection; import java.util.Set; -import java.util.stream.Collectors; +import java.util.function.Consumer; +/** + * Interface for accessing a native configuration repository. + * The goal of this repository is to answer questions like: + * "give me the configuration files for this artifact", where + * an artifact is represented by its GAV coordinates. + * + * The repository query may be configured for multiple artifacts + * and provide overrides for cases where configuration files + * are missing. + */ public interface NativeConfigurationRepository { /** - * Returns a list of configuration directories for the specified artifact. - * There may be more than one configuration directory for a given artifact, - * but the list may also be empty if the repository doesn't contain any. - * Never null. - * @param groupId the group id - * @param artifactId the artifac id - * @param version the version of the artifact - * @return a list of configuration directories + * Performs a generic query on the repository, returning a list of + * configuration directories. The query may be parameterized with + * a number of artifacts, and can be used to refine behavior, for + * example if a configuration directory isn't available for a + * particular artifact version. + * @param queryBuilder the query builder + * @return the set of configuration directories matching the query */ - Set findConfigurationDirectoriesFor(String groupId, String artifactId, String version); + Set findConfigurationDirectoriesFor(Consumer queryBuilder); /** * Returns a list of configuration directories for the specified artifact. @@ -67,11 +76,7 @@ public interface NativeConfigurationRepository { * @return a list of configuration directories */ default Set findConfigurationDirectoriesFor(String gavCoordinates) { - String[] gav = gavCoordinates.split(":"); - if (gav.length != 3) { - throw new IllegalArgumentException("Invalid GAV coordinates: " + gavCoordinates + " (expected format: groupId:artifactId:version)"); - } - return findConfigurationDirectoriesFor(gav[0], gav[1], gav[2]); + return findConfigurationDirectoriesFor(q -> q.forArtifacts(gavCoordinates)); } /** @@ -81,8 +86,6 @@ default Set findConfigurationDirectoriesFor(String gavCoordinates) { * @return the set of configuration directories */ default Set findConfigurationDirectoriesFor(Collection modules) { - return modules.stream() - .flatMap(m -> findConfigurationDirectoriesFor(m).stream()) - .collect(Collectors.toSet()); + return findConfigurationDirectoriesFor(q -> q.forArtifacts(modules)); } } diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/Query.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/Query.java new file mode 100644 index 000000000..4cb26041f --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/Query.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig; + +import java.util.Collection; +import java.util.function.Consumer; + +public interface Query { + void forArtifacts(String... gavCoordinates); + + default void forArtifacts(Collection gavCoordinates) { + forArtifacts(gavCoordinates.toArray(new String[0])); + } + + void forArtifact(Consumer config); + void useLatestConfigWhenVersionIsUntested(); + + interface ArtifactQuery { + void gav(String gavCoordinates); + void useLatestConfigWhenVersionIsUntested(); + void doNotUseLatestConfigWhenVersionIsUntested(); + void forceConfigVersion(String version); + } +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultArtifactQuery.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultArtifactQuery.java new file mode 100644 index 000000000..24798918d --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultArtifactQuery.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal; + +import org.graalvm.nativeconfig.Query; + +import java.util.Optional; + +public class DefaultArtifactQuery implements Query.ArtifactQuery { + + private String groupId; + private String artifactId; + private String version; + + private boolean useLatestVersion = false; + private String forcedConfig = null; + + @Override + public void gav(String gavCoordinates) { + String[] gav = gavCoordinates.split(":"); + if (gav.length != 3) { + throw new IllegalArgumentException("Invalid GAV coordinates: " + gavCoordinates + " (expected format: groupId:artifactId:version)"); + } + groupId = gav[0]; + artifactId = gav[1]; + version = gav[2]; + } + + @Override + public void useLatestConfigWhenVersionIsUntested() { + useLatestVersion = true; + forcedConfig = null; + } + + @Override + public void doNotUseLatestConfigWhenVersionIsUntested() { + useLatestVersion = false; + } + + @Override + public void forceConfigVersion(String version) { + useLatestVersion = false; + forcedConfig = version; + } + + public String getGroupId() { + return groupId; + } + + public String getArtifactId() { + return artifactId; + } + + public String getVersion() { + return version; + } + + public boolean isUseLatestVersion() { + return useLatestVersion; + } + + public Optional getForcedConfig() { + return Optional.ofNullable(forcedConfig); + } +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultQuery.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultQuery.java new file mode 100644 index 000000000..e8b0cab13 --- /dev/null +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultQuery.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeconfig.internal; + +import org.graalvm.nativeconfig.Query; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +public class DefaultQuery implements Query { + private boolean useLatest = false; + private final List> artifactsQueries = new ArrayList<>(); + + @Override + public void forArtifacts(String... gavCoordinates) { + for (String coordinates : gavCoordinates) { + forArtifact(q -> q.gav(coordinates)); + } + } + + @Override + public void forArtifact(Consumer config) { + artifactsQueries.add(config); + } + + @Override + public void useLatestConfigWhenVersionIsUntested() { + useLatest = true; + } + + List getArtifacts() { + return artifactsQueries.stream() + .map(spec -> { + DefaultArtifactQuery query = new DefaultArtifactQuery(); + if (useLatest) { + query.useLatestConfigWhenVersionIsUntested(); + } + spec.accept(query); + return query; + }) + .collect(Collectors.toList()); + } +} diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java index d9e939abd..3084e0c10 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java @@ -41,6 +41,7 @@ package org.graalvm.nativeconfig.internal; import org.graalvm.nativeconfig.NativeConfigurationRepository; +import org.graalvm.nativeconfig.Query; import org.graalvm.nativeconfig.internal.index.artifacts.SingleModuleJsonVersionToConfigDirectoryIndex; import org.graalvm.nativeconfig.internal.index.artifacts.VersionToConfigDirectoryIndex; import org.graalvm.nativeconfig.internal.index.modules.FileSystemModuleToConfigDirectoryIndex; @@ -50,6 +51,7 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; import java.util.stream.Collectors; public class FileSystemRepository implements NativeConfigurationRepository { @@ -62,16 +64,31 @@ public FileSystemRepository(Path rootDirectory) { } @Override - public Set findConfigurationDirectoriesFor(String groupId, String artifactId, String version) { - return moduleIndex.findConfigurationDirectories(groupId, artifactId) + public Set findConfigurationDirectoriesFor(Consumer queryBuilder) { + DefaultQuery query = new DefaultQuery(); + queryBuilder.accept(query); + return query.getArtifacts() .stream() - .map(dir -> { - VersionToConfigDirectoryIndex index = artifactIndexes.computeIfAbsent(dir, SingleModuleJsonVersionToConfigDirectoryIndex::new); - return index.findConfigurationDirectory(groupId, artifactId, version); + .flatMap(artifactQuery -> { + String groupId = artifactQuery.getGroupId(); + String artifactId = artifactQuery.getArtifactId(); + String version = artifactQuery.getVersion(); + return moduleIndex.findConfigurationDirectories(groupId, artifactId) + .stream() + .map(dir -> { + VersionToConfigDirectoryIndex index = artifactIndexes.computeIfAbsent(dir, SingleModuleJsonVersionToConfigDirectoryIndex::new); + if (artifactQuery.getForcedConfig().isPresent()) { + return index.findForcedConfiguration(artifactQuery.getForcedConfig().get()); + } + Optional configurationDirectory = index.findConfigurationDirectory(groupId, artifactId, version); + if (!configurationDirectory.isPresent() && artifactQuery.isUseLatestVersion()) { + configurationDirectory = index.findLatestConfigurationFor(groupId, artifactId); + } + return configurationDirectory; + }) + .filter(Optional::isPresent) + .map(Optional::get); }) - .filter(Optional::isPresent) - .map(Optional::get) .collect(Collectors.toSet()); } - } diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java index 04da47621..5b864f34c 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java @@ -80,6 +80,11 @@ private Map> parseIndexFile(Path rootPath) { } + @Override + public Optional findForcedConfiguration(String version) { + Path configDir = moduleRoot.resolve(version); + return Files.isDirectory(configDir) ? Optional.of(configDir) : Optional.empty(); + } /** * Returns the configuration directory for the requested artifact. diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java index 3eebc187f..8f6b8ce80 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java @@ -44,6 +44,15 @@ import java.util.Optional; public interface VersionToConfigDirectoryIndex { + + /** + * Returns the specified configuration directory version, ignoring + * any existing configuration. + * @param version the requested version + * @return the configuration directory + */ + Optional findForcedConfiguration(String version); + /** * Returns the configuration directory for the requested artifact. * @param groupId the group ID of the artifact diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java index d6f0e7b4c..5c9cebcf4 100644 --- a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java +++ b/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java @@ -41,12 +41,14 @@ package org.graalvm.nativeconfig.internal; +import org.graalvm.nativeconfig.Query; import org.junit.jupiter.api.Test; import java.io.File; import java.net.URISyntaxException; import java.nio.file.Path; import java.util.Set; +import java.util.function.Consumer; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -87,6 +89,86 @@ void testRepo2() { result.hasSinglePath("org/foo/2"); } + @Test + void canDefaultToLatestConfigDir() { + // when: + withRepo("repo1"); + lookup(q -> { + q.useLatestConfigWhenVersionIsUntested(); + q.forArtifacts("org:foo:1.2"); + }); + + // then: + result.hasSinglePath("org/foo/2"); + + //when: "order of spec shouldn't matter" + lookup(q -> { + q.forArtifacts("org:foo:1.2"); + q.useLatestConfigWhenVersionIsUntested(); + }); + + // then: + result.hasSinglePath("org/foo/2"); + } + + @Test + void canForceToParticularConfigVersion() { + // when: + withRepo("repo1"); + + lookup(q -> q.forArtifact(artifact -> { + artifact.gav("org:foo:1.2"); + artifact.forceConfigVersion("1"); + })); + + // then: + result.hasSinglePath("org/foo/1"); + } + + @Test + void forcingToNonExistentDirectoryReturnsEmpty() { + // when: + withRepo("repo1"); + + lookup(q -> q.forArtifact(artifact -> { + artifact.gav("org:foo:1.2"); + artifact.forceConfigVersion("123"); + })); + + // then: + result.isEmpty(); + } + + @Test + void canUseLatestConfigDir() { + // when: + withRepo("repo1"); + lookup(q -> q.forArtifact(artifact -> { + artifact.gav("org:foo:1.2"); + artifact.useLatestConfigWhenVersionIsUntested(); + })); + + // then: + result.hasSinglePath("org/foo/2"); + + // when: + lookup(q -> { + q.useLatestConfigWhenVersionIsUntested(); + q.forArtifact(artifact -> { + artifact.gav("org:foo:1.2"); + // Can override default global + artifact.doNotUseLatestConfigWhenVersionIsUntested(); + }); + }); + + // then: + result.isEmpty(); + } + + private void lookup(Consumer builder) { + result = new Result(repository.findConfigurationDirectoriesFor(builder), repoPath); + } + private void lookup(String gav) { result = new Result(repository.findConfigurationDirectoriesFor(gav), repoPath); } @@ -100,7 +182,7 @@ private void withRepo(String id) { } } - private static class Result { + private static final class Result { private final Path repoPath; private final Set configDirs; From 3a3b2987e772f613cae8db65599cd017981bc9a9 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Tue, 8 Feb 2022 11:55:52 +0100 Subject: [PATCH 18/30] Introduce the ability to configure queries Instead of simply querying by artifact GAV coordinates, the configuration repository can now be queried with an advanced query model which supports falling back to a default configuration directory, or overriding a particular version. --- .../gradle/native-image-testing.gradle | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 common/native-config/gradle/native-image-testing.gradle diff --git a/common/native-config/gradle/native-image-testing.gradle b/common/native-config/gradle/native-image-testing.gradle new file mode 100644 index 000000000..b7de78a52 --- /dev/null +++ b/common/native-config/gradle/native-image-testing.gradle @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import org.gradle.util.GFileUtils + +def agentOutput = layout.buildDirectory.dir("agent") + +ext { + testIdsDir = layout.buildDirectory.dir("test_ids") +} + +tasks.register("testConsoleLauncher", JavaExec) { + outputs.dir(agentOutput) + classpath = test.classpath + main = "org.junit.platform.console.ConsoleLauncher" + args = ["--scan-class-path"] + doFirst { + def agentOutputDir = agentOutput.get().asFile + if (agentOutputDir.exists()) { + GFileUtils.deleteDirectory(agentOutputDir) + } + if (project.hasProperty("agent")) { + mkdir "${agentOutputDir}" + new File("${agentOutputDir}", "agent-filter.json").text = """ + { + "rules":[ + { + "excludeClasses":"org.gradle.**" + }, + { + "excludeClasses":"java.**" + } + ] + } + """ + jvmArgs = [ + "-agentlib:native-image-agent=access-filter-file=${agentOutputDir}/agent-filter.json,experimental-class-loader-support,config-output-dir=${agentOutputDir}/agentOutput", + "-Dorg.graalvm.nativeimage.imagecode=agent" + ] + } + } +} + +abstract class NativeTestArgumentProvider implements CommandLineArgumentProvider { + @InputFiles + abstract ConfigurableFileCollection getClasspath() + + @InputDirectory + abstract DirectoryProperty getTestIdsDir() + + @InputDirectory + @Optional + abstract DirectoryProperty getAgentOutputDir() + + @Input + abstract Property getDiscovery() + + @Override + Iterable asArguments() { + def args = [ + "-cp", classpath.asPath, + "--no-fallback", + "--features=org.graalvm.junit.platform.JUnitPlatformFeature", + "-H:Name=native-image-tests", + "-H:Class=org.graalvm.junit.platform.NativeImageJUnitLauncher", + "-Djunit.platform.listeners.uid.tracking.output.dir=${testIdsDir.get().asFile.absolutePath}" + ] + if (agentOutputDir.isPresent()) { + def outputDir = agentOutputDir.get().asFile + if (!outputDir.exists()) { + throw new GradleException("Agent output missing when -Pagent is set.\n" + + "You need to run `gradle -Pagent test` first.") + } + + args << "-H:ConfigurationFileDirectories=${outputDir.absolutePath}/agentOutput" + args << "-H:+AllowIncompleteClasspath" + } + + if (discovery.get()) { + args << "-DtestDiscovery" + } + args.collect { it.toString() } + } +} + +tasks.named("test") { + doFirst { + agentOutput.get().asFile.mkdirs() + } +} + +tasks.register("nativeTestCompile", Exec) { + dependsOn(test) + inputs.files(test.classpath) + workingDir "${buildDir}" + executable = System.getenv("GRAALVM_HOME") + "/bin/native-image" + def argsProvider = objects.newInstance(NativeTestArgumentProvider) + argsProvider.classpath.from(test.classpath) + argsProvider.testIdsDir.set(testIdsDir) + argsProvider.agentOutputDir.set(agentOutput) + argsProvider.discovery.set(providers.systemProperty("testDiscovery").forUseAtConfigurationTime().map(v -> Boolean.valueOf(v)).orElse(false)) + argumentProviders.add(argsProvider) +} + +tasks.register("nativeTest", Exec) { + dependsOn nativeTestCompile + workingDir = "${buildDir}" + executable = "${buildDir}/native-image-tests" +} From efd25269c854bef1d28dbd52a4b136bfe708474b Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 9 Feb 2022 09:18:26 +0100 Subject: [PATCH 19/30] Initial support for fetching configuration from a configuration repo This commit adds the ability to setup a configuration repository. If used, then the dependency graph is used as an input to fetch configuration directories from the config repo. --- gradle/libs.versions.toml | 1 + native-gradle-plugin/build.gradle | 1 + .../buildtools/gradle/NativeImagePlugin.java | 57 ++++++ ...ativeConfigurationRepositoryExtension.java | 104 ++++++++++ .../internal/NativeConfigurationService.java | 183 ++++++++++++++++++ 5 files changed, 346 insertions(+) create mode 100644 native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java create mode 100644 native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bbd71df92..22a25771b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,6 +23,7 @@ nativeGradlePlugin = { module = "org.graalvm.buildtools:native-gradle-plugin", v nativeMavenPlugin = { module = "org.graalvm.buildtools:native-maven-plugin", version.ref = "nativeBuildTools" } junitPlatformNative = { module = "org.graalvm.buildtools:junit-platform-native", version.ref = "nativeBuildTools" } utils = { module = "org.graalvm.buildtools:utils", version.ref = "nativeBuildTools" } +nativeConfig = { module = "org.graalvm.buildtools:native-config", version.ref = "nativeBuildTools" } # External dependencies test-junit-platform-console = { module = "org.junit.platform:junit-platform-console", version.ref = "junitPlatform" } diff --git a/native-gradle-plugin/build.gradle b/native-gradle-plugin/build.gradle index 65aa34a80..2ccc70b7b 100644 --- a/native-gradle-plugin/build.gradle +++ b/native-gradle-plugin/build.gradle @@ -56,6 +56,7 @@ maven { dependencies { implementation libs.utils + implementation libs.nativeConfig testImplementation libs.test.spock testFixturesImplementation libs.test.spock testFixturesImplementation gradleTestKit() diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java index 1dc8e2d17..7ef27df69 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java @@ -44,6 +44,7 @@ import org.graalvm.buildtools.VersionInfo; import org.graalvm.buildtools.gradle.dsl.AgentConfiguration; import org.graalvm.buildtools.gradle.dsl.GraalVMExtension; +import org.graalvm.buildtools.gradle.dsl.NativeConfigurationRepositoryExtension; import org.graalvm.buildtools.gradle.dsl.NativeImageOptions; import org.graalvm.buildtools.gradle.internal.AgentCommandLineProvider; import org.graalvm.buildtools.gradle.internal.BaseNativeImageOptions; @@ -52,6 +53,7 @@ import org.graalvm.buildtools.gradle.internal.DeprecatedNativeImageOptions; import org.graalvm.buildtools.gradle.internal.GraalVMLogger; import org.graalvm.buildtools.gradle.internal.GradleUtils; +import org.graalvm.buildtools.gradle.internal.NativeConfigurationService; import org.graalvm.buildtools.gradle.internal.NativeConfigurations; import org.graalvm.buildtools.gradle.internal.ProcessGeneratedGraalResourceFiles; import org.graalvm.buildtools.gradle.tasks.BuildNativeImageTask; @@ -65,6 +67,7 @@ import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ConfigurationContainer; +import org.gradle.api.artifacts.ModuleVersionIdentifier; import org.gradle.api.attributes.Attribute; import org.gradle.api.attributes.AttributeContainer; import org.gradle.api.file.ArchiveOperations; @@ -77,6 +80,7 @@ import org.gradle.api.file.FileSystemOperations; import org.gradle.api.model.ObjectFactory; import org.gradle.api.plugins.ApplicationPlugin; +import org.gradle.api.plugins.ExtensionAware; import org.gradle.api.plugins.JavaApplication; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginConvention; @@ -101,10 +105,14 @@ import javax.inject.Inject; import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.concurrent.Callable; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -277,9 +285,43 @@ private void configureAutomaticTaskCreation(Project project, options.getConfigurationFileDirectories().from(generateResourcesConfig.map(t -> t.getOutputFile().map(f -> f.getAsFile().getParentFile()) )); + configureNativeConfigurationDirectories(project, graalExtension, options, sourceSet); }); } + private void configureNativeConfigurationDirectories(Project project, GraalVMExtension graalExtension, NativeImageOptions options, SourceSet sourceSet) { + NativeConfigurationRepositoryExtension repositoryExtension = nativeConfiguration(graalExtension); + Provider serviceProvider = project.getGradle() + .getSharedServices() + .registerIfAbsent("nativeConfigurationService", NativeConfigurationService.class, spec -> { + spec.getParameters().getUri().set(repositoryExtension.getUri()); + spec.getParameters().getCacheDir().set(new File(project.getGradle().getGradleUserHomeDir(), "native-build-tools/repositories")); + }); + options.getConfigurationFileDirectories().from(repositoryExtension.getEnabled().flatMap(enabled -> { + if (enabled) { + if (repositoryExtension.getUri().isPresent()) { + Configuration classpath = project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()); + Set excludedModules = repositoryExtension.getExcludedModules().getOrElse(Collections.emptySet()); + return serviceProvider.map(repo -> repo.findConfigurationDirectoriesFor(query -> classpath.getIncoming().getResolutionResult().allComponents(component -> { + ModuleVersionIdentifier moduleVersion = component.getModuleVersion(); + String module = moduleVersion.getGroup() + ":" + moduleVersion.getName(); + if (!excludedModules.contains(module)) { + query.forArtifact(artifact -> artifact.gav(module + ":" + moduleVersion.getVersion())); + } + })).stream() + .map(Path::toAbsolutePath) + .map(Path::toFile) + .collect(Collectors.toList())); + } + } + return project.getProviders().provider(Collections::emptySet); + })); + } + + private static NativeConfigurationRepositoryExtension nativeConfiguration(GraalVMExtension graalExtension) { + return ((ExtensionAware) graalExtension).getExtensions().getByType(NativeConfigurationRepositoryExtension.class); + } + private void deprecateExtension(Project project, NativeImageOptions delegate, String name, @@ -338,9 +380,24 @@ private GraalVMExtension registerGraalVMExtension(Project project) { graalvmNative.getGeneratedResourcesDirectory().set(project.getLayout() .getBuildDirectory() .dir("native/generated/")); + configureNativeConfigurationRepo((ExtensionAware) graalvmNative); return graalvmNative; } + private void configureNativeConfigurationRepo(ExtensionAware graalvmNative) { + NativeConfigurationRepositoryExtension configurationRepository = graalvmNative.getExtensions().create("configurationRepository", NativeConfigurationRepositoryExtension.class); + configurationRepository.getEnabled().convention(false); + configurationRepository.getUri().convention(configurationRepository.getVersion().map(v -> { + try { + // TODO: replace with real URI + return new URI("https://github.com/graalvm/native-configuration/releases/download/" + v + "/native-configuration-" + v + ".zip"); + } catch (URISyntaxException e) { + return null; + } + })); + configurationRepository.getExcludedModules().convention(Collections.emptySet()); + } + private TaskProvider registerResourcesConfigTask(Provider generatedDir, NativeImageOptions options, TaskContainer tasks, diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java new file mode 100644 index 000000000..9d8a3e002 --- /dev/null +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.buildtools.gradle.dsl; + +import org.gradle.api.provider.Property; +import org.gradle.api.provider.SetProperty; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * Extension used to configure the native configuration + * repository. + */ +public interface NativeConfigurationRepositoryExtension { + /** + * Property used to determine if the native configuration + * repository should be used. + * @return the enabled property + */ + Property getEnabled(); + + /** + * A URI pointing to a configuration repository. This must + * either be a local file or a remote URI. In case of remote + * files, only zip or tarballs are supported. + * @return the uri property + */ + Property getUri(); + + /** + * An optional version of the remote repository: if specified, + * and that no URI is provided, it will automatically use a + * published repository from the official GraalVM configuration + * repository. + * + * @return the version of the repository to use + */ + Property getVersion(); + + /** + * The set of modules for which we don't want to use the + * configuration found in the repository. Modules must be + * declared with the `groupId:artifactId` syntax. + * @return the set of excluded modules + */ + SetProperty getExcludedModules(); + + /** + * Convenience method to use a String for the URI + * property + * @param uri the URI + */ + default void uri(String uri) throws URISyntaxException { + getUri().set(new URI(uri)); + } + + /** + * Convenience method to use a URI for the property + * @param file a file + */ + default void uri(File file) { + getUri().set(file.toURI()); + } +} diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java new file mode 100644 index 000000000..66a0a01d4 --- /dev/null +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java @@ -0,0 +1,183 @@ +/* + * Copyright 2003-2021 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.graalvm.buildtools.gradle.internal; + +import org.graalvm.nativeconfig.NativeConfigurationRepository; +import org.graalvm.nativeconfig.Query; +import org.graalvm.nativeconfig.internal.FileSystemRepository; +import org.gradle.api.file.ArchiveOperations; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.FileSystemOperations; +import org.gradle.api.logging.Logger; +import org.gradle.api.logging.Logging; +import org.gradle.api.provider.Property; +import org.gradle.api.services.BuildService; +import org.gradle.api.services.BuildServiceParameters; + +import javax.inject.Inject; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Collection; +import java.util.Set; +import java.util.function.Consumer; + +public abstract class NativeConfigurationService implements BuildService, NativeConfigurationRepository { + private static final Logger LOGGER = Logging.getLogger(NativeConfigurationService.class); + + private final NativeConfigurationRepository repository; + + @Inject + protected abstract ArchiveOperations getArchiveOperations(); + + @Inject + protected abstract FileSystemOperations getFileOperations(); + + public interface Params extends BuildServiceParameters { + Property getUri(); + + DirectoryProperty getCacheDir(); + } + + public NativeConfigurationService() throws URISyntaxException { + URI uri = getParameters().getUri().get(); + this.repository = newRepository(uri); + } + + private static String hashFor(URI uri) { + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] messageDigest = md.digest(md.digest(uri.toString().getBytes("utf-8"))); + BigInteger no = new BigInteger(1, messageDigest); + StringBuilder digest = new StringBuilder(no.toString(16)); + while (digest.length() < 32) { + digest.insert(0, "0"); + } + return digest.toString(); + } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { + throw new UnsupportedOperationException(e); + } + } + + private NativeConfigurationRepository newRepository(URI uri) throws URISyntaxException { + String cacheKey = hashFor(uri); + String path = uri.getPath(); + if (uri.getScheme().equals("file")) { + File localFile = new File(uri); + if (isSupportedZipFormat(path)) { + return newRepositoryFromZipFile(cacheKey, localFile); + } + return newRepositoryFromDirectory(localFile.toPath()); + } + if (isSupportedZipFormat(path)) { + File zipped = getParameters().getCacheDir().file(cacheKey + "/archive").get().getAsFile(); + if (!zipped.exists()) { + try (ReadableByteChannel readableByteChannel = Channels.newChannel(uri.toURL().openStream())) { + try (FileOutputStream fileOutputStream = new FileOutputStream(zipped)) { + fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return newRepositoryFromZipFile(cacheKey, zipped); + } + throw new UnsupportedOperationException("Remote URI must point to a zip, a tar.gz or tar.bz2 file"); + } + + private static boolean isSupportedZipFormat(String path) { + return path.endsWith(".zip") || path.endsWith(".tar.gz") || path.endsWith(".tar.bz2"); + } + + private FileSystemRepository newRepositoryFromZipFile(String cacheKey, File localFile) { + File explodedEntry = getParameters().getCacheDir().file(cacheKey + "/exploded").get().getAsFile(); + if (!explodedEntry.exists()) { + if (explodedEntry.getParentFile().isDirectory() || explodedEntry.getParentFile().mkdirs()) { + LOGGER.info("Extracting {} to {}", localFile, explodedEntry); + getFileOperations().copy(spec -> { + if (localFile.getName().endsWith(".zip")) { + spec.from(getArchiveOperations().zipTree(localFile)); + } else if (localFile.getName().endsWith(".tar.gz")) { + spec.from(getArchiveOperations().tarTree(localFile)); + } else if (localFile.getName().endsWith(".tar.bz2")) { + spec.from(getArchiveOperations().tarTree(localFile)); + } + spec.into(explodedEntry); + }); + } + } + return newRepositoryFromDirectory(explodedEntry.toPath()); + } + + private FileSystemRepository newRepositoryFromDirectory(Path path) { + if (Files.isDirectory(path)) { + return new FileSystemRepository(path); + } else { + throw new IllegalArgumentException("Native configuration repository URI must point to a directory"); + } + } + + /** + * Performs a generic query on the repository, returning a list of + * configuration directories. The query may be parameterized with + * a number of artifacts, and can be used to refine behavior, for + * example if a configuration directory isn't available for a + * particular artifact version. + * + * @param queryBuilder the query builder + * @return the set of configuration directories matching the query + */ + @Override + public Set findConfigurationDirectoriesFor(Consumer queryBuilder) { + return repository.findConfigurationDirectoriesFor(queryBuilder); + } + + /** + * Returns a list of configuration directories for the specified artifact. + * There may be more than one configuration directory for a given artifact, + * but the list may also be empty if the repository doesn't contain any. + * Never null. + * + * @param gavCoordinates the artifact GAV coordinates (group:artifact:version) + * @return a list of configuration directories + */ + @Override + public Set findConfigurationDirectoriesFor(String gavCoordinates) { + return repository.findConfigurationDirectoriesFor(gavCoordinates); + } + + /** + * Returns the set of configuration directories for all the modules supplied + * as an argument. + * + * @param modules the list of modules + * @return the set of configuration directories + */ + @Override + public Set findConfigurationDirectoriesFor(Collection modules) { + return repository.findConfigurationDirectoriesFor(modules); + } +} From fdaeefc7c3b3688e45a127524c176e5d8505b762 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Tue, 1 Mar 2022 16:59:08 +0100 Subject: [PATCH 20/30] Add integration testing for native config repository This commit introduces testing of the native configuration repository integration for Gradle. Instead of using the "real" configuration repository, which would require writing a test library which uses "unsupported" GraalVM features, the tests use a test fixture, a library which makes use of reflection. This library is injected into the tests and we create a corresponding test repository. --- .../junit-platform-native-feature.yml | 16 +-- .github/workflows/native-config.yml | 11 +- .github/workflows/native-gradle-plugin.yml | 10 +- .github/workflows/native-maven-plugin.yml | 5 +- .../internal/FileSystemRepository.java | 38 ++++++- .../internal/index/artifacts/Artifact.java | 2 + .../internal/index/modules/ModuleEntry.java | 2 + native-gradle-plugin/build.gradle | 1 + native-gradle-plugin/settings.gradle | 1 + .../NativeConfigRepoFunctionalTest.groovy | 91 ++++++++++++++++ .../buildtools/gradle/NativeImagePlugin.java | 15 +++ ...ativeConfigurationRepositoryExtension.java | 4 +- .../internal/NativeConfigurationService.java | 69 +++++++++--- native-maven-plugin/build.gradle.kts | 1 + .../native-config-integration/build.gradle | 102 ++++++++++++++++++ .../config-directory/index.json | 1 + .../1/reflect-config.json | 7 ++ .../library-with-reflection/index.json | 13 +++ .../gradle.properties | 3 + .../native-config-integration/settings.gradle | 52 +++++++++ .../java/org/graalvm/example/Application.java | 10 ++ .../library-with-reflection/build.gradle.kts | 21 ++++ .../settings.gradle.kts | 5 + .../org/graalvm/internal/reflect/Greeter.java | 44 ++++++++ .../org/graalvm/internal/reflect/Message.java | 22 ++++ 25 files changed, 492 insertions(+), 54 deletions(-) create mode 100644 native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy create mode 100644 samples/native-config-integration/build.gradle create mode 100644 samples/native-config-integration/config-directory/index.json create mode 100644 samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/1/reflect-config.json create mode 100644 samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/index.json create mode 100644 samples/native-config-integration/gradle.properties create mode 100644 samples/native-config-integration/settings.gradle create mode 100644 samples/native-config-integration/src/main/java/org/graalvm/example/Application.java create mode 100644 test-support/library-with-reflection/build.gradle.kts create mode 100644 test-support/library-with-reflection/settings.gradle.kts create mode 100644 test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Greeter.java create mode 100644 test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Message.java diff --git a/.github/workflows/junit-platform-native-feature.yml b/.github/workflows/junit-platform-native-feature.yml index 328fe7908..d1bf9c2f4 100644 --- a/.github/workflows/junit-platform-native-feature.yml +++ b/.github/workflows/junit-platform-native-feature.yml @@ -26,21 +26,11 @@ jobs: echo "JAVA_HOME=$JAVA_HOME" >> $GITHUB_ENV echo "GRAALVM_HOME=$GRAALVM_HOME" >> $GITHUB_ENV - name: Checkstyle - run: | - pushd common/junit-platform-native - ./gradlew checkstyleMain - ./gradlew checkstyleTest - popd + run: ./gradlew :junit-platform-native:checkstyleMain :junit-platform-native:checkstyleTest - name: JVM test - run: | - pushd common/junit-platform-native - ./gradlew test - popd + run: ./gradlew :junit-platform-native:test - name: Feature test - run: | - pushd common/junit-platform-native - ./gradlew nativeTest - popd + run: ./gradlew :junit-platform-native:nativeTest - name: Tests results if: always() uses: actions/upload-artifact@v2 diff --git a/.github/workflows/native-config.yml b/.github/workflows/native-config.yml index 86186f36c..9feb2f079 100644 --- a/.github/workflows/native-config.yml +++ b/.github/workflows/native-config.yml @@ -26,16 +26,9 @@ jobs: echo "JAVA_HOME=$JAVA_HOME" >> $GITHUB_ENV echo "GRAALVM_HOME=$GRAALVM_HOME" >> $GITHUB_ENV - name: Checkstyle - run: | - pushd common/native-config - ./gradlew checkstyleMain - ./gradlew checkstyleTest - popd + run: ./gradlew :native-config:checkstyleMain :native-config:checkstyleTest - name: JVM test - run: | - pushd common/native-config - ./gradlew test - popd + run: ./gradlew :native-config:test - name: Tests results if: always() uses: actions/upload-artifact@v2 diff --git a/.github/workflows/native-gradle-plugin.yml b/.github/workflows/native-gradle-plugin.yml index f23a97cb4..b459b42ac 100644 --- a/.github/workflows/native-gradle-plugin.yml +++ b/.github/workflows/native-gradle-plugin.yml @@ -30,10 +30,7 @@ jobs: echo "JAVA_HOME=$JAVA_HOME" >> $GITHUB_ENV echo "GRAALVM_HOME=$GRAALVM_HOME" >> $GITHUB_ENV - name: Unit tests and inspections - run: | - pushd native-gradle-plugin - ./gradlew test inspections - popd + run: ./gradlew :native-gradle-plugin:test :native-gradle-plugin:inspections - name: Unit tests results uses: actions/upload-artifact@v1 with: @@ -57,10 +54,7 @@ jobs: echo "JAVA_HOME=$JAVA_HOME" >> $GITHUB_ENV echo "GRAALVM_HOME=$GRAALVM_HOME" >> $GITHUB_ENV - name: Check and test the plugin - run: | - pushd native-gradle-plugin - ./gradlew functionalTest -DgradleVersion=${{ matrix.gradle-version }} - popd + run: ./gradlew :native-gradle-plugin:functionalTest -DgradleVersion=${{ matrix.gradle-version }} - name: Functional tests results if: always() uses: actions/upload-artifact@v2 diff --git a/.github/workflows/native-maven-plugin.yml b/.github/workflows/native-maven-plugin.yml index 80bcb70f3..9c7761ddf 100644 --- a/.github/workflows/native-maven-plugin.yml +++ b/.github/workflows/native-maven-plugin.yml @@ -30,10 +30,7 @@ jobs: echo "JAVA_HOME=$JAVA_HOME" >> $GITHUB_ENV echo "GRAALVM_HOME=$GRAALVM_HOME" >> $GITHUB_ENV - name: Check and test the plugin - run: | - pushd native-maven-plugin - ./gradlew check --no-daemon - popd + run: ./gradlew :native-maven-plugin:check --no-daemon - name: Tests results if: always() uses: actions/upload-artifact@v2 diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java index 3084e0c10..a6cdf7aee 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java @@ -52,15 +52,24 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; +import java.util.function.Supplier; import java.util.stream.Collectors; public class FileSystemRepository implements NativeConfigurationRepository { private final FileSystemModuleToConfigDirectoryIndex moduleIndex; + private final Logger logger; private final Map artifactIndexes; + private final Path rootDirectory; public FileSystemRepository(Path rootDirectory) { + this(rootDirectory, new Logger() {}); + } + + public FileSystemRepository(Path rootDirectory, Logger logger) { this.moduleIndex = new FileSystemModuleToConfigDirectoryIndex(rootDirectory); + this.logger = logger; this.artifactIndexes = new ConcurrentHashMap<>(); + this.rootDirectory = rootDirectory; } @Override @@ -78,12 +87,26 @@ public Set findConfigurationDirectoriesFor(Consumer queryBu .map(dir -> { VersionToConfigDirectoryIndex index = artifactIndexes.computeIfAbsent(dir, SingleModuleJsonVersionToConfigDirectoryIndex::new); if (artifactQuery.getForcedConfig().isPresent()) { - return index.findForcedConfiguration(artifactQuery.getForcedConfig().get()); + String configVersion = artifactQuery.getForcedConfig().get(); + logger.log(groupId, artifactId, version, "Configuration is forced to version " + configVersion); + return index.findForcedConfiguration(configVersion); } Optional configurationDirectory = index.findConfigurationDirectory(groupId, artifactId, version); if (!configurationDirectory.isPresent() && artifactQuery.isUseLatestVersion()) { + logger.log(groupId, artifactId, version, "Configuration directory not found. Trying latest version."); configurationDirectory = index.findLatestConfigurationFor(groupId, artifactId); + if (!configurationDirectory.isPresent()) { + logger.log(groupId, artifactId, version, "Latest version not found!"); + } } + Optional finalConfigurationDirectory = configurationDirectory; + logger.log(groupId, artifactId, version, () -> { + if (finalConfigurationDirectory.isPresent()) { + Path path = finalConfigurationDirectory.get(); + return "Configuration directory is " + rootDirectory.relativize(path); + } + return "missing."; + }); return configurationDirectory; }) .filter(Optional::isPresent) @@ -91,4 +114,17 @@ public Set findConfigurationDirectoriesFor(Consumer queryBu }) .collect(Collectors.toSet()); } + + /** + * Allows getting insights about how configuration is picked. + */ + public interface Logger { + default void log(String groupId, String artifactId, String version, String message) { + log(groupId, artifactId, version, () -> message); + } + + default void log(String groupId, String artifactId, String version, Supplier message) { + + } + } } diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java index 3fa727c5a..fc9b40c4d 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java @@ -41,10 +41,12 @@ package org.graalvm.nativeconfig.internal.index.artifacts; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Set; +@JsonIgnoreProperties(ignoreUnknown = true) public class Artifact { private final String module; private final Set versions; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java index ba44f2d27..a35d0497b 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java +++ b/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java @@ -41,11 +41,13 @@ package org.graalvm.nativeconfig.internal.index.modules; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Collections; import java.util.List; +@JsonIgnoreProperties(ignoreUnknown = true) public class ModuleEntry { private final String module; private final String moduleDirectory; diff --git a/native-gradle-plugin/build.gradle b/native-gradle-plugin/build.gradle index 2ccc70b7b..81bf14c89 100644 --- a/native-gradle-plugin/build.gradle +++ b/native-gradle-plugin/build.gradle @@ -61,6 +61,7 @@ dependencies { testFixturesImplementation libs.test.spock testFixturesImplementation gradleTestKit() functionalTestCommonRepository(libs.junitPlatformNative) + functionalTestCommonRepository("org.graalvm.internal:library-with-reflection") } pluginBundle { diff --git a/native-gradle-plugin/settings.gradle b/native-gradle-plugin/settings.gradle index 165d7091d..a26690df8 100644 --- a/native-gradle-plugin/settings.gradle +++ b/native-gradle-plugin/settings.gradle @@ -53,3 +53,4 @@ rootProject.name = 'native-gradle-plugin' includeBuild("../common/junit-platform-native") includeBuild("../common/utils") +includeBuild("../test-support/library-with-reflection") diff --git a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy new file mode 100644 index 000000000..e384c46b4 --- /dev/null +++ b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.graalvm.buildtools.gradle + +import org.graalvm.buildtools.gradle.fixtures.AbstractFunctionalTest +import org.gradle.api.logging.LogLevel +import spock.lang.Unroll + +class NativeConfigRepoFunctionalTest extends AbstractFunctionalTest { + + @Unroll + def "can build a native image using native configuration from a #label"() { + given: + withSample("native-config-integration") + + switch (format) { + case 'dir': + break + case 'zip': + run 'configZip' + break + default: + run "config${format.split('[.]').collect {it.capitalize()}.join("")}" + } + + when: + def extension = format == 'dir' ? '' : format + run 'nativeRun', "-D${NativeImagePlugin.CONFIG_REPO_LOGLEVEL}=${LogLevel.LIFECYCLE}", "-Dextension=$extension" + + then: + tasks { + succeeded ':jar', ':nativeCompile', ':nativeRun' + } + + then: + outputContains "Hello, from reflection!" + + and: "doesn't find a configuration directory for the current version" + outputContains "[configuration repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration directory not found. Trying latest version." + + and: "but finds one thanks to the latest configuration field" + outputContains "[configuration repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration directory is org/graalvm/internal/library-with-reflection/1" + + where: + format | label + 'dir' | "flat directory" + 'zip' | 'zip file' + 'tar.gz' | 'tar.gz file' + 'tar.bz2' | 'tar.bz2 file' + } + +} diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java index 7ef27df69..1dd511d45 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java @@ -78,6 +78,7 @@ import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileSystemLocation; import org.gradle.api.file.FileSystemOperations; +import org.gradle.api.logging.LogLevel; import org.gradle.api.model.ObjectFactory; import org.gradle.api.plugins.ApplicationPlugin; import org.gradle.api.plugins.ExtensionAware; @@ -142,6 +143,8 @@ public class NativeImagePlugin implements Plugin { public static final String DEPRECATED_NATIVE_BUILD_TASK = "nativeBuild"; public static final String DEPRECATED_NATIVE_TEST_BUILD_TASK = "nativeTestBuild"; + public static final String CONFIG_REPO_LOGLEVEL = "org.graalvm.internal.gradle.configrepo.logging"; + /** * This looks strange, but it is used to force the configuration of a dependent * task during the configuration of another one. This is a workaround for a bug @@ -294,6 +297,8 @@ private void configureNativeConfigurationDirectories(Project project, GraalVMExt Provider serviceProvider = project.getGradle() .getSharedServices() .registerIfAbsent("nativeConfigurationService", NativeConfigurationService.class, spec -> { + LogLevel logLevel = determineLogLevel(); + spec.getParameters().getLogLevel().set(logLevel); spec.getParameters().getUri().set(repositoryExtension.getUri()); spec.getParameters().getCacheDir().set(new File(project.getGradle().getGradleUserHomeDir(), "native-build-tools/repositories")); }); @@ -308,6 +313,7 @@ private void configureNativeConfigurationDirectories(Project project, GraalVMExt if (!excludedModules.contains(module)) { query.forArtifact(artifact -> artifact.gav(module + ":" + moduleVersion.getVersion())); } + query.useLatestConfigWhenVersionIsUntested(); })).stream() .map(Path::toAbsolutePath) .map(Path::toFile) @@ -318,6 +324,15 @@ private void configureNativeConfigurationDirectories(Project project, GraalVMExt })); } + private static LogLevel determineLogLevel() { + LogLevel logLevel = LogLevel.DEBUG; + String loggingProperty = System.getProperty(CONFIG_REPO_LOGLEVEL); + if (loggingProperty != null) { + logLevel = LogLevel.valueOf(loggingProperty.toUpperCase(Locale.US)); + } + return logLevel; + } + private static NativeConfigurationRepositoryExtension nativeConfiguration(GraalVMExtension graalExtension) { return ((ExtensionAware) graalExtension).getExtensions().getByType(NativeConfigurationRepositoryExtension.class); } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java index 9d8a3e002..039fdf38c 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java @@ -87,7 +87,7 @@ public interface NativeConfigurationRepositoryExtension { /** * Convenience method to use a String for the URI - * property + * property. * @param uri the URI */ default void uri(String uri) throws URISyntaxException { @@ -95,7 +95,7 @@ default void uri(String uri) throws URISyntaxException { } /** - * Convenience method to use a URI for the property + * Convenience method to use a URI for the property. * @param file a file */ default void uri(File file) { diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java index 66a0a01d4..cd3e550e9 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java @@ -1,17 +1,42 @@ /* - * Copyright 2003-2021 the original author or authors. + * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * 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 + * The Universal Permissive License (UPL), Version 1.0 * - * https://www.apache.org/licenses/LICENSE-2.0 + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both * - * 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. + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ package org.graalvm.buildtools.gradle.internal; @@ -21,6 +46,7 @@ import org.gradle.api.file.ArchiveOperations; import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.FileSystemOperations; +import org.gradle.api.logging.LogLevel; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; import org.gradle.api.provider.Property; @@ -44,6 +70,7 @@ import java.util.Collection; import java.util.Set; import java.util.function.Consumer; +import java.util.function.Supplier; public abstract class NativeConfigurationService implements BuildService, NativeConfigurationRepository { private static final Logger LOGGER = Logging.getLogger(NativeConfigurationService.class); @@ -57,6 +84,8 @@ public abstract class NativeConfigurationService implements BuildService getLogLevel(); + Property getUri(); DirectoryProperty getCacheDir(); @@ -85,12 +114,13 @@ private static String hashFor(URI uri) { private NativeConfigurationRepository newRepository(URI uri) throws URISyntaxException { String cacheKey = hashFor(uri); String path = uri.getPath(); + LogLevel logLevel = getParameters().getLogLevel().get(); if (uri.getScheme().equals("file")) { File localFile = new File(uri); if (isSupportedZipFormat(path)) { - return newRepositoryFromZipFile(cacheKey, localFile); + return newRepositoryFromZipFile(cacheKey, localFile, logLevel); } - return newRepositoryFromDirectory(localFile.toPath()); + return newRepositoryFromDirectory(localFile.toPath(), logLevel); } if (isSupportedZipFormat(path)) { File zipped = getParameters().getCacheDir().file(cacheKey + "/archive").get().getAsFile(); @@ -103,7 +133,7 @@ private NativeConfigurationRepository newRepository(URI uri) throws URISyntaxExc throw new RuntimeException(e); } } - return newRepositoryFromZipFile(cacheKey, zipped); + return newRepositoryFromZipFile(cacheKey, zipped, logLevel); } throw new UnsupportedOperationException("Remote URI must point to a zip, a tar.gz or tar.bz2 file"); } @@ -112,7 +142,7 @@ private static boolean isSupportedZipFormat(String path) { return path.endsWith(".zip") || path.endsWith(".tar.gz") || path.endsWith(".tar.bz2"); } - private FileSystemRepository newRepositoryFromZipFile(String cacheKey, File localFile) { + private FileSystemRepository newRepositoryFromZipFile(String cacheKey, File localFile, LogLevel logLevel) { File explodedEntry = getParameters().getCacheDir().file(cacheKey + "/exploded").get().getAsFile(); if (!explodedEntry.exists()) { if (explodedEntry.getParentFile().isDirectory() || explodedEntry.getParentFile().mkdirs()) { @@ -129,12 +159,17 @@ private FileSystemRepository newRepositoryFromZipFile(String cacheKey, File loca }); } } - return newRepositoryFromDirectory(explodedEntry.toPath()); + return newRepositoryFromDirectory(explodedEntry.toPath(), logLevel); } - private FileSystemRepository newRepositoryFromDirectory(Path path) { + private FileSystemRepository newRepositoryFromDirectory(Path path, LogLevel logLevel) { if (Files.isDirectory(path)) { - return new FileSystemRepository(path); + return new FileSystemRepository(path, new FileSystemRepository.Logger() { + @Override + public void log(String groupId, String artifactId, String version, Supplier message) { + LOGGER.log(logLevel, "[configuration repository for {}:{}:{}]: {}", groupId, artifactId, version, message.get()); + } + }); } else { throw new IllegalArgumentException("Native configuration repository URI must point to a directory"); } diff --git a/native-maven-plugin/build.gradle.kts b/native-maven-plugin/build.gradle.kts index 440b02907..508d24e6d 100644 --- a/native-maven-plugin/build.gradle.kts +++ b/native-maven-plugin/build.gradle.kts @@ -101,6 +101,7 @@ val localRepositoryDir = project.layout.buildDirectory.dir("maven-seeded-repo") tasks { generatePluginDescriptor { + dependsOn(prepareMavenLocalRepo) commonRepository.set(repoDirectory) localRepository.set(localRepositoryDir) } diff --git a/samples/native-config-integration/build.gradle b/samples/native-config-integration/build.gradle new file mode 100644 index 000000000..13560620d --- /dev/null +++ b/samples/native-config-integration/build.gradle @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +plugins { + id 'application' + id 'org.graalvm.buildtools.native' +} + +repositories { + mavenCentral() +} + +application { + mainClass.set('org.graalvm.example.Application') +} + +def junitVersion = providers.gradleProperty('junit.jupiter.version') + .forUseAtConfigurationTime() + .get() + +dependencies { + implementation("org.graalvm.internal:library-with-reflection:1.5") + + testImplementation(platform("org.junit:junit-bom:${junitVersion}")) + testImplementation('org.junit.jupiter:junit-jupiter') +} + +tasks.withType(Test).configureEach { + useJUnitPlatform() +} + +graalvmNative { + configurationRepository { + enabled = true + def extension = System.getProperty("extension", '') + def repo = file("config-directory${extension ? '.' + extension : ''}") + println("Using config repo: $repo") + uri(repo) + } + binaries.all { + verbose = true + runtimeArgs.add("-DmessageClass=org.graalvm.internal.reflect.Message") + } +} + +tasks.register("configZip", Zip) { + destinationDirectory = project.layout.projectDirectory + from(file("config-directory")) + archiveName = 'config-directory.zip' +} + +tasks.register("configTarGz", Tar) { + destinationDirectory = project.layout.projectDirectory + compression = Compression.GZIP + from(file("config-directory")) + archiveName = 'config-directory.tar.gz' +} + +tasks.register("configTarBz2", Tar) { + destinationDirectory = project.layout.projectDirectory + compression = Compression.BZIP2 + from(file("config-directory")) + archiveName = 'config-directory.tar.bz2' +} diff --git a/samples/native-config-integration/config-directory/index.json b/samples/native-config-integration/config-directory/index.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/samples/native-config-integration/config-directory/index.json @@ -0,0 +1 @@ +[] diff --git a/samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/1/reflect-config.json b/samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/1/reflect-config.json new file mode 100644 index 000000000..b4de3b1f5 --- /dev/null +++ b/samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/1/reflect-config.json @@ -0,0 +1,7 @@ +[ + { + "name": "org.graalvm.internal.reflect.Message", + "allDeclaredFields": true, + "allDeclaredMethods": true + } +] diff --git a/samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/index.json b/samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/index.json new file mode 100644 index 000000000..cb1bc5060 --- /dev/null +++ b/samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/index.json @@ -0,0 +1,13 @@ +[ + { + "module": "org.graalvm.internal:library-with-reflection", + "tested-versions": [ + "1.0", + "1.1", + "1.2", + "1.3" + ], + "config-version": "1", + "latest": true + } +] diff --git a/samples/native-config-integration/gradle.properties b/samples/native-config-integration/gradle.properties new file mode 100644 index 000000000..030694402 --- /dev/null +++ b/samples/native-config-integration/gradle.properties @@ -0,0 +1,3 @@ +native.gradle.plugin.version = 0.9.11-SNAPSHOT +junit.jupiter.version = 5.8.1 +junit.platform.version = 1.8.1 diff --git a/samples/native-config-integration/settings.gradle b/samples/native-config-integration/settings.gradle new file mode 100644 index 000000000..32a2f35ac --- /dev/null +++ b/samples/native-config-integration/settings.gradle @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +pluginManagement { + plugins { + id 'org.graalvm.buildtools.native' version getProperty('native.gradle.plugin.version') + } + repositories { + mavenCentral() + gradlePluginPortal() + } +} + +rootProject.name = 'native-config-integration' diff --git a/samples/native-config-integration/src/main/java/org/graalvm/example/Application.java b/samples/native-config-integration/src/main/java/org/graalvm/example/Application.java new file mode 100644 index 000000000..75fee8112 --- /dev/null +++ b/samples/native-config-integration/src/main/java/org/graalvm/example/Application.java @@ -0,0 +1,10 @@ +package org.graalvm.example; + +import org.graalvm.internal.reflect.Greeter; + +public class Application { + public static void main(String[] args) { + Greeter greeter = new Greeter(); + greeter.greet(); + } +} diff --git a/test-support/library-with-reflection/build.gradle.kts b/test-support/library-with-reflection/build.gradle.kts new file mode 100644 index 000000000..0e0ced479 --- /dev/null +++ b/test-support/library-with-reflection/build.gradle.kts @@ -0,0 +1,21 @@ +plugins { + `java-library` + id("org.graalvm.build.publishing") +} + +group = "org.graalvm.internal" +version = "1.5" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) + } +} + +publishing { + publications { + create("maven") { + from(components["java"]) + } + } +} diff --git a/test-support/library-with-reflection/settings.gradle.kts b/test-support/library-with-reflection/settings.gradle.kts new file mode 100644 index 000000000..bd8668d0a --- /dev/null +++ b/test-support/library-with-reflection/settings.gradle.kts @@ -0,0 +1,5 @@ +pluginManagement { + includeBuild("../../build-logic/common-plugins") +} + +rootProject.name = "library-with-reflection" diff --git a/test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Greeter.java b/test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Greeter.java new file mode 100644 index 000000000..72a82ac0a --- /dev/null +++ b/test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Greeter.java @@ -0,0 +1,44 @@ +/* + * Copyright 2003-2021 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.graalvm.internal.reflect; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Optional; + +public class Greeter { + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public void greet() { + System.out.println(Optional.ofNullable(message).orElseGet(() -> { + Method method; + try { + method = Class.forName(System.getProperty("messageClass")).getDeclaredMethod("getDefault"); + return (String) method.invoke(null); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) { + return null; + } + })); + } +} diff --git a/test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Message.java b/test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Message.java new file mode 100644 index 000000000..dcc89ba98 --- /dev/null +++ b/test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Message.java @@ -0,0 +1,22 @@ +/* + * Copyright 2003-2021 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.graalvm.internal.reflect; + +public class Message { + public static String getDefault() { + return "Hello, from reflection!"; + } +} From 5e211f8b2800b05ed2dfd217a0dad452843eda7a Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 2 Mar 2022 14:15:20 +0100 Subject: [PATCH 21/30] Add support for excluded modules and forced versions --- .../NativeConfigRepoFunctionalTest.groovy | 54 +++++++++++++++++++ .../buildtools/gradle/NativeImagePlugin.java | 9 +++- ...ativeConfigurationRepositoryExtension.java | 8 +++ .../org/graalvm/internal/reflect/Greeter.java | 20 ++++--- 4 files changed, 84 insertions(+), 7 deletions(-) diff --git a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy index e384c46b4..92f4f4eee 100644 --- a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy +++ b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy @@ -88,4 +88,58 @@ class NativeConfigRepoFunctionalTest extends AbstractFunctionalTest { 'tar.bz2' | 'tar.bz2 file' } + def "can exclude a dependency from native configuration"() { + given: + withSample("native-config-integration") + + buildFile << """ +graalvmNative { + configurationRepository { + excludedModules.add("org.graalvm.internal:library-with-reflection") + } +} + """ + + when: + run 'nativeRun', "-D${NativeImagePlugin.CONFIG_REPO_LOGLEVEL}=${LogLevel.LIFECYCLE}" + + then: + tasks { + succeeded ':jar', ':nativeCompile', ':nativeRun' + } + + then: + outputContains "Reflection failed" + + and: "doesn't look for a configuration directory for the current version" + outputDoesNotContain "[configuration repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration directory not found. Trying latest version." + } + + def "can force a dependency to a specific config version"() { + given: + withSample("native-config-integration") + + buildFile << """ +graalvmNative { + configurationRepository { + moduleToConfigVersion.put("org.graalvm.internal:library-with-reflection", "2") + } +} + """ + + when: + run 'nativeRun', "-D${NativeImagePlugin.CONFIG_REPO_LOGLEVEL}=${LogLevel.LIFECYCLE}" + + then: + tasks { + succeeded ':jar', ':nativeCompile', ':nativeRun' + } + + then: + outputContains "Reflection failed" + + and: "looks for specific configuration version" + outputContains "[configuration repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration is forced to version 2" + } + } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java index 1dd511d45..518d9481b 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java @@ -307,11 +307,17 @@ private void configureNativeConfigurationDirectories(Project project, GraalVMExt if (repositoryExtension.getUri().isPresent()) { Configuration classpath = project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()); Set excludedModules = repositoryExtension.getExcludedModules().getOrElse(Collections.emptySet()); + Map forcedVersions = repositoryExtension.getModuleToConfigVersion().getOrElse(Collections.emptyMap()); return serviceProvider.map(repo -> repo.findConfigurationDirectoriesFor(query -> classpath.getIncoming().getResolutionResult().allComponents(component -> { ModuleVersionIdentifier moduleVersion = component.getModuleVersion(); String module = moduleVersion.getGroup() + ":" + moduleVersion.getName(); if (!excludedModules.contains(module)) { - query.forArtifact(artifact -> artifact.gav(module + ":" + moduleVersion.getVersion())); + query.forArtifact(artifact -> { + artifact.gav(module + ":" + moduleVersion.getVersion()); + if (forcedVersions.containsKey(module)) { + artifact.forceConfigVersion(forcedVersions.get(module)); + } + }); } query.useLatestConfigWhenVersionIsUntested(); })).stream() @@ -411,6 +417,7 @@ private void configureNativeConfigurationRepo(ExtensionAware graalvmNative) { } })); configurationRepository.getExcludedModules().convention(Collections.emptySet()); + configurationRepository.getModuleToConfigVersion().convention(Collections.emptyMap()); } private TaskProvider registerResourcesConfigTask(Provider generatedDir, diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java index 039fdf38c..dde1340dc 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java @@ -40,6 +40,7 @@ */ package org.graalvm.buildtools.gradle.dsl; +import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Property; import org.gradle.api.provider.SetProperty; @@ -85,6 +86,13 @@ public interface NativeConfigurationRepositoryExtension { */ SetProperty getExcludedModules(); + /** + * A map from a module (org.group:artifact) to configuration + * repository config version. + * @return the map of modules to forced configuration versions + */ + MapProperty getModuleToConfigVersion(); + /** * Convenience method to use a String for the URI * property. diff --git a/test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Greeter.java b/test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Greeter.java index 72a82ac0a..073ae2e5e 100644 --- a/test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Greeter.java +++ b/test-support/library-with-reflection/src/main/java/org/graalvm/internal/reflect/Greeter.java @@ -32,13 +32,21 @@ public void setMessage(String message) { public void greet() { System.out.println(Optional.ofNullable(message).orElseGet(() -> { - Method method; - try { - method = Class.forName(System.getProperty("messageClass")).getDeclaredMethod("getDefault"); - return (String) method.invoke(null); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) { - return null; + String msg = defaultMessage(); + if (msg == null) { + return "Reflection failed"; } + return msg; })); } + + private String defaultMessage() { + Method method; + try { + method = Class.forName(System.getProperty("messageClass")).getDeclaredMethod("getDefault"); + return (String) method.invoke(null); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) { + return null; + } + } } From bac2a24384dfb574cc9f29c09243dc468ce046ad Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 16 Mar 2022 14:01:46 +0100 Subject: [PATCH 22/30] Terminology changes: native configuration -> JVM reachability metadata This commit updates the native configuration project according to the latest approved terminology: we're talking about JVM reachability metadata. The extension is now: ```gradle graalvmNative { jvmReachabilityMetadataRepository { ... } } ``` --- ...ive-config.yml => jvm-metadata-config.yml} | 10 ++++---- .../LICENSE | 0 .../build.gradle.kts | 4 +-- .../gradle/native-image-testing.gradle | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../gradlew | 0 .../gradlew.bat | 0 .../settings.gradle.kts | 2 +- .../JvmReachabilityMetadataRepository.java} | 6 ++--- .../java/org/graalvm/reachability}/Query.java | 2 +- .../internal/DefaultArtifactQuery.java | 4 +-- .../reachability}/internal/DefaultQuery.java | 4 +-- .../internal/FileSystemRepository.java | 14 +++++------ .../internal/UncheckedIOException.java | 2 +- .../internal/index/artifacts/Artifact.java | 2 +- ...duleJsonVersionToConfigDirectoryIndex.java | 4 +-- .../VersionToConfigDirectoryIndex.java | 2 +- ...ileSystemModuleToConfigDirectoryIndex.java | 2 +- .../JsonModuleToConfigDirectoryIndex.java | 4 +-- .../internal/index/modules/ModuleEntry.java | 2 +- .../modules/ModuleToConfigDirectoryIndex.java | 2 +- ...dLocationModuleToConfigDirectoryIndex.java | 2 +- .../internal/FileSystemRepositoryTest.java | 4 +-- ...JsonVersionToConfigDirectoryIndexTest.java | 2 +- ...ystemModuleToConfigDirectoryIndexTest.java | 2 +- .../JsonModuleToConfigDirectoryIndexTest.java | 2 +- ...ationModuleToConfigDirectoryIndexTest.java | 2 +- .../test/resources/json/artifact-1/index.json | 0 .../json/modules/multi-dirs/index.json | 0 .../modules/multi-dirs/jline/placeholder.txt | 0 .../multi-dirs/netty-core/placeholder.txt | 0 .../multi-dirs/org/bar/placeholder.txt | 0 .../json/modules/single-dir/index.json | 0 .../io/netty/netty-core/placeholder.txt | 0 .../modules/single-dir/jline/placeholder.txt | 0 .../single-dir/org/bar/placeholder.txt | 0 .../src/test/resources/repos/repo1/index.json | 0 .../repos/repo1/org/foo/1/reflect-config.json | 0 .../repos/repo1/org/foo/2/reflect-config.json | 0 .../resources/repos/repo1/org/foo/index.json | 0 .../src/test/resources/repos/repo2/index.json | 0 .../repos/repo2/org/foo/1/reflect-config.json | 0 .../repos/repo2/org/foo/2/reflect-config.json | 0 .../resources/repos/repo2/org/foo/index.json | 0 gradle/libs.versions.toml | 2 +- native-gradle-plugin/build.gradle | 2 +- .../NativeConfigRepoFunctionalTest.groovy | 12 ++++----- .../buildtools/gradle/NativeImagePlugin.java | 23 +++++++++--------- ...chabilityMetadataRepositoryExtension.java} | 7 +++--- ...va => JvmReachabilityMetadataService.java} | 20 +++++++-------- .../native-config-integration/build.gradle | 2 +- settings.gradle.kts | 2 +- 53 files changed, 74 insertions(+), 76 deletions(-) rename .github/workflows/{native-config.yml => jvm-metadata-config.yml} (69%) rename common/{native-config => jvm-reachability-metadata}/LICENSE (100%) rename common/{native-config => jvm-reachability-metadata}/build.gradle.kts (94%) rename common/{native-config => jvm-reachability-metadata}/gradle/native-image-testing.gradle (100%) rename common/{native-config => jvm-reachability-metadata}/gradle/wrapper/gradle-wrapper.jar (100%) rename common/{native-config => jvm-reachability-metadata}/gradle/wrapper/gradle-wrapper.properties (100%) rename common/{native-config => jvm-reachability-metadata}/gradlew (100%) rename common/{native-config => jvm-reachability-metadata}/gradlew.bat (100%) rename common/{native-config => jvm-reachability-metadata}/settings.gradle.kts (97%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java => jvm-reachability-metadata/src/main/java/org/graalvm/reachability/JvmReachabilityMetadataRepository.java} (96%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/Query.java (98%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/DefaultArtifactQuery.java (97%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/DefaultQuery.java (97%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/FileSystemRepository.java (93%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/UncheckedIOException.java (98%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/index/artifacts/Artifact.java (98%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java (97%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/index/artifacts/VersionToConfigDirectoryIndex.java (98%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java (98%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/index/modules/JsonModuleToConfigDirectoryIndex.java (97%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/index/modules/ModuleEntry.java (98%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/index/modules/ModuleToConfigDirectoryIndex.java (97%) rename common/{native-config/src/main/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/main/java/org/graalvm/reachability}/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java (97%) rename common/{native-config/src/test/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/test/java/org/graalvm/reachability}/internal/FileSystemRepositoryTest.java (98%) rename common/{native-config/src/test/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/test/java/org/graalvm/reachability}/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java (98%) rename common/{native-config/src/test/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/test/java/org/graalvm/reachability}/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java (98%) rename common/{native-config/src/test/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/test/java/org/graalvm/reachability}/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java (98%) rename common/{native-config/src/test/java/org/graalvm/nativeconfig => jvm-reachability-metadata/src/test/java/org/graalvm/reachability}/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java (98%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/json/artifact-1/index.json (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/json/modules/multi-dirs/index.json (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/json/modules/multi-dirs/jline/placeholder.txt (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/json/modules/multi-dirs/netty-core/placeholder.txt (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/json/modules/multi-dirs/org/bar/placeholder.txt (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/json/modules/single-dir/index.json (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/json/modules/single-dir/io/netty/netty-core/placeholder.txt (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/json/modules/single-dir/jline/placeholder.txt (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/json/modules/single-dir/org/bar/placeholder.txt (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/repos/repo1/index.json (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/repos/repo1/org/foo/1/reflect-config.json (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/repos/repo1/org/foo/2/reflect-config.json (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/repos/repo1/org/foo/index.json (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/repos/repo2/index.json (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/repos/repo2/org/foo/1/reflect-config.json (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/repos/repo2/org/foo/2/reflect-config.json (100%) rename common/{native-config => jvm-reachability-metadata}/src/test/resources/repos/repo2/org/foo/index.json (100%) rename native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/{NativeConfigurationRepositoryExtension.java => JvmReachabilityMetadataRepositoryExtension.java} (94%) rename native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/{NativeConfigurationService.java => JvmReachabilityMetadataService.java} (90%) diff --git a/.github/workflows/native-config.yml b/.github/workflows/jvm-metadata-config.yml similarity index 69% rename from .github/workflows/native-config.yml rename to .github/workflows/jvm-metadata-config.yml index 9feb2f079..062109185 100644 --- a/.github/workflows/native-config.yml +++ b/.github/workflows/jvm-metadata-config.yml @@ -3,10 +3,10 @@ name: Native Configuration Repository on: push: paths: - - 'common/native-config/**' + - 'common/jvm-reachability-metadata/**' pull_request: paths: - - 'common/native-config/**' + - 'common/jvm-reachability-metadata/**' workflow_dispatch: jobs: @@ -26,12 +26,12 @@ jobs: echo "JAVA_HOME=$JAVA_HOME" >> $GITHUB_ENV echo "GRAALVM_HOME=$GRAALVM_HOME" >> $GITHUB_ENV - name: Checkstyle - run: ./gradlew :native-config:checkstyleMain :native-config:checkstyleTest + run: ./gradlew :jvm-reachability-metadata:checkstyleMain :jvm-reachability-metadata:checkstyleTest - name: JVM test - run: ./gradlew :native-config:test + run: ./gradlew :jvm-reachability-metadata:test - name: Tests results if: always() uses: actions/upload-artifact@v2 with: name: tests-results - path: common/native-config/build/reports/tests/ + path: common/jvm-reachability-metadata/build/reports/tests/ diff --git a/common/native-config/LICENSE b/common/jvm-reachability-metadata/LICENSE similarity index 100% rename from common/native-config/LICENSE rename to common/jvm-reachability-metadata/LICENSE diff --git a/common/native-config/build.gradle.kts b/common/jvm-reachability-metadata/build.gradle.kts similarity index 94% rename from common/native-config/build.gradle.kts rename to common/jvm-reachability-metadata/build.gradle.kts index bf363f36e..432b4210c 100644 --- a/common/native-config/build.gradle.kts +++ b/common/jvm-reachability-metadata/build.gradle.kts @@ -46,8 +46,8 @@ plugins { } maven { - name.set("GraalVM Native Configuration support") - description.set("A library to help dealing with the GraaVM native configuration repository") + name.set("GraalVM JVM Reachability Metadata support") + description.set("A library to help dealing with the GraaVM JVM Reachability Metadata repository") } dependencies { diff --git a/common/native-config/gradle/native-image-testing.gradle b/common/jvm-reachability-metadata/gradle/native-image-testing.gradle similarity index 100% rename from common/native-config/gradle/native-image-testing.gradle rename to common/jvm-reachability-metadata/gradle/native-image-testing.gradle diff --git a/common/native-config/gradle/wrapper/gradle-wrapper.jar b/common/jvm-reachability-metadata/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from common/native-config/gradle/wrapper/gradle-wrapper.jar rename to common/jvm-reachability-metadata/gradle/wrapper/gradle-wrapper.jar diff --git a/common/native-config/gradle/wrapper/gradle-wrapper.properties b/common/jvm-reachability-metadata/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from common/native-config/gradle/wrapper/gradle-wrapper.properties rename to common/jvm-reachability-metadata/gradle/wrapper/gradle-wrapper.properties diff --git a/common/native-config/gradlew b/common/jvm-reachability-metadata/gradlew similarity index 100% rename from common/native-config/gradlew rename to common/jvm-reachability-metadata/gradlew diff --git a/common/native-config/gradlew.bat b/common/jvm-reachability-metadata/gradlew.bat similarity index 100% rename from common/native-config/gradlew.bat rename to common/jvm-reachability-metadata/gradlew.bat diff --git a/common/native-config/settings.gradle.kts b/common/jvm-reachability-metadata/settings.gradle.kts similarity index 97% rename from common/native-config/settings.gradle.kts rename to common/jvm-reachability-metadata/settings.gradle.kts index 79d87f443..39c0f4fe5 100644 --- a/common/native-config/settings.gradle.kts +++ b/common/jvm-reachability-metadata/settings.gradle.kts @@ -48,4 +48,4 @@ plugins { id("org.graalvm.build.common") } -rootProject.name = "native-config" +rootProject.name = "jvm-reachability-metadata" diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/JvmReachabilityMetadataRepository.java similarity index 96% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/JvmReachabilityMetadataRepository.java index 0eb980a47..6d10e91ea 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/NativeConfigurationRepository.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/JvmReachabilityMetadataRepository.java @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig; +package org.graalvm.reachability; import java.nio.file.Path; import java.util.Collection; @@ -46,7 +46,7 @@ import java.util.function.Consumer; /** - * Interface for accessing a native configuration repository. + * Interface for accessing a reachability metadata repository. * The goal of this repository is to answer questions like: * "give me the configuration files for this artifact", where * an artifact is represented by its GAV coordinates. @@ -55,7 +55,7 @@ * and provide overrides for cases where configuration files * are missing. */ -public interface NativeConfigurationRepository { +public interface JvmReachabilityMetadataRepository { /** * Performs a generic query on the repository, returning a list of * configuration directories. The query may be parameterized with diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/Query.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/Query.java similarity index 98% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/Query.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/Query.java index 4cb26041f..17232d684 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/Query.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/Query.java @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig; +package org.graalvm.reachability; import java.util.Collection; import java.util.function.Consumer; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultArtifactQuery.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/DefaultArtifactQuery.java similarity index 97% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultArtifactQuery.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/DefaultArtifactQuery.java index 24798918d..2af118e70 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultArtifactQuery.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/DefaultArtifactQuery.java @@ -38,9 +38,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal; +package org.graalvm.reachability.internal; -import org.graalvm.nativeconfig.Query; +import org.graalvm.reachability.Query; import java.util.Optional; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultQuery.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/DefaultQuery.java similarity index 97% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultQuery.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/DefaultQuery.java index e8b0cab13..cb4fad4fb 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/DefaultQuery.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/DefaultQuery.java @@ -38,9 +38,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal; +package org.graalvm.reachability.internal; -import org.graalvm.nativeconfig.Query; +import org.graalvm.reachability.Query; import java.util.ArrayList; import java.util.List; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/FileSystemRepository.java similarity index 93% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/FileSystemRepository.java index a6cdf7aee..e848e70fd 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/FileSystemRepository.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/FileSystemRepository.java @@ -38,13 +38,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal; +package org.graalvm.reachability.internal; -import org.graalvm.nativeconfig.NativeConfigurationRepository; -import org.graalvm.nativeconfig.Query; -import org.graalvm.nativeconfig.internal.index.artifacts.SingleModuleJsonVersionToConfigDirectoryIndex; -import org.graalvm.nativeconfig.internal.index.artifacts.VersionToConfigDirectoryIndex; -import org.graalvm.nativeconfig.internal.index.modules.FileSystemModuleToConfigDirectoryIndex; +import org.graalvm.reachability.JvmReachabilityMetadataRepository; +import org.graalvm.reachability.Query; +import org.graalvm.reachability.internal.index.artifacts.SingleModuleJsonVersionToConfigDirectoryIndex; +import org.graalvm.reachability.internal.index.artifacts.VersionToConfigDirectoryIndex; +import org.graalvm.reachability.internal.index.modules.FileSystemModuleToConfigDirectoryIndex; import java.nio.file.Path; import java.util.Map; @@ -55,7 +55,7 @@ import java.util.function.Supplier; import java.util.stream.Collectors; -public class FileSystemRepository implements NativeConfigurationRepository { +public class FileSystemRepository implements JvmReachabilityMetadataRepository { private final FileSystemModuleToConfigDirectoryIndex moduleIndex; private final Logger logger; private final Map artifactIndexes; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/UncheckedIOException.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/UncheckedIOException.java similarity index 98% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/UncheckedIOException.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/UncheckedIOException.java index 6a56bca52..021bccc0a 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/UncheckedIOException.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/UncheckedIOException.java @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal; +package org.graalvm.reachability.internal; import java.io.IOException; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java similarity index 98% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java index fc9b40c4d..d38681748 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/Artifact.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.artifacts; +package org.graalvm.reachability.internal.index.artifacts; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java similarity index 97% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java index 5b864f34c..25709d50c 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java @@ -38,11 +38,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.artifacts; +package org.graalvm.reachability.internal.index.artifacts; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; -import org.graalvm.nativeconfig.internal.UncheckedIOException; +import org.graalvm.reachability.internal.UncheckedIOException; import java.io.BufferedReader; import java.io.IOException; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/VersionToConfigDirectoryIndex.java similarity index 98% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/VersionToConfigDirectoryIndex.java index 8f6b8ce80..3a712265d 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/artifacts/VersionToConfigDirectoryIndex.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/VersionToConfigDirectoryIndex.java @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.artifacts; +package org.graalvm.reachability.internal.index.artifacts; import java.nio.file.Path; import java.util.Optional; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java similarity index 98% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java index c2233453b..78d6a8604 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/FileSystemModuleToConfigDirectoryIndex.java @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.modules; +package org.graalvm.reachability.internal.index.modules; import java.nio.file.Path; import java.util.Set; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndex.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/JsonModuleToConfigDirectoryIndex.java similarity index 97% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndex.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/JsonModuleToConfigDirectoryIndex.java index fa72ad7ba..c072de033 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndex.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/JsonModuleToConfigDirectoryIndex.java @@ -38,11 +38,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.modules; +package org.graalvm.reachability.internal.index.modules; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; -import org.graalvm.nativeconfig.internal.UncheckedIOException; +import org.graalvm.reachability.internal.UncheckedIOException; import java.io.BufferedReader; import java.io.IOException; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/ModuleEntry.java similarity index 98% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/ModuleEntry.java index a35d0497b..7093eae97 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleEntry.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/ModuleEntry.java @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.modules; +package org.graalvm.reachability.internal.index.modules; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleToConfigDirectoryIndex.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/ModuleToConfigDirectoryIndex.java similarity index 97% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleToConfigDirectoryIndex.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/ModuleToConfigDirectoryIndex.java index 057d4d5a1..ab4dce7b4 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/ModuleToConfigDirectoryIndex.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/ModuleToConfigDirectoryIndex.java @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.modules; +package org.graalvm.reachability.internal.index.modules; import java.nio.file.Path; import java.util.Set; diff --git a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java similarity index 97% rename from common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java rename to common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java index c43aa59e0..d8d8a82a0 100644 --- a/common/native-config/src/main/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/modules/StandardLocationModuleToConfigDirectoryIndex.java @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.modules; +package org.graalvm.reachability.internal.index.modules; import java.nio.file.Files; import java.nio.file.Path; diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java b/common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/FileSystemRepositoryTest.java similarity index 98% rename from common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java rename to common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/FileSystemRepositoryTest.java index 5c9cebcf4..60ac40d20 100644 --- a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/FileSystemRepositoryTest.java +++ b/common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/FileSystemRepositoryTest.java @@ -39,9 +39,9 @@ * SOFTWARE. */ -package org.graalvm.nativeconfig.internal; +package org.graalvm.reachability.internal; -import org.graalvm.nativeconfig.Query; +import org.graalvm.reachability.Query; import org.junit.jupiter.api.Test; import java.io.File; diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java b/common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java similarity index 98% rename from common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java rename to common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java index 8d5cb1ce9..38f806e21 100644 --- a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java +++ b/common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java @@ -39,7 +39,7 @@ * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.artifacts; +package org.graalvm.reachability.internal.index.artifacts; import org.junit.jupiter.api.Test; diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java b/common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java similarity index 98% rename from common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java rename to common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java index 80a57813a..11102b826 100644 --- a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java +++ b/common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/modules/FileSystemModuleToConfigDirectoryIndexTest.java @@ -39,7 +39,7 @@ * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.modules; +package org.graalvm.reachability.internal.index.modules; import org.junit.jupiter.api.Test; diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java b/common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java similarity index 98% rename from common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java rename to common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java index 0ae9033b2..eca5987d8 100644 --- a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java +++ b/common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/modules/JsonModuleToConfigDirectoryIndexTest.java @@ -39,7 +39,7 @@ * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.modules; +package org.graalvm.reachability.internal.index.modules; import org.junit.jupiter.api.Test; diff --git a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java b/common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java similarity index 98% rename from common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java rename to common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java index 189607e59..8b866066c 100644 --- a/common/native-config/src/test/java/org/graalvm/nativeconfig/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java +++ b/common/jvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/modules/StandardLocationModuleToConfigDirectoryIndexTest.java @@ -39,7 +39,7 @@ * SOFTWARE. */ -package org.graalvm.nativeconfig.internal.index.modules; +package org.graalvm.reachability.internal.index.modules; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/common/native-config/src/test/resources/json/artifact-1/index.json b/common/jvm-reachability-metadata/src/test/resources/json/artifact-1/index.json similarity index 100% rename from common/native-config/src/test/resources/json/artifact-1/index.json rename to common/jvm-reachability-metadata/src/test/resources/json/artifact-1/index.json diff --git a/common/native-config/src/test/resources/json/modules/multi-dirs/index.json b/common/jvm-reachability-metadata/src/test/resources/json/modules/multi-dirs/index.json similarity index 100% rename from common/native-config/src/test/resources/json/modules/multi-dirs/index.json rename to common/jvm-reachability-metadata/src/test/resources/json/modules/multi-dirs/index.json diff --git a/common/native-config/src/test/resources/json/modules/multi-dirs/jline/placeholder.txt b/common/jvm-reachability-metadata/src/test/resources/json/modules/multi-dirs/jline/placeholder.txt similarity index 100% rename from common/native-config/src/test/resources/json/modules/multi-dirs/jline/placeholder.txt rename to common/jvm-reachability-metadata/src/test/resources/json/modules/multi-dirs/jline/placeholder.txt diff --git a/common/native-config/src/test/resources/json/modules/multi-dirs/netty-core/placeholder.txt b/common/jvm-reachability-metadata/src/test/resources/json/modules/multi-dirs/netty-core/placeholder.txt similarity index 100% rename from common/native-config/src/test/resources/json/modules/multi-dirs/netty-core/placeholder.txt rename to common/jvm-reachability-metadata/src/test/resources/json/modules/multi-dirs/netty-core/placeholder.txt diff --git a/common/native-config/src/test/resources/json/modules/multi-dirs/org/bar/placeholder.txt b/common/jvm-reachability-metadata/src/test/resources/json/modules/multi-dirs/org/bar/placeholder.txt similarity index 100% rename from common/native-config/src/test/resources/json/modules/multi-dirs/org/bar/placeholder.txt rename to common/jvm-reachability-metadata/src/test/resources/json/modules/multi-dirs/org/bar/placeholder.txt diff --git a/common/native-config/src/test/resources/json/modules/single-dir/index.json b/common/jvm-reachability-metadata/src/test/resources/json/modules/single-dir/index.json similarity index 100% rename from common/native-config/src/test/resources/json/modules/single-dir/index.json rename to common/jvm-reachability-metadata/src/test/resources/json/modules/single-dir/index.json diff --git a/common/native-config/src/test/resources/json/modules/single-dir/io/netty/netty-core/placeholder.txt b/common/jvm-reachability-metadata/src/test/resources/json/modules/single-dir/io/netty/netty-core/placeholder.txt similarity index 100% rename from common/native-config/src/test/resources/json/modules/single-dir/io/netty/netty-core/placeholder.txt rename to common/jvm-reachability-metadata/src/test/resources/json/modules/single-dir/io/netty/netty-core/placeholder.txt diff --git a/common/native-config/src/test/resources/json/modules/single-dir/jline/placeholder.txt b/common/jvm-reachability-metadata/src/test/resources/json/modules/single-dir/jline/placeholder.txt similarity index 100% rename from common/native-config/src/test/resources/json/modules/single-dir/jline/placeholder.txt rename to common/jvm-reachability-metadata/src/test/resources/json/modules/single-dir/jline/placeholder.txt diff --git a/common/native-config/src/test/resources/json/modules/single-dir/org/bar/placeholder.txt b/common/jvm-reachability-metadata/src/test/resources/json/modules/single-dir/org/bar/placeholder.txt similarity index 100% rename from common/native-config/src/test/resources/json/modules/single-dir/org/bar/placeholder.txt rename to common/jvm-reachability-metadata/src/test/resources/json/modules/single-dir/org/bar/placeholder.txt diff --git a/common/native-config/src/test/resources/repos/repo1/index.json b/common/jvm-reachability-metadata/src/test/resources/repos/repo1/index.json similarity index 100% rename from common/native-config/src/test/resources/repos/repo1/index.json rename to common/jvm-reachability-metadata/src/test/resources/repos/repo1/index.json diff --git a/common/native-config/src/test/resources/repos/repo1/org/foo/1/reflect-config.json b/common/jvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/1/reflect-config.json similarity index 100% rename from common/native-config/src/test/resources/repos/repo1/org/foo/1/reflect-config.json rename to common/jvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/1/reflect-config.json diff --git a/common/native-config/src/test/resources/repos/repo1/org/foo/2/reflect-config.json b/common/jvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/2/reflect-config.json similarity index 100% rename from common/native-config/src/test/resources/repos/repo1/org/foo/2/reflect-config.json rename to common/jvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/2/reflect-config.json diff --git a/common/native-config/src/test/resources/repos/repo1/org/foo/index.json b/common/jvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/index.json similarity index 100% rename from common/native-config/src/test/resources/repos/repo1/org/foo/index.json rename to common/jvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/index.json diff --git a/common/native-config/src/test/resources/repos/repo2/index.json b/common/jvm-reachability-metadata/src/test/resources/repos/repo2/index.json similarity index 100% rename from common/native-config/src/test/resources/repos/repo2/index.json rename to common/jvm-reachability-metadata/src/test/resources/repos/repo2/index.json diff --git a/common/native-config/src/test/resources/repos/repo2/org/foo/1/reflect-config.json b/common/jvm-reachability-metadata/src/test/resources/repos/repo2/org/foo/1/reflect-config.json similarity index 100% rename from common/native-config/src/test/resources/repos/repo2/org/foo/1/reflect-config.json rename to common/jvm-reachability-metadata/src/test/resources/repos/repo2/org/foo/1/reflect-config.json diff --git a/common/native-config/src/test/resources/repos/repo2/org/foo/2/reflect-config.json b/common/jvm-reachability-metadata/src/test/resources/repos/repo2/org/foo/2/reflect-config.json similarity index 100% rename from common/native-config/src/test/resources/repos/repo2/org/foo/2/reflect-config.json rename to common/jvm-reachability-metadata/src/test/resources/repos/repo2/org/foo/2/reflect-config.json diff --git a/common/native-config/src/test/resources/repos/repo2/org/foo/index.json b/common/jvm-reachability-metadata/src/test/resources/repos/repo2/org/foo/index.json similarity index 100% rename from common/native-config/src/test/resources/repos/repo2/org/foo/index.json rename to common/jvm-reachability-metadata/src/test/resources/repos/repo2/org/foo/index.json diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 22a25771b..7eb567c6c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,7 +23,7 @@ nativeGradlePlugin = { module = "org.graalvm.buildtools:native-gradle-plugin", v nativeMavenPlugin = { module = "org.graalvm.buildtools:native-maven-plugin", version.ref = "nativeBuildTools" } junitPlatformNative = { module = "org.graalvm.buildtools:junit-platform-native", version.ref = "nativeBuildTools" } utils = { module = "org.graalvm.buildtools:utils", version.ref = "nativeBuildTools" } -nativeConfig = { module = "org.graalvm.buildtools:native-config", version.ref = "nativeBuildTools" } +jvmReachabilityMetadata = { module = "org.graalvm.buildtools:jvm-reachability-metadata", version.ref = "nativeBuildTools" } # External dependencies test-junit-platform-console = { module = "org.junit.platform:junit-platform-console", version.ref = "junitPlatform" } diff --git a/native-gradle-plugin/build.gradle b/native-gradle-plugin/build.gradle index 81bf14c89..fd6bbde0e 100644 --- a/native-gradle-plugin/build.gradle +++ b/native-gradle-plugin/build.gradle @@ -56,7 +56,7 @@ maven { dependencies { implementation libs.utils - implementation libs.nativeConfig + implementation libs.jvmReachabilityMetadata testImplementation libs.test.spock testFixturesImplementation libs.test.spock testFixturesImplementation gradleTestKit() diff --git a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy index 92f4f4eee..3a6f1bd26 100644 --- a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy +++ b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy @@ -75,10 +75,10 @@ class NativeConfigRepoFunctionalTest extends AbstractFunctionalTest { outputContains "Hello, from reflection!" and: "doesn't find a configuration directory for the current version" - outputContains "[configuration repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration directory not found. Trying latest version." + outputContains "[jvm reachability metadata repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration directory not found. Trying latest version." and: "but finds one thanks to the latest configuration field" - outputContains "[configuration repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration directory is org/graalvm/internal/library-with-reflection/1" + outputContains "[jvm reachability metadata repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration directory is org/graalvm/internal/library-with-reflection/1" where: format | label @@ -94,7 +94,7 @@ class NativeConfigRepoFunctionalTest extends AbstractFunctionalTest { buildFile << """ graalvmNative { - configurationRepository { + jvmReachabilityMetadataRepository { excludedModules.add("org.graalvm.internal:library-with-reflection") } } @@ -112,7 +112,7 @@ graalvmNative { outputContains "Reflection failed" and: "doesn't look for a configuration directory for the current version" - outputDoesNotContain "[configuration repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration directory not found. Trying latest version." + outputDoesNotContain "[jvm reachability metadata repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration directory not found. Trying latest version." } def "can force a dependency to a specific config version"() { @@ -121,7 +121,7 @@ graalvmNative { buildFile << """ graalvmNative { - configurationRepository { + jvmReachabilityMetadataRepository { moduleToConfigVersion.put("org.graalvm.internal:library-with-reflection", "2") } } @@ -139,7 +139,7 @@ graalvmNative { outputContains "Reflection failed" and: "looks for specific configuration version" - outputContains "[configuration repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration is forced to version 2" + outputContains "[jvm reachability metadata repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration is forced to version 2" } } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java index 518d9481b..a0c0c061f 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java @@ -44,7 +44,7 @@ import org.graalvm.buildtools.VersionInfo; import org.graalvm.buildtools.gradle.dsl.AgentConfiguration; import org.graalvm.buildtools.gradle.dsl.GraalVMExtension; -import org.graalvm.buildtools.gradle.dsl.NativeConfigurationRepositoryExtension; +import org.graalvm.buildtools.gradle.dsl.JvmReachabilityMetadataRepositoryExtension; import org.graalvm.buildtools.gradle.dsl.NativeImageOptions; import org.graalvm.buildtools.gradle.internal.AgentCommandLineProvider; import org.graalvm.buildtools.gradle.internal.BaseNativeImageOptions; @@ -53,7 +53,7 @@ import org.graalvm.buildtools.gradle.internal.DeprecatedNativeImageOptions; import org.graalvm.buildtools.gradle.internal.GraalVMLogger; import org.graalvm.buildtools.gradle.internal.GradleUtils; -import org.graalvm.buildtools.gradle.internal.NativeConfigurationService; +import org.graalvm.buildtools.gradle.internal.JvmReachabilityMetadataService; import org.graalvm.buildtools.gradle.internal.NativeConfigurations; import org.graalvm.buildtools.gradle.internal.ProcessGeneratedGraalResourceFiles; import org.graalvm.buildtools.gradle.tasks.BuildNativeImageTask; @@ -288,15 +288,15 @@ private void configureAutomaticTaskCreation(Project project, options.getConfigurationFileDirectories().from(generateResourcesConfig.map(t -> t.getOutputFile().map(f -> f.getAsFile().getParentFile()) )); - configureNativeConfigurationDirectories(project, graalExtension, options, sourceSet); + configureJvmReachabilityConfigurationDirectories(project, graalExtension, options, sourceSet); }); } - private void configureNativeConfigurationDirectories(Project project, GraalVMExtension graalExtension, NativeImageOptions options, SourceSet sourceSet) { - NativeConfigurationRepositoryExtension repositoryExtension = nativeConfiguration(graalExtension); - Provider serviceProvider = project.getGradle() + private void configureJvmReachabilityConfigurationDirectories(Project project, GraalVMExtension graalExtension, NativeImageOptions options, SourceSet sourceSet) { + JvmReachabilityMetadataRepositoryExtension repositoryExtension = reachabilityExtensionOn(graalExtension); + Provider serviceProvider = project.getGradle() .getSharedServices() - .registerIfAbsent("nativeConfigurationService", NativeConfigurationService.class, spec -> { + .registerIfAbsent("nativeConfigurationService", JvmReachabilityMetadataService.class, spec -> { LogLevel logLevel = determineLogLevel(); spec.getParameters().getLogLevel().set(logLevel); spec.getParameters().getUri().set(repositoryExtension.getUri()); @@ -339,8 +339,8 @@ private static LogLevel determineLogLevel() { return logLevel; } - private static NativeConfigurationRepositoryExtension nativeConfiguration(GraalVMExtension graalExtension) { - return ((ExtensionAware) graalExtension).getExtensions().getByType(NativeConfigurationRepositoryExtension.class); + private static JvmReachabilityMetadataRepositoryExtension reachabilityExtensionOn(GraalVMExtension graalExtension) { + return ((ExtensionAware) graalExtension).getExtensions().getByType(JvmReachabilityMetadataRepositoryExtension.class); } private void deprecateExtension(Project project, @@ -406,12 +406,11 @@ private GraalVMExtension registerGraalVMExtension(Project project) { } private void configureNativeConfigurationRepo(ExtensionAware graalvmNative) { - NativeConfigurationRepositoryExtension configurationRepository = graalvmNative.getExtensions().create("configurationRepository", NativeConfigurationRepositoryExtension.class); + JvmReachabilityMetadataRepositoryExtension configurationRepository = graalvmNative.getExtensions().create("jvmReachabilityMetadataRepository", JvmReachabilityMetadataRepositoryExtension.class); configurationRepository.getEnabled().convention(false); configurationRepository.getUri().convention(configurationRepository.getVersion().map(v -> { try { - // TODO: replace with real URI - return new URI("https://github.com/graalvm/native-configuration/releases/download/" + v + "/native-configuration-" + v + ".zip"); + return new URI("https://github.com/graalvm/jvm-reachability-metadata/releases/download/" + v + "/jvm-reachability-metadata-" + v + ".zip"); } catch (URISyntaxException e) { return null; } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/JvmReachabilityMetadataRepositoryExtension.java similarity index 94% rename from native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java rename to native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/JvmReachabilityMetadataRepositoryExtension.java index dde1340dc..181b693fc 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeConfigurationRepositoryExtension.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/JvmReachabilityMetadataRepositoryExtension.java @@ -49,10 +49,9 @@ import java.net.URISyntaxException; /** - * Extension used to configure the native configuration - * repository. + * Extension used to configure the JVM reachability metadata repository. */ -public interface NativeConfigurationRepositoryExtension { +public interface JvmReachabilityMetadataRepositoryExtension { /** * Property used to determine if the native configuration * repository should be used. @@ -61,7 +60,7 @@ public interface NativeConfigurationRepositoryExtension { Property getEnabled(); /** - * A URI pointing to a configuration repository. This must + * A URI pointing to a jvm reachability metadata repository. This must * either be a local file or a remote URI. In case of remote * files, only zip or tarballs are supported. * @return the uri property diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/JvmReachabilityMetadataService.java similarity index 90% rename from native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java rename to native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/JvmReachabilityMetadataService.java index cd3e550e9..0e1997825 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeConfigurationService.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/JvmReachabilityMetadataService.java @@ -40,9 +40,9 @@ */ package org.graalvm.buildtools.gradle.internal; -import org.graalvm.nativeconfig.NativeConfigurationRepository; -import org.graalvm.nativeconfig.Query; -import org.graalvm.nativeconfig.internal.FileSystemRepository; +import org.graalvm.reachability.JvmReachabilityMetadataRepository; +import org.graalvm.reachability.Query; +import org.graalvm.reachability.internal.FileSystemRepository; import org.gradle.api.file.ArchiveOperations; import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.FileSystemOperations; @@ -72,10 +72,10 @@ import java.util.function.Consumer; import java.util.function.Supplier; -public abstract class NativeConfigurationService implements BuildService, NativeConfigurationRepository { - private static final Logger LOGGER = Logging.getLogger(NativeConfigurationService.class); +public abstract class JvmReachabilityMetadataService implements BuildService, JvmReachabilityMetadataRepository { + private static final Logger LOGGER = Logging.getLogger(JvmReachabilityMetadataService.class); - private final NativeConfigurationRepository repository; + private final JvmReachabilityMetadataRepository repository; @Inject protected abstract ArchiveOperations getArchiveOperations(); @@ -91,7 +91,7 @@ public interface Params extends BuildServiceParameters { DirectoryProperty getCacheDir(); } - public NativeConfigurationService() throws URISyntaxException { + public JvmReachabilityMetadataService() throws URISyntaxException { URI uri = getParameters().getUri().get(); this.repository = newRepository(uri); } @@ -111,7 +111,7 @@ private static String hashFor(URI uri) { } } - private NativeConfigurationRepository newRepository(URI uri) throws URISyntaxException { + private JvmReachabilityMetadataRepository newRepository(URI uri) throws URISyntaxException { String cacheKey = hashFor(uri); String path = uri.getPath(); LogLevel logLevel = getParameters().getLogLevel().get(); @@ -167,11 +167,11 @@ private FileSystemRepository newRepositoryFromDirectory(Path path, LogLevel logL return new FileSystemRepository(path, new FileSystemRepository.Logger() { @Override public void log(String groupId, String artifactId, String version, Supplier message) { - LOGGER.log(logLevel, "[configuration repository for {}:{}:{}]: {}", groupId, artifactId, version, message.get()); + LOGGER.log(logLevel, "[jvm reachability metadata repository for {}:{}:{}]: {}", groupId, artifactId, version, message.get()); } }); } else { - throw new IllegalArgumentException("Native configuration repository URI must point to a directory"); + throw new IllegalArgumentException("JVM reachability metadata repository URI must point to a directory"); } } diff --git a/samples/native-config-integration/build.gradle b/samples/native-config-integration/build.gradle index 13560620d..ae713869b 100644 --- a/samples/native-config-integration/build.gradle +++ b/samples/native-config-integration/build.gradle @@ -68,7 +68,7 @@ tasks.withType(Test).configureEach { } graalvmNative { - configurationRepository { + jvmReachabilityMetadataRepository { enabled = true def extension = System.getProperty("extension", '') def repo = file("config-directory${extension ? '.' + extension : ''}") diff --git a/settings.gradle.kts b/settings.gradle.kts index bee7f3039..4edd83d39 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -48,7 +48,7 @@ rootProject.name = "native-build-tools" includeBuild("common/junit-platform-native") includeBuild("common/utils") -includeBuild("common/native-config") +includeBuild("common/jvm-reachability-metadata") includeBuild("native-gradle-plugin") includeBuild("native-maven-plugin") includeBuild("docs") From f4bb059fc59b4f0c34fecca781cd91bd4034849b Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 16 Mar 2022 15:35:37 +0100 Subject: [PATCH 23/30] Rename `config-directory` to `metadata-version` --- .github/workflows/jvm-metadata-config.yml | 4 ++-- .../reachability/internal/index/artifacts/Artifact.java | 2 +- .../src/test/resources/json/artifact-1/index.json | 6 +++--- .../src/test/resources/repos/repo1/org/foo/index.json | 4 ++-- .../src/test/resources/repos/repo2/org/foo/index.json | 6 +++--- .../org/graalvm/internal/library-with-reflection/index.json | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/jvm-metadata-config.yml b/.github/workflows/jvm-metadata-config.yml index 062109185..8df508868 100644 --- a/.github/workflows/jvm-metadata-config.yml +++ b/.github/workflows/jvm-metadata-config.yml @@ -1,4 +1,4 @@ -name: Native Configuration Repository +name: JVM Reachability Metadata Repository on: push: @@ -10,7 +10,7 @@ on: workflow_dispatch: jobs: - test-native-config: + test-jvm-reachability-metadata: name: runs-on: ubuntu-18.04 strategy: diff --git a/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java index d38681748..3641a67a7 100644 --- a/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java +++ b/common/jvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java @@ -56,7 +56,7 @@ public class Artifact { @JsonCreator public Artifact(@JsonProperty("module") String module, @JsonProperty("tested-versions") Set versions, - @JsonProperty("config-version") String directory, + @JsonProperty("metadata-version") String directory, @JsonProperty(value = "latest", defaultValue = "false") boolean latest) { this.module = module; this.versions = versions; diff --git a/common/jvm-reachability-metadata/src/test/resources/json/artifact-1/index.json b/common/jvm-reachability-metadata/src/test/resources/json/artifact-1/index.json index 0dca61c23..ad650cfc3 100644 --- a/common/jvm-reachability-metadata/src/test/resources/json/artifact-1/index.json +++ b/common/jvm-reachability-metadata/src/test/resources/json/artifact-1/index.json @@ -1,5 +1,5 @@ [ - { "module": "com.foo:bar", "tested-versions": ["1.0", "1.1", "1.2", "1.3"], "config-version": "1" }, - { "module": "com.foo:bar", "tested-versions": ["2.0", "2.1"], "config-version": "2", "latest": true }, - { "module": "com.foo:bar-all", "tested-versions": ["2.0", "2.1"], "config-version": "2" } + { "module": "com.foo:bar", "tested-versions": ["1.0", "1.1", "1.2", "1.3"], "metadata-version": "1" }, + { "module": "com.foo:bar", "tested-versions": ["2.0", "2.1"], "metadata-version": "2", "latest": true }, + { "module": "com.foo:bar-all", "tested-versions": ["2.0", "2.1"], "metadata-version": "2" } ] diff --git a/common/jvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/index.json b/common/jvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/index.json index ffd7c5bcb..cef1cc778 100644 --- a/common/jvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/index.json +++ b/common/jvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/index.json @@ -4,14 +4,14 @@ "tested-versions": [ "1.0" ], - "config-version": "1" + "metadata-version": "1" }, { "module": "org:foo", "tested-versions": [ "1.1" ], - "config-version": "2", + "metadata-version": "2", "latest": true } ] diff --git a/common/jvm-reachability-metadata/src/test/resources/repos/repo2/org/foo/index.json b/common/jvm-reachability-metadata/src/test/resources/repos/repo2/org/foo/index.json index 6a6e12db7..82b6277d0 100644 --- a/common/jvm-reachability-metadata/src/test/resources/repos/repo2/org/foo/index.json +++ b/common/jvm-reachability-metadata/src/test/resources/repos/repo2/org/foo/index.json @@ -1,5 +1,5 @@ [ - { "module": "org:foo", "tested-versions": ["1.0"], "config-version": "1" }, - { "module": "org:foo", "tested-versions": ["1.1"], "config-version": "2" }, - { "module": "org:bar", "tested-versions": ["2.1"], "config-version": "2" } + { "module": "org:foo", "tested-versions": ["1.0"], "metadata-version": "1" }, + { "module": "org:foo", "tested-versions": ["1.1"], "metadata-version": "2" }, + { "module": "org:bar", "tested-versions": ["2.1"], "metadata-version": "2" } ] diff --git a/samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/index.json b/samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/index.json index cb1bc5060..0e78c26de 100644 --- a/samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/index.json +++ b/samples/native-config-integration/config-directory/org/graalvm/internal/library-with-reflection/index.json @@ -7,7 +7,7 @@ "1.2", "1.3" ], - "config-version": "1", + "metadata-version": "1", "latest": true } ] From b0f2e13d8379d51a1fde1369e1e8e529f4fb10e1 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Fri, 18 Mar 2022 17:03:36 +0100 Subject: [PATCH 24/30] Escape spaces in file names when using @argfiles --- .../org/graalvm/buildtools/utils/NativeImageUtils.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java b/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java index d2a83c588..1d3ceba01 100644 --- a/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java +++ b/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java @@ -48,6 +48,7 @@ import java.nio.file.StandardOpenOption; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import static org.graalvm.buildtools.utils.SharedConstants.GRAALVM_EXE_EXTENSION; @@ -75,6 +76,7 @@ public static List convertToArgsFile(List cliArgs) { try { File tmpFile = File.createTempFile("native-image", "args"); tmpFile.deleteOnExit(); + cliArgs = cliArgs.stream().map(NativeImageUtils::escapeArg).collect(Collectors.toList()); Files.write(tmpFile.toPath(), cliArgs, StandardCharsets.UTF_8, StandardOpenOption.CREATE); return Collections.singletonList("@" + tmpFile.getAbsolutePath()); } catch (IOException e) { @@ -82,4 +84,12 @@ public static List convertToArgsFile(List cliArgs) { return Collections.unmodifiableList(cliArgs); } } + + private static String escapeArg(String arg) { + arg = arg.replace("\\", "\\\\"); + if (arg.contains(" ")) { + arg = "\"" + arg + "\""; + } + return arg; + } } From 34ed43506819c28bcaba3939241386db8d9d94a8 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Fri, 18 Mar 2022 17:28:38 +0100 Subject: [PATCH 25/30] Fix invalid argfile when paths contain spaces Fixes #224 --- .../JavaApplicationFunctionalTest.groovy | 33 +++++++++++++++++++ .../fixtures/AbstractFunctionalTest.groovy | 6 ++++ 2 files changed, 39 insertions(+) diff --git a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy index 4876c7fd3..4af8aadc2 100644 --- a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy +++ b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy @@ -155,4 +155,37 @@ class JavaApplicationFunctionalTest extends AbstractFunctionalTest { } + @Issue("https://github.com/graalvm/native-build-tools/issues/224") + def "handles spaces in file names"() { + given: + withSpacesInProjectDir() + withSample("java-application") + + buildFile << """ + // force realization of the run task to verify that it + // doesn't accidentally introduce a dependency + tasks.getByName('run') + """.stripIndent() + + when: + run 'nativeCompile' + + then: + tasks { + succeeded ':jar', ':nativeCompile' + doesNotContain ':build', ':run' + } + + and: + def nativeApp = file("build/native/nativeCompile/java-application") + nativeApp.exists() + + when: + def process = execute(nativeApp) + + then: + process.output.contains "Hello, native!" + + } + } diff --git a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy index 6a4638603..a6a4f2e8f 100644 --- a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy +++ b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy @@ -49,6 +49,7 @@ import org.gradle.util.GradleVersion import spock.lang.Specification import spock.lang.TempDir +import java.nio.file.Files import java.nio.file.Path abstract class AbstractFunctionalTest extends Specification { @@ -114,6 +115,11 @@ abstract class AbstractFunctionalTest extends Specification { groovySettingsFile } + protected void withSpacesInProjectDir() { + testDirectory = testDirectory.resolve("with spaces") + Files.createDirectory(testDirectory) + } + protected void withSample(String name) { File sampleDir = new File("../samples/$name") GFileUtils.copyDirectory(sampleDir, testDirectory.toFile()) From d7a8b27c46344f9abb2d668d7a66acea44e26abe Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Mon, 21 Mar 2022 09:23:25 +0100 Subject: [PATCH 26/30] Add test case for Maven with spaces in directory name --- .../buildtools/utils/NativeImageUtils.java | 2 +- .../JavaApplicationFunctionalTest.groovy | 19 +++++++++++++++++++ .../AbstractGraalVMMavenFunctionalTest.groovy | 5 +++++ samples/java-application/build.gradle | 4 ++++ samples/java-application/pom.xml | 8 ++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java b/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java index 1d3ceba01..ce3045c25 100644 --- a/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java +++ b/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java @@ -85,7 +85,7 @@ public static List convertToArgsFile(List cliArgs) { } } - private static String escapeArg(String arg) { + public static String escapeArg(String arg) { arg = arg.replace("\\", "\\\\"); if (arg.contains(" ")) { arg = "\"" + arg + "\""; diff --git a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy index 905c87b58..5cf0464a8 100644 --- a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy +++ b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy @@ -41,6 +41,8 @@ package org.graalvm.buildtools.maven +import spock.lang.Issue + class JavaApplicationFunctionalTest extends AbstractGraalVMMavenFunctionalTest { def "can build and execute a native image with the Maven plugin"() { withSample("java-application") @@ -63,4 +65,21 @@ class JavaApplicationFunctionalTest extends AbstractGraalVMMavenFunctionalTest { buildSucceeded outputContains "Hello, native!" } + + @Issue("") + def "supports spaces in file names (useArgFile = #argFile)"() { + withSpacesInProjectDir() + withSample("java-application") + + when: + mvn '-Pnative', '-DskipTests', 'package', 'exec:exec@native', "-DuseArgFile=${argFile}" + + then: + buildSucceeded + outputContains "Hello, native!" + + where: + argFile << [true, false] + } + } diff --git a/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy b/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy index 0f9c60087..57d3cc7ef 100644 --- a/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy +++ b/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy @@ -72,6 +72,11 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { executor.debug = true } + protected void withSpacesInProjectDir() { + testDirectory = testDirectory.resolve("with spaces") + Files.createDirectory(testDirectory) + } + protected void withReproducer(String name) { File sampleDir = new File("reproducers/$name") copySample(sampleDir.toPath(), testDirectory) diff --git a/samples/java-application/build.gradle b/samples/java-application/build.gradle index 4a2400ff1..1953b0025 100644 --- a/samples/java-application/build.gradle +++ b/samples/java-application/build.gradle @@ -51,3 +51,7 @@ application { repositories { mavenCentral() } + +dependencies { + implementation 'org.apache.commons:commons-lang3:3.8.1' +} diff --git a/samples/java-application/pom.xml b/samples/java-application/pom.xml index 9fbda7706..7aff396f4 100644 --- a/samples/java-application/pom.xml +++ b/samples/java-application/pom.xml @@ -57,6 +57,14 @@ org.graalvm.demo.Application + + + org.apache.commons + commons-lang3 + 3.8.1 + + + native From d17200a178bd8c873e3a0dced7858b69e98837c9 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Mon, 21 Mar 2022 10:58:54 +0100 Subject: [PATCH 27/30] Rename `metadataRepository` and document feature This commit renames `jvmReachabilityMetadataRepository` to `metadataRepository` in the DSL. It also adds minimal documentation for this feature. --- docs/src/docs/asciidoc/gradle-plugin.adoc | 79 +++++++++++++++++++ docs/src/docs/asciidoc/index.adoc | 3 + .../docs/snippets/gradle/groovy/build.gradle | 43 ++++++++++ .../snippets/gradle/kotlin/build.gradle.kts | 44 +++++++++++ .../NativeConfigRepoFunctionalTest.groovy | 4 +- .../buildtools/gradle/NativeImagePlugin.java | 2 +- .../native-config-integration/build.gradle | 2 +- 7 files changed, 173 insertions(+), 4 deletions(-) diff --git a/docs/src/docs/asciidoc/gradle-plugin.adoc b/docs/src/docs/asciidoc/gradle-plugin.adoc index 1a23caa6a..d864ea551 100644 --- a/docs/src/docs/asciidoc/gradle-plugin.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin.adoc @@ -335,6 +335,85 @@ include::../snippets/gradle/groovy/build.gradle[tags=add-agent-options-individua include::../snippets/gradle/kotlin/build.gradle.kts[tags=add-agent-options-individual] ---- +[[metadata-support]] +== JVM Reachability Metadata support + +Since release 0.9.11, the plugin adds experimental support for the https://github.com/graalvm/jvm-reachability-metadata/[JVM reachability metadata repository]. +This repository provides GraalVM configuration for libraries which do not officially support GraalVM native. + +=== Enabling the metadata repository + +Support needs to be enabled explicitly: + +.Enabling the metadata repository +[source, groovy, role="multi-language-sample"] +---- +include::../snippets/gradle/groovy/build.gradle[tags=enable-metadata-repository] +---- + +[source, kotlin, role="multi-language-sample"] +---- +include::../snippets/gradle/kotlin/build.gradle.kts[tags=enable-metadata-repository] +---- + +A metadata repository consists of configuration files for GraalVM. +The plugin will automatically download the configuration metadata from the official repository if you supply the version of the repository you want to use: + +.Enabling the metadata repository +[source, groovy, role="multi-language-sample"] +---- +include::../snippets/gradle/groovy/build.gradle[tags=specify-metadata-repository-version] +---- + +[source, kotlin, role="multi-language-sample"] +---- +include::../snippets/gradle/kotlin/build.gradle.kts[tags=specify-metadata-repository-version] +---- + +Alternatively, it is possible to use a _local repository_, in which case you can specify the path to the repository: + +.Using a local repository +[source, groovy, role="multi-language-sample"] +---- +include::../snippets/gradle/groovy/build.gradle[tags=specify-metadata-repository-file] +---- + +[source, kotlin, role="multi-language-sample"] +---- +include::../snippets/gradle/kotlin/build.gradle.kts[tags=specify-metadata-repository-file] +---- + +=== Configuring the metadata repository + +Once activated, for each library included in the native image, the plugin will automatically search for GraalVM JVM reachability metadata in the repository. +In some cases, you may need to exclude a particular module from the search. +This can be done by adding it to the exclude list: + +.Excluding a module from search +[source, groovy, role="multi-language-sample"] +---- +include::../snippets/gradle/groovy/build.gradle[tags=exclude-module-from-metadata-repo] +---- + +[source, kotlin, role="multi-language-sample"] +---- +include::../snippets/gradle/kotlin/build.gradle.kts[tags=exclude-module-from-metadata-repo] +---- + +Last, it is possible for you to override the _metadata version_ of a particular module. +This may be interesting if there's no specific metadata available for the particular version of the library that you use, but that you know that a version works: + +.Specifying the metadata version to use for a particular library +[source, groovy, role="multi-language-sample"] +---- +include::../snippets/gradle/groovy/build.gradle[tags=specify-metadata-version-for-library] +---- + +[source, kotlin, role="multi-language-sample"] +---- +include::../snippets/gradle/kotlin/build.gradle.kts[tags=specify-metadata-version-for-library] +---- + [[plugin-configurations]] == Configurations defined by the plugin diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index a6d4f7281..d25f3bdb0 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -20,10 +20,13 @@ If you are interested in contributing, please refer to our https://github.com/gr * Fix long classpath issue under Windows when running native tests * Inherit environment variables and system properties from the surefire plugin configuration when executing tests +* Fix invocation of `native-image` when classpath contains spaces ==== Gradle plugin * Add support for environment variables in native test execution +* Fix invocation of `native-image` when classpath contains spaces +* Add experimental support for the JVM reachability metadata repository === Release 0.9.10 diff --git a/docs/src/docs/snippets/gradle/groovy/build.gradle b/docs/src/docs/snippets/gradle/groovy/build.gradle index c7ba25b7e..91c9f9fbd 100644 --- a/docs/src/docs/snippets/gradle/groovy/build.gradle +++ b/docs/src/docs/snippets/gradle/groovy/build.gradle @@ -149,3 +149,46 @@ graalvmNative { } } // end::add-agent-options-individual[] + +// tag::enable-metadata-repository[] +graalvmNative { + metadataRepository { + enabled = true + } +} +// end::enable-metadata-repository[] + +// tag::specify-metadata-repository-version[] +graalvmNative { + metadataRepository { + version = "1.0.0" + } +} +// end::specify-metadata-repository-version[] + +// tag::specify-metadata-repository-file[] +graalvmNative { + metadataRepository { + uri(file("metadata-repository")) + } +} +// end::specify-metadata-repository-file[] + +// tag::exclude-module-from-metadata-repo[] +graalvmNative { + metadataRepository { + // Exclude this library from automatic metadata + // repository search + excludes.add("com.company:some-library") + } +} +// end::exclude-module-from-metadata-repo[] + +// tag::specify-metadata-version-for-library[] +graalvmNative { + metadataRepository { + // Force the version of the metadata for a particular library + moduleToConfigVersion.put("com.company:some-library", "3") + } +} +// end::specify-metadata-version-for-library[] diff --git a/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts b/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts index 7d26539d0..78db3e99a 100644 --- a/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts +++ b/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts @@ -162,3 +162,47 @@ graalvmNative { } } // end::add-agent-options-individual[] + +// tag::enable-metadata-repository[] +graalvmNative { + metadataRepository { + enabled.set(true) + } +} +// end::enable-metadata-repository[] + +// tag::specify-metadata-repository-version[] +graalvmNative { + metadataRepository { + version.set("1.0.0") + } +} +// end::specify-metadata-repository-version[] + + +// tag::specify-metadata-repository-file[] +graalvmNative { + metadataRepository { + uri(file("metadata-repository")) + } +} +// end::specify-metadata-repository-file[] + +// tag::exclude-module-from-metadata-repo[] +graalvmNative { + metadataRepository { + // Exclude this library from automatic metadata + // repository search + excludes.add("com.company:some-library") + } +} +// end::exclude-module-from-metadata-repo[] + +// tag::specify-metadata-version-for-library[] +graalvmNative { + metadataRepository { + // Force the version of the metadata for a particular library + moduleToConfigVersion.put("com.company:some-library", "3") + } +} +// end::specify-metadata-version-for-library[] diff --git a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy index 3a6f1bd26..ef1b0af0e 100644 --- a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy +++ b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/NativeConfigRepoFunctionalTest.groovy @@ -94,7 +94,7 @@ class NativeConfigRepoFunctionalTest extends AbstractFunctionalTest { buildFile << """ graalvmNative { - jvmReachabilityMetadataRepository { + metadataRepository { excludedModules.add("org.graalvm.internal:library-with-reflection") } } @@ -121,7 +121,7 @@ graalvmNative { buildFile << """ graalvmNative { - jvmReachabilityMetadataRepository { + metadataRepository { moduleToConfigVersion.put("org.graalvm.internal:library-with-reflection", "2") } } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java index a0c0c061f..e35e67179 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java @@ -406,7 +406,7 @@ private GraalVMExtension registerGraalVMExtension(Project project) { } private void configureNativeConfigurationRepo(ExtensionAware graalvmNative) { - JvmReachabilityMetadataRepositoryExtension configurationRepository = graalvmNative.getExtensions().create("jvmReachabilityMetadataRepository", JvmReachabilityMetadataRepositoryExtension.class); + JvmReachabilityMetadataRepositoryExtension configurationRepository = graalvmNative.getExtensions().create("metadataRepository", JvmReachabilityMetadataRepositoryExtension.class); configurationRepository.getEnabled().convention(false); configurationRepository.getUri().convention(configurationRepository.getVersion().map(v -> { try { diff --git a/samples/native-config-integration/build.gradle b/samples/native-config-integration/build.gradle index ae713869b..6a4eda85c 100644 --- a/samples/native-config-integration/build.gradle +++ b/samples/native-config-integration/build.gradle @@ -68,7 +68,7 @@ tasks.withType(Test).configureEach { } graalvmNative { - jvmReachabilityMetadataRepository { + metadataRepository { enabled = true def extension = System.getProperty("extension", '') def repo = file("config-directory${extension ? '.' + extension : ''}") From 77941e411b0d330171b2dda0fc2a2daceb8e327e Mon Sep 17 00:00:00 2001 From: Alvaro Sanchez-Mariscal Date: Mon, 21 Mar 2022 16:53:00 +0100 Subject: [PATCH 28/30] Support applications with custom packaging types If an application has a custom packaging type, but its artefact is really a JAR file, I will be skipped by the classpath calculation algorithm. This PR allows the main project artifact to have a different packaging type, which is the case of Micronaut applications packaged as native images (`native-image`). --- .../org/graalvm/buildtools/maven/NativeBuildMojo.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeBuildMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeBuildMojo.java index ac6b94608..c63ee6d6b 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeBuildMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeBuildMojo.java @@ -123,7 +123,7 @@ public void execute() throws MojoExecutionException { for (Artifact dependency : project.getArtifacts()) { addClasspath(dependency); } - addClasspath(project.getArtifact()); + addClasspath(project.getArtifact(), project.getPackaging()); } String classpathStr = imageClasspath.stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator)); @@ -156,7 +156,11 @@ public void execute() throws MojoExecutionException { } private void addClasspath(Artifact artifact) throws MojoExecutionException { - if (!"jar".equals(artifact.getType())) { + addClasspath(artifact, "jar"); + } + + private void addClasspath(Artifact artifact, String artifactType) throws MojoExecutionException { + if (!artifactType.equals(artifact.getType())) { getLog().warn("Ignoring non-jar type ImageClasspath Entry " + artifact); return; } From 7e169772170c0c0b7df89c4e702b18297a539c0a Mon Sep 17 00:00:00 2001 From: Alvaro Sanchez-Mariscal Date: Mon, 21 Mar 2022 19:02:20 +0100 Subject: [PATCH 29/30] Add functional test --- .../JavaApplicationFunctionalTest.groovy | 12 ++ .../pom.xml | 167 ++++++++++++++++++ .../java/org/graalvm/demo/Application.java | 16 ++ .../src/main/resources/application.yml | 3 + .../src/main/resources/logback.xml | 15 ++ 5 files changed, 213 insertions(+) create mode 100644 samples/java-application-with-custom-packaging/pom.xml create mode 100644 samples/java-application-with-custom-packaging/src/main/java/org/graalvm/demo/Application.java create mode 100644 samples/java-application-with-custom-packaging/src/main/resources/application.yml create mode 100644 samples/java-application-with-custom-packaging/src/main/resources/logback.xml diff --git a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy index 5cf0464a8..8d2e40f15 100644 --- a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy +++ b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy @@ -82,4 +82,16 @@ class JavaApplicationFunctionalTest extends AbstractGraalVMMavenFunctionalTest { argFile << [true, false] } + def "can build and execute a native image with the Maven plugin when the application has a custom packaging type"() { + withSample("java-application-with-custom-packaging") + + when: + mvn 'package', '-Dpackaging=native-image', 'exec:exec@native' + + then: + buildSucceeded + outputContains "ImageClasspath Entry: org.graalvm.buildtools.examples:java-application-with-custom-packaging:native-image:0.1" + outputContains "Hello, native!" + } + } diff --git a/samples/java-application-with-custom-packaging/pom.xml b/samples/java-application-with-custom-packaging/pom.xml new file mode 100644 index 000000000..3a0deee4d --- /dev/null +++ b/samples/java-application-with-custom-packaging/pom.xml @@ -0,0 +1,167 @@ + + + + + 4.0.0 + org.graalvm.buildtools.examples + java-application-with-custom-packaging + 0.1 + ${packaging} + + + io.micronaut + micronaut-parent + 3.3.4 + + + + jar + 11 + 11 + 3.3.4 + org.graalvm.demo.Application + netty + 0.9.11-SNAPSHOT + + + + + central + https://repo.maven.apache.org/maven2 + + + + + + io.micronaut + micronaut-inject + compile + + + io.micronaut + micronaut-validation + compile + + + io.micronaut + micronaut-http-client + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + io.micronaut.test + micronaut-test-junit5 + test + + + info.picocli + picocli + compile + + + io.micronaut + micronaut-jackson-databind + compile + + + io.micronaut + micronaut-runtime + compile + + + io.micronaut.picocli + micronaut-picocli + compile + + + jakarta.annotation + jakarta.annotation-api + compile + + + ch.qos.logback + logback-classic + runtime + + + + + + + io.micronaut.build + micronaut-maven-plugin + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + + + info.picocli + picocli-codegen + ${picocli.version} + + + + -Amicronaut.processing.group=org.graalvm.demo + -Amicronaut.processing.module=demo + + + + + + + diff --git a/samples/java-application-with-custom-packaging/src/main/java/org/graalvm/demo/Application.java b/samples/java-application-with-custom-packaging/src/main/java/org/graalvm/demo/Application.java new file mode 100644 index 000000000..81e95b73d --- /dev/null +++ b/samples/java-application-with-custom-packaging/src/main/java/org/graalvm/demo/Application.java @@ -0,0 +1,16 @@ +package org.graalvm.demo; + +import io.micronaut.configuration.picocli.PicocliRunner; +import picocli.CommandLine.Command; + +@Command(name = "demo", description = "...", mixinStandardHelpOptions = true) +public class Application implements Runnable { + + public static void main(String[] args) { + PicocliRunner.run(Application.class, args); + } + + public void run() { + System.out.println("Hello, native!"); + } +} diff --git a/samples/java-application-with-custom-packaging/src/main/resources/application.yml b/samples/java-application-with-custom-packaging/src/main/resources/application.yml new file mode 100644 index 000000000..91ee466e3 --- /dev/null +++ b/samples/java-application-with-custom-packaging/src/main/resources/application.yml @@ -0,0 +1,3 @@ +micronaut: + application: + name: java-application-with-custom-packaging diff --git a/samples/java-application-with-custom-packaging/src/main/resources/logback.xml b/samples/java-application-with-custom-packaging/src/main/resources/logback.xml new file mode 100644 index 000000000..214d9d904 --- /dev/null +++ b/samples/java-application-with-custom-packaging/src/main/resources/logback.xml @@ -0,0 +1,15 @@ + + + + true + + + %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n + + + + + + + \ No newline at end of file From 542c1c2d43c2c8e73189a4f1e79af534d902b145 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Tue, 22 Mar 2022 11:40:17 +0100 Subject: [PATCH 30/30] Release 0.9.11 --- gradle/libs.versions.toml | 2 +- native-maven-plugin/reproducers/issue-144/pom.xml | 4 ++-- samples/java-application-with-custom-tests/gradle.properties | 2 +- .../java-application-with-extra-sourceset/gradle.properties | 2 +- samples/java-application-with-reflection/gradle.properties | 2 +- samples/java-application-with-reflection/pom.xml | 4 ++-- samples/java-application-with-resources/gradle.properties | 2 +- samples/java-application-with-resources/pom.xml | 4 ++-- samples/java-application-with-tests/gradle.properties | 2 +- samples/java-application-with-tests/pom.xml | 4 ++-- samples/java-application/gradle.properties | 2 +- samples/java-application/pom.xml | 4 ++-- samples/java-library/gradle.properties | 2 +- samples/java-library/pom.xml | 4 ++-- samples/kotlin-application-with-tests/gradle.properties | 2 +- samples/multi-project-with-tests/gradle.properties | 2 +- samples/native-config-integration/gradle.properties | 2 +- 17 files changed, 23 insertions(+), 23 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7eb567c6c..de4a759ab 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # Project versions -nativeBuildTools = "0.9.11-SNAPSHOT" +nativeBuildTools = "0.9.11" # External dependencies spock = "2.0-groovy-3.0" diff --git a/native-maven-plugin/reproducers/issue-144/pom.xml b/native-maven-plugin/reproducers/issue-144/pom.xml index 24dca7164..186472575 100644 --- a/native-maven-plugin/reproducers/issue-144/pom.xml +++ b/native-maven-plugin/reproducers/issue-144/pom.xml @@ -56,8 +56,8 @@ 1.8 UTF-8 - 0.9.11-SNAPSHOT - 0.9.11-SNAPSHOT + 0.9.11 + 0.9.11 example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-custom-tests/gradle.properties b/samples/java-application-with-custom-tests/gradle.properties index 030694402..e7aa7b8c8 100644 --- a/samples/java-application-with-custom-tests/gradle.properties +++ b/samples/java-application-with-custom-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.11-SNAPSHOT +native.gradle.plugin.version = 0.9.11 junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-extra-sourceset/gradle.properties b/samples/java-application-with-extra-sourceset/gradle.properties index 030694402..e7aa7b8c8 100644 --- a/samples/java-application-with-extra-sourceset/gradle.properties +++ b/samples/java-application-with-extra-sourceset/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.11-SNAPSHOT +native.gradle.plugin.version = 0.9.11 junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-reflection/gradle.properties b/samples/java-application-with-reflection/gradle.properties index 030694402..e7aa7b8c8 100644 --- a/samples/java-application-with-reflection/gradle.properties +++ b/samples/java-application-with-reflection/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.11-SNAPSHOT +native.gradle.plugin.version = 0.9.11 junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-reflection/pom.xml b/samples/java-application-with-reflection/pom.xml index 96ab41d30..a684225d5 100644 --- a/samples/java-application-with-reflection/pom.xml +++ b/samples/java-application-with-reflection/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.8.1 - 0.9.11-SNAPSHOT - 0.9.11-SNAPSHOT + 0.9.11 + 0.9.11 example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-resources/gradle.properties b/samples/java-application-with-resources/gradle.properties index 030694402..e7aa7b8c8 100644 --- a/samples/java-application-with-resources/gradle.properties +++ b/samples/java-application-with-resources/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.11-SNAPSHOT +native.gradle.plugin.version = 0.9.11 junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-resources/pom.xml b/samples/java-application-with-resources/pom.xml index 5e5ec9bad..4fd4f54db 100644 --- a/samples/java-application-with-resources/pom.xml +++ b/samples/java-application-with-resources/pom.xml @@ -51,9 +51,9 @@ 1.8 UTF-8 - 0.9.11-SNAPSHOT + 0.9.11 5.8.1 - 0.9.11-SNAPSHOT + 0.9.11 example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-tests/gradle.properties b/samples/java-application-with-tests/gradle.properties index 030694402..e7aa7b8c8 100644 --- a/samples/java-application-with-tests/gradle.properties +++ b/samples/java-application-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.11-SNAPSHOT +native.gradle.plugin.version = 0.9.11 junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-tests/pom.xml b/samples/java-application-with-tests/pom.xml index ca6d171af..5abb87abd 100644 --- a/samples/java-application-with-tests/pom.xml +++ b/samples/java-application-with-tests/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.8.1 - 0.9.11-SNAPSHOT - 0.9.11-SNAPSHOT + 0.9.11 + 0.9.11 example-app org.graalvm.demo.Application diff --git a/samples/java-application/gradle.properties b/samples/java-application/gradle.properties index 030694402..e7aa7b8c8 100644 --- a/samples/java-application/gradle.properties +++ b/samples/java-application/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.11-SNAPSHOT +native.gradle.plugin.version = 0.9.11 junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application/pom.xml b/samples/java-application/pom.xml index 7aff396f4..4cf36901e 100644 --- a/samples/java-application/pom.xml +++ b/samples/java-application/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.11-SNAPSHOT - 0.9.11-SNAPSHOT + 0.9.11 + 0.9.11 example-app org.graalvm.demo.Application diff --git a/samples/java-library/gradle.properties b/samples/java-library/gradle.properties index 030694402..e7aa7b8c8 100644 --- a/samples/java-library/gradle.properties +++ b/samples/java-library/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.11-SNAPSHOT +native.gradle.plugin.version = 0.9.11 junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-library/pom.xml b/samples/java-library/pom.xml index 0c8ecbd90..01a17a513 100644 --- a/samples/java-library/pom.xml +++ b/samples/java-library/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.11-SNAPSHOT - 0.9.11-SNAPSHOT + 0.9.11 + 0.9.11 java-library diff --git a/samples/kotlin-application-with-tests/gradle.properties b/samples/kotlin-application-with-tests/gradle.properties index 030694402..e7aa7b8c8 100644 --- a/samples/kotlin-application-with-tests/gradle.properties +++ b/samples/kotlin-application-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.11-SNAPSHOT +native.gradle.plugin.version = 0.9.11 junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/multi-project-with-tests/gradle.properties b/samples/multi-project-with-tests/gradle.properties index 030694402..e7aa7b8c8 100644 --- a/samples/multi-project-with-tests/gradle.properties +++ b/samples/multi-project-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.11-SNAPSHOT +native.gradle.plugin.version = 0.9.11 junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/native-config-integration/gradle.properties b/samples/native-config-integration/gradle.properties index 030694402..e7aa7b8c8 100644 --- a/samples/native-config-integration/gradle.properties +++ b/samples/native-config-integration/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.11-SNAPSHOT +native.gradle.plugin.version = 0.9.11 junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1