Skip to content

Commit

Permalink
Make plugins use metadata repository by default
Browse files Browse the repository at this point in the history
  • Loading branch information
dnestoro committed Jan 12, 2024
1 parent 92fe418 commit 19f3769
Show file tree
Hide file tree
Showing 12 changed files with 231 additions and 86 deletions.
12 changes: 5 additions & 7 deletions docs/src/docs/asciidoc/gradle-plugin.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -361,14 +361,14 @@ This repository provides https://www.graalvm.org/22.2/reference-manual/native-im

NOTE: This version of the plugin defaults to the using the metadata repository in version {metadata-repository-version}. There is nothing for you to configure if you are fine with this version. The repository is also published on Maven Central at the following coordinates: `org.graalvm.buildtools:graalvm-reachability-metadata:graalvm-reachability-metadata` with the `repository` classifier and `zip` extension, e.g. `graalvm-reachability-metadata-{gradle-plugin-version}-repository.zip`.

=== Enabling the metadata repository
=== Configuring the metadata repository

Support needs to be enabled explicitly:
Metadata repository is enabled by default. Support can be disabled explicitly:

.Enabling the metadata repository
.Disabling the metadata repository
[source, groovy, role="multi-language-sample"]
----
include::../snippets/gradle/groovy/build.gradle[tags=enable-metadata-repository]
include::../snippets/gradle/groovy/build.gradle[tags=disable-metadata-repository]
----

