blob: 669a78ddc3ed70fd1ae81d18dde137b1c2b745b2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.apache.geronimo.arthur.maven.mojo;
import org.apache.geronimo.arthur.impl.nativeimage.archive.Extractor;
import org.apache.geronimo.arthur.impl.nativeimage.installer.SdkmanGraalVMInstaller;
import org.apache.geronimo.arthur.impl.nativeimage.installer.SdkmanGraalVMInstallerConfiguration;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.installation.InstallRequest;
import org.eclipse.aether.installation.InstallResult;
import org.eclipse.aether.installation.InstallationException;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import java.io.File;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Collections.emptyMap;
import static java.util.Locale.ROOT;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.joining;
public abstract class ArthurMojo extends AbstractMojo {
/**
* native-image binary to use, if not set it will install graal in the local repository.
*/
@Parameter(property = "arthur.nativeImage")
protected String nativeImage;
/**
* Once built, the binary path is set in maven properties.
* This enables to configure the prefix to use.
*/
@Parameter(defaultValue = "arthur.", property = "arthur.propertiesPrefix")
protected String propertiesPrefix;
@Parameter(defaultValue = "${project}", readonly = true)
protected MavenProject project;
@Parameter(defaultValue = "${settings.offline}", readonly = true)
protected boolean offline;
//
// Installer parameters
//
/**
* In case Graal must be downloaded to get native-image, where to take it from.
*/
@Parameter(property = "arthur.graalDownloadUrl",
defaultValue = "https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${graalSimpleVersion}/graalvm-ce-java${graalJavaVersion}-${githubPlatform}-${graalSimpleVersion}.tar.gz")
private String graalDownloadUrl;
/**
* In case Graal must be downloaded to get native-image, which version to download.
* It contains the graal version and can be suffixed by the graal java version prefixed with "r" (as on sdkman).
*/
@Parameter(property = "arthur.graalVersion", defaultValue = "20.3.0.r8")
private String graalVersion;
/**
* In case Graal must be downloaded to get native-image, which platform to download, auto will handle it for you.
*/
@Parameter(property = "arthur.graalPlatform", defaultValue = "auto")
private String graalPlatform;
/**
* In case Graal must be downloaded to get native-image, it will be cached in the local repository with this gav.
*/
@Parameter(property = "arthur.graalCacheGav", defaultValue = "org.apache.geronimo.arthur.cache:graal")
private String graalCacheGav; // groupId:artifactId
/**
* Where the temporary files are created.
*/
@Parameter(defaultValue = "${project.build.directory}/arthur_workdir")
protected File workdir;
@Parameter(defaultValue = "${repositorySystemSession}")
protected RepositorySystemSession repositorySystemSession;
@Parameter(defaultValue = "${project.remoteProjectRepositories}")
private List<RemoteRepository> remoteRepositories;
@Component
private RepositorySystem repositorySystem;
protected boolean isInheritIO() {
return false;
}
protected SdkmanGraalVMInstaller createInstaller() {
final String graalPlatform = buildPlatform();
final Extractor extractor = new Extractor();
final String url = buildDownloadUrl(graalPlatform);
getLog().debug("Graal URL: " + url);
return new SdkmanGraalVMInstaller(SdkmanGraalVMInstallerConfiguration.builder()
.offline(offline)
.inheritIO(isInheritIO())
.url(url)
.version(graalVersion)
.platform(graalPlatform)
.gav(buildCacheGav(graalPlatform))
.workdir(workdir.toPath())
.resolver(gav -> resolve(toArtifact(gav)).getFile().toPath())
.installer((gav, file) -> install(file.toFile(), toArtifact(gav)))
.extractor(extractor::unpack)
.build());
}
protected org.eclipse.aether.artifact.Artifact toArtifact(final String s) {
return new DefaultArtifact(s);
}
protected Path install(final File file, final org.eclipse.aether.artifact.Artifact art) {
final org.eclipse.aether.artifact.Artifact artifact = new DefaultArtifact(
art.getGroupId(),
art.getArtifactId(),
art.getClassifier(),
art.getExtension(),
art.getVersion(),
emptyMap(),
file);
try {
final InstallResult result = repositorySystem.install(
repositorySystemSession,
new InstallRequest().addArtifact(artifact));
if (result.getArtifacts().isEmpty()) {
throw new IllegalStateException("Can't install " + art);
}
return resolve(art).getFile().toPath();
} catch (final InstallationException e) {
throw new IllegalStateException(e);
}
}
protected org.eclipse.aether.artifact.Artifact resolve(final org.eclipse.aether.artifact.Artifact art) {
final ArtifactRequest artifactRequest =
new ArtifactRequest().setArtifact(art).setRepositories(remoteRepositories);
try {
final ArtifactResult result = repositorySystem.resolveArtifact(repositorySystemSession, artifactRequest);
if (result.isMissing()) {
throw new IllegalStateException("Can't find " + art);
}
return result.getArtifact();
} catch (final ArtifactResolutionException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
private String buildCacheGav(final String graalPlatform) {
if (!graalPlatform.toLowerCase(ROOT).startsWith("linux")) { // cygwin
return graalCacheGav + ":zip:" + graalPlatform + ':' + graalVersion;
}
return graalCacheGav + ":tar.gz:" + graalPlatform + ':' + graalVersion;
}
private String buildDownloadUrl(final String graalPlatform) {
if (graalDownloadUrl.startsWith("https://api.sdkman.io/2/broker/download/java/")) {
return graalDownloadUrl
.replace("${graalVersion}", graalVersion)
.replace("${platform}", graalPlatform);
}
// else assume github
final String[] versionSegments = graalVersion.split("\\.");
final boolean versionIncludesJavaVersion = versionSegments[versionSegments.length - 1].startsWith("r");
final String graalSimpleVersion = versionIncludesJavaVersion ?
Stream.of(versionSegments).limit(versionSegments.length - 1).collect(joining(".")) :
graalVersion;
final String graalJavaVersion = versionIncludesJavaVersion ?
versionSegments[versionSegments.length - 1].substring(1) :
System.getProperty("java.version", "1.8").startsWith("8") ? "8" : "11";
final String githubPlatform = graalPlatform.contains("win") ?
"windows-amd64" : (graalPlatform.contains("linux") ? "linux-amd64" : "darwin-amd64");
return graalDownloadUrl
.replace("${graalSimpleVersion}", graalSimpleVersion)
.replace("${graalJavaVersion}", graalJavaVersion)
.replace("${githubPlatform}", githubPlatform);
}
private String buildPlatform() {
if (!"auto".equals(graalPlatform)) {
return graalPlatform;
}
return (System.getProperty("os.name", "linux") +
ofNullable(System.getProperty("sun.arch.data.model"))
.orElseGet(() -> System.getProperty("os.arch", "64").replace("amd", "")))
.toLowerCase(ROOT);
}
}