[source, kotlin, role="multi-language-sample"]
Expand Down Expand Up @@ -403,9 +403,7 @@ include::../snippets/gradle/groovy/build.gradle[tags=specify-metadata-repository
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 reachability metadata in the repository.
For each library included in the native image, the plugin will automatically search for GraalVM 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:

Expand Down
11 changes: 11 additions & 0 deletions docs/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ If you are using alternative build systems, see <<alternative-build-systems.adoc
[[changelog]]
== Changelog

=== Release 0.10.0

==== Gradle plugin

- Update plugin to use metadata repository by default

====Maven plugin

- Update plugin to use metadata repository by default


=== Release 0.9.28

* Fix path escaping problem for Windows users
Expand Down
14 changes: 6 additions & 8 deletions docs/src/docs/asciidoc/maven-plugin.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -631,14 +631,14 @@ This version of the plugin defaults to the using the metadata repository in vers
e.g. `graalvm-reachability-metadata-{maven-plugin-version}-repository.zip`.
====

=== Enabling the metadata repository
=== Configuring the metadata repository

Support needs to be enabled explicitly by including the following into the `<configuration>` element:
Metadata repository is enabled by default. Support can be disabled by including the following into the `<configuration>` element:

.Enabling the metadata repository
.Disabling the metadata repository
[source,xml,indent=0]
----
include::../../../../samples/metadata-repo-integration/pom.xml[tag=metadata-default]
include::../../../../samples/metadata-repo-integration/pom.xml[tag=metadata-disable]
----

Alternatively, you can use a _remote repository_, in which case you can specify the URL of the ZIP file:
Expand All @@ -658,10 +658,8 @@ include::../../../../samples/native-config-integration/pom.xml[tag=metadata-loca
----
<1> The local path can point to an _exploded_ directory, or to a compressed ZIP file.

=== Configuring the metadata repository

Once activated, for each library included in the native image, the plugin will automatically search for GraalVM reachability metadata in the repository that was released together with the plugin.
In case you want to use another verion of the metadata use:
For each library included in the native image, the plugin will automatically search for GraalVM reachability metadata in the repository that was released together with the plugin.
In case you want to use another version of the metadata use:

.Choosing a version for the metadata repository
[source,xml,indent=0]
Expand Down
6 changes: 3 additions & 3 deletions docs/src/docs/snippets/gradle/groovy/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,13 @@ graalvmNative {
}
// end::disable-test-support[]

// tag::enable-metadata-repository[]
// tag::disable-metadata-repository[]
graalvmNative {
metadataRepository {
enabled = true
enabled = false
}
}
// end::enable-metadata-repository[]
// end::disable-metadata-repository[]

// tag::specify-metadata-repository-version[]
graalvmNative {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import org.gradle.api.logging.LogLevel

class OfficialMetadataRepoFunctionalTest extends AbstractFunctionalTest {

def "the application runs when using the official metadata repository"() {
def "the application runs when using the official metadata repository by default"() {
given:
withSample("metadata-repo-integration")
debug = true
Expand All @@ -65,4 +65,18 @@ class OfficialMetadataRepoFunctionalTest extends AbstractFunctionalTest {
outputDoesNotContain "Falling back to the default repository at"
}

def "the application doesn't run when usage of the official metadata repository is disabled"() {
given:
withSample("metadata-repo-integration")
debug = true

when:
run 'nativeRun', "-Pmetadata.repo.enabled=false", "-D${NativeImagePlugin.CONFIG_REPO_LOGLEVEL}=${LogLevel.LIFECYCLE}"

then:
tasks {
failed ':nativeCompile'
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ private GraalVMExtension registerGraalVMExtension(Project project) {

private void configureNativeConfigurationRepo(ExtensionAware graalvmNative) {
GraalVMReachabilityMetadataRepositoryExtension configurationRepository = graalvmNative.getExtensions().create("metadataRepository", GraalVMReachabilityMetadataRepositoryExtension.class);
configurationRepository.getEnabled().convention(false);
configurationRepository.getEnabled().convention(true);
configurationRepository.getVersion().convention(VersionInfo.METADATA_REPO_VERSION);
configurationRepository.getUri().convention(configurationRepository.getVersion().map(serializableTransformerOf(this::getReachabilityMetadataRepositoryUrlForVersion)));
configurationRepository.getExcludedModules().convention(Collections.emptySet());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ abstract class AbstractFunctionalTest extends Specification {
}
}

void failed(String... tasks) {
tasks.each { task ->
contains(task)
assert result.task(task).outcome == TaskOutcome.FAILED
}
}

void skipped(String... tasks) {
tasks.each { task ->
contains(task)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ package org.graalvm.buildtools.maven
import spock.lang.IgnoreIf

class OfficialMetadataRepositoryFunctionalTest extends AbstractGraalVMMavenFunctionalTest {

@IgnoreIf({ os.windows })
void "the application runs when using the official metadata repository"() {
given:
Expand Down Expand Up @@ -82,4 +83,35 @@ class OfficialMetadataRepositoryFunctionalTest extends AbstractGraalVMMavenFunct
outputContains "[graalvm reachability metadata repository for com.h2database:h2:"
outputContains "Configuration directory is com.h2database" + File.separator + "h2" + File.separator
}

@IgnoreIf({ os.windows })
void "the application uses specified version of metadata repository without explicit enable"() {
given:
withSample("metadata-repo-integration")

when:
mvn '-PenableMetadataByDefault', '-DquickBuild', '-DskipTests', 'package', 'exec:exec@native'

then:
buildSucceeded

and: "the run succeeded and retrieved data from the database"
outputContains "Customers in the database"

and: "finds metadata in the remote repository"
outputContains "[graalvm reachability metadata repository for com.h2database:h2:"
outputContains "Configuration directory is com.h2database" + File.separator + "h2" + File.separator
}

@IgnoreIf({ os.windows })
void "the application doesn't run when metadata repository is disabled"() {
given:
withSample("metadata-repo-integration")

when:
mvn '-PdisabledMetadataRepo', '-DquickBuild', '-DskipTests', 'package', 'exec:exec@native'

then:
buildFailed
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,78 +123,112 @@ protected AbstractNativeMojo() {
}

protected boolean isMetadataRepositoryEnabled() {
return metadataRepositoryConfiguration != null && metadataRepositoryConfiguration.isEnabled();
return metadataRepositoryConfiguration == null || metadataRepositoryConfiguration.isEnabled();
}

protected void configureMetadataRepository() {
if (isMetadataRepositoryEnabled()) {
Path repoPath = null;
Path destinationRoot = reachabilityMetadataOutputDirectory.toPath();
if (Files.exists(destinationRoot) && !Files.isDirectory(destinationRoot)) {
throw new RuntimeException("Metadata repository must be a directory, please remove regular file at: " + destinationRoot);
}
if (!isMetadataRepositoryEnabled()) {
logger.warn("GraalVM reachability metadata repository is disabled");
return;
}

Path destinationRoot = reachabilityMetadataOutputDirectory.toPath();
if (Files.exists(destinationRoot) && !Files.isDirectory(destinationRoot)) {
throw new RuntimeException("Metadata repository must be a directory, please remove regular file at: " + destinationRoot);
}
try {
Files.createDirectories(destinationRoot);
} catch (IOException e) {
throw new RuntimeException(e);
}

Path repoPath = metadataRepositoryConfiguration != null ? getRepo(destinationRoot) : getDefaultRepo(destinationRoot);
if (repoPath == null) {
throw new RuntimeException("Cannot pull GraalVM reachability metadata repository either from the one specified in the configuration or the default one.\n" +
"Note: Since the repository is enabled by default, you can disable it manually in your pom.xml file (see this: " +
"https://graalvm.github.io/native-build-tools/latest/maven-plugin.html#_configuring_the_metadata_repository)");
} else {
metadataRepository = new FileSystemRepository(repoPath, new FileSystemRepository.Logger() {
@Override
public void log(String groupId, String artifactId, String version, Supplier<String> message) {
logger.info(String.format("[graalvm reachability metadata repository for %s:%s:%s]: %s", groupId, artifactId, version, message.get()));
}
});
}
}

private Path getDefaultRepo(Path destinationRoot) {
// try to get default Metadata Repository from Maven Central
URL targetUrl = resolveDefaultMetadataRepositoryUrl();
if (targetUrl == null) {
logger.warn("Unable to find the GraalVM reachability metadata repository in Maven repository. " +
"Falling back to the default repository.");
String metadataUrl = String.format(METADATA_REPO_URL_TEMPLATE, VersionInfo.METADATA_REPO_VERSION);
try {
Files.createDirectories(destinationRoot);
} catch (IOException e) {
targetUrl = new URI(metadataUrl).toURL();
// TODO investigate if the following line is necessary
metadataRepositoryConfiguration.setUrl(targetUrl);
} catch (URISyntaxException | MalformedURLException e) {
throw new RuntimeException(e);
}
}

if (metadataRepositoryConfiguration.getLocalPath() != null) {
Path localPath = metadataRepositoryConfiguration.getLocalPath().toPath();
Path destination = destinationRoot.resolve(FileUtils.hashFor(localPath.toUri()));
repoPath = unzipLocalMetadata(localPath, destination);
} else {
URL targetUrl = metadataRepositoryConfiguration.getUrl();
if (targetUrl == null) {
String version = metadataRepositoryConfiguration.getVersion();
if (version == null) {
// Both the URL and version are unset, so we want to use
// the version from Maven Central
targetUrl = resolveDefaultMetadataRepositoryUrl();
if (targetUrl == null) {
logger.warn("Unable to find the GraalVM reachability metadata repository in Maven repository. " +
"Falling back to the default repository.");
version = VersionInfo.METADATA_REPO_VERSION;
}
}
if (version != null) {
String metadataUrl = String.format(METADATA_REPO_URL_TEMPLATE, version);
try {
targetUrl = new URI(metadataUrl).toURL();
metadataRepositoryConfiguration.setUrl(targetUrl);
} catch (URISyntaxException | MalformedURLException e) {
throw new RuntimeException(e);
}
return downloadMetadataRepo(destinationRoot, targetUrl);
}

private Path getRepo(Path destinationRoot) {
if (metadataRepositoryConfiguration.getLocalPath() != null) {
Path localPath = metadataRepositoryConfiguration.getLocalPath().toPath();
Path destination = destinationRoot.resolve(FileUtils.hashFor(localPath.toUri()));
return unzipLocalMetadata(localPath, destination);
} else {
URL targetUrl = metadataRepositoryConfiguration.getUrl();
if (targetUrl == null) {
String version = metadataRepositoryConfiguration.getVersion();
if (version == null) {
// Both the URL and version are unset, so we want to use
// the version from Maven Central
targetUrl = resolveDefaultMetadataRepositoryUrl();
if (targetUrl == null) {
logger.warn("Unable to find the GraalVM reachability metadata repository in Maven repository. " +
"Falling back to the default repository.");
version = VersionInfo.METADATA_REPO_VERSION;
}
}
Path destination;
try {
destination = destinationRoot.resolve(FileUtils.hashFor(targetUrl.toURI()));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
if (Files.exists(destination)) {
repoPath = destination;
} else {
Optional<Path> download = downloadMetadata(targetUrl, destination);
if (download.isPresent()) {
logger.info("Downloaded GraalVM reachability metadata repository from " + targetUrl);
repoPath = unzipLocalMetadata(download.get(), destination);
if (version != null) {
String metadataUrl = String.format(METADATA_REPO_URL_TEMPLATE, version);
try {
targetUrl = new URI(metadataUrl).toURL();
// TODO investigate if the following line is necessary
metadataRepositoryConfiguration.setUrl(targetUrl);
} catch (URISyntaxException | MalformedURLException e) {
throw new RuntimeException(e);
}
}
}

if (repoPath == null) {
logger.warn("GraalVM reachability metadata repository is enabled, but no repository has been configured");
} else {
metadataRepository = new FileSystemRepository(repoPath, new FileSystemRepository.Logger() {
@Override
public void log(String groupId, String artifactId, String version, Supplier<String> message) {
logger.info(String.format("[graalvm reachability metadata repository for %s:%s:%s]: %s", groupId, artifactId, version, message.get()));
}
});
return downloadMetadataRepo(destinationRoot, targetUrl);
}
}

private Path downloadMetadataRepo(Path destinationRoot, URL targetUrl) {
Path destination;
try {
destination = destinationRoot.resolve(FileUtils.hashFor(targetUrl.toURI()));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
if (Files.exists(destination)) {
return destination;
} else {
Optional<Path> download = downloadMetadata(targetUrl, destination);
if (download.isPresent()) {
logger.info("Downloaded GraalVM reachability metadata repository from " + targetUrl);
return unzipLocalMetadata(download.get(), destination);
}
}

return null;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@

public class MetadataRepositoryConfiguration {

@Parameter(defaultValue = "false")
private boolean enabled;
@Parameter(defaultValue = "true")
private boolean enabled = true;

@Parameter
private String version;
Expand Down
4 changes: 3 additions & 1 deletion samples/metadata-repo-integration/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ graalvmNative {
defaultMode = "standard"
}
metadataRepository {
enabled = true
if (providers.gradleProperty("metadata.repo.enabled").isPresent()) {
enabled = providers.gradleProperty("metadata.repo.enabled").map { value -> value.toBoolean()}
}
}
binaries.all {
verbose = true
Expand Down
Loading

0 comments on commit 19f3769

Please sign in to comment.