[pure-refactor] Make everything incremental, fix custom version bugs (#17)
This commit is contained in:
parent
6e94f257c2
commit
7d2d672697
12 changed files with 384 additions and 199 deletions
|
@ -4,7 +4,7 @@ A simple wrapper around GraalVM tooling that will download and locally cache a G
|
|||
available select parts of the GraalVM compiler for use in Gradle builds.
|
||||
|
||||
To use this plugin, apply `com.palantir.graal`. See a full example in the
|
||||
[integration tests](src/test/groovy/com/palantir/gradle/graal/GradleGraalPluginIntegrationSpec.groovy).
|
||||
[ETE tests](src/test/groovy/com/palantir/gradle/graal/GradleGraalEndToEndSpec.groovy).
|
||||
|
||||
Gradle Tasks
|
||||
------------
|
||||
|
|
|
@ -65,6 +65,7 @@ dependencies {
|
|||
|
||||
testCompile gradleTestKit()
|
||||
testCompile 'com.netflix.nebula:nebula-test'
|
||||
testCompile 'com.squareup.okhttp3:mockwebserver'
|
||||
|
||||
baseline 'com.palantir.baseline:gradle-baseline-java-config:0.26.1@zip'
|
||||
}
|
||||
|
@ -95,7 +96,7 @@ tasks.withType(JavaCompile) {
|
|||
gradlePlugin {
|
||||
// do not add new task to publish to plugins.gradle.org
|
||||
automatedPublishing = false
|
||||
|
||||
|
||||
plugins {
|
||||
graal {
|
||||
id = 'com.palantir.graal'
|
||||
|
|
|
@ -23,63 +23,65 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.internal.TaskInternal;
|
||||
import org.gradle.api.file.RegularFile;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.specs.Spec;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.OutputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
/** Downloads GraalVM binaries to {@link GradleGraalPlugin#CACHE_DIR}. */
|
||||
/** Downloads GraalVM binaries. */
|
||||
public class DownloadGraalTask extends DefaultTask {
|
||||
|
||||
private static final String ARTIFACT_PATTERN = "[url]/vm-[version]/graalvm-ce-[version]-[os]-[arch].tar.gz";
|
||||
private static final String FILENAME_PATTERN = "graalvm-ce-[version]-[arch].tar.gz";
|
||||
|
||||
@Input private Provider<String> graalVersion;
|
||||
@Input private Provider<String> downloadBaseUrl;
|
||||
private final Property<String> graalVersion = getProject().getObjects().property(String.class);
|
||||
private final Property<String> downloadBaseUrl = getProject().getObjects().property(String.class);
|
||||
private final Property<Path> cacheDir = getProject().getObjects().property(Path.class);
|
||||
|
||||
public DownloadGraalTask() {
|
||||
setGroup(GradleGraalPlugin.TASK_GROUP);
|
||||
setDescription("Downloads and caches GraalVM binaries.");
|
||||
|
||||
onlyIf(task -> !getTgz().get().getAsFile().exists());
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public final void downloadGraal() throws IOException {
|
||||
Path cache = getCache();
|
||||
if (!(cache.toFile().mkdirs() || cache.toFile().exists())) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to make cache directory, and the cache directory does not already exist: " + cache);
|
||||
Path cache = getCacheSubdirectory().get();
|
||||
Files.createDirectories(cache);
|
||||
try (InputStream in = new URL(render(ARTIFACT_PATTERN)).openStream()) {
|
||||
Files.copy(in, getTgz().get().getAsFile().toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
InputStream in = new URL(render(ARTIFACT_PATTERN)).openStream();
|
||||
Files.copy(in, getOutput(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getGroup() {
|
||||
return GradleGraalPlugin.TASK_GROUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getDescription() {
|
||||
return "Downloads and caches GraalVM binaries.";
|
||||
}
|
||||
|
||||
@OutputFile
|
||||
public final Path getOutput() {
|
||||
return getCache().resolve(render(FILENAME_PATTERN));
|
||||
public final Provider<RegularFile> getTgz() {
|
||||
return getProject().getLayout()
|
||||
.file(getCacheSubdirectory().map(dir -> dir.resolve(render(FILENAME_PATTERN)).toFile()));
|
||||
}
|
||||
|
||||
/** Returns a lambda that prevents this task from running if the download target already exists in the cache. */
|
||||
@Override
|
||||
public final Spec<? super TaskInternal> getOnlyIf() {
|
||||
return spec -> !getOutput().toFile().exists();
|
||||
@Input
|
||||
public final Provider<String> getGraalVersion() {
|
||||
return graalVersion;
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:hiddenfield")
|
||||
public final void configure(Provider<String> graalVersion, Provider<String> downloadBaseUrl) {
|
||||
this.graalVersion = graalVersion;
|
||||
this.downloadBaseUrl = downloadBaseUrl;
|
||||
public final void setGraalVersion(Provider<String> provider) {
|
||||
graalVersion.set(provider);
|
||||
}
|
||||
|
||||
private Path getCache() {
|
||||
return GradleGraalPlugin.CACHE_DIR.resolve(graalVersion.get());
|
||||
@Input
|
||||
public final Provider<String> getDownloadBaseUrl() {
|
||||
return downloadBaseUrl;
|
||||
}
|
||||
|
||||
public final void setDownloadBaseUrl(Provider<String> provider) {
|
||||
downloadBaseUrl.set(provider);
|
||||
}
|
||||
|
||||
private Provider<Path> getCacheSubdirectory() {
|
||||
return cacheDir.map(dir -> dir.resolve(graalVersion.get()));
|
||||
}
|
||||
|
||||
private String render(String pattern) {
|
||||
|
@ -109,4 +111,8 @@ public class DownloadGraalTask extends DefaultTask {
|
|||
throw new IllegalStateException("No GraalVM support for " + Platform.architecture());
|
||||
}
|
||||
}
|
||||
|
||||
final void setCacheDir(Path value) {
|
||||
cacheDir.set(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,21 +16,38 @@
|
|||
|
||||
package com.palantir.gradle.graal;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.internal.TaskInternal;
|
||||
import org.gradle.api.file.Directory;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.file.RegularFile;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.specs.Spec;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
/** Extracts GraalVM tooling from downloaded tgz archive using the system's tar command. */
|
||||
public class ExtractGraalTask extends DefaultTask {
|
||||
|
||||
@Input private Provider<File> inputTgz;
|
||||
@Input private Provider<String> graalVersion;
|
||||
private final RegularFileProperty inputTgz = newInputFile();
|
||||
private final Property<String> graalVersion = getProject().getObjects().property(String.class);
|
||||
private final DirectoryProperty outputDirectory = newOutputDirectory();
|
||||
private final Property<Path> cacheDir = getProject().getObjects().property(Path.class);
|
||||
|
||||
public ExtractGraalTask() {
|
||||
setGroup(GradleGraalPlugin.TASK_GROUP);
|
||||
setDescription("Extracts GraalVM tooling from downloaded tgz archive using the system's tar command.");
|
||||
|
||||
onlyIf(task -> !getOutputDirectory().get().getAsFile().exists());
|
||||
outputDirectory.set(graalVersion.map(v ->
|
||||
getProject().getLayout().getProjectDirectory()
|
||||
.dir(cacheDir.get().toFile().getAbsolutePath())
|
||||
.dir(v)
|
||||
.dir("graalvm-ce-" + v)));
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public final void extractGraal() {
|
||||
|
@ -41,34 +58,35 @@ public class ExtractGraalTask extends DefaultTask {
|
|||
// ideally this would be a CopyTask, but through Gradle 4.9 CopyTask fails to correctly extract symlinks
|
||||
getProject().exec(spec -> {
|
||||
spec.executable("tar");
|
||||
spec.args("-xzf", inputTgz.get().getAbsolutePath());
|
||||
spec.workingDir(GradleGraalPlugin.CACHE_DIR.resolve(graalVersion.get()));
|
||||
spec.args("-xzf", inputTgz.get().getAsFile().getAbsolutePath());
|
||||
spec.workingDir(cacheDir.get().resolve(graalVersion.get()));
|
||||
});
|
||||
}
|
||||
|
||||
@InputFile
|
||||
public final Provider<RegularFile> getInputTgz() {
|
||||
return inputTgz;
|
||||
}
|
||||
|
||||
public final void setInputTgz(Provider<RegularFile> value) {
|
||||
this.inputTgz.set(value);
|
||||
}
|
||||
|
||||
@Input
|
||||
public final Provider<String> getGraalVersion() {
|
||||
return graalVersion;
|
||||
}
|
||||
|
||||
public final void setGraalVersion(Provider<String> provider) {
|
||||
graalVersion.set(provider);
|
||||
}
|
||||
|
||||
@OutputDirectory
|
||||
public final Path getOutputDirectory() {
|
||||
return GradleGraalPlugin.CACHE_DIR.resolve(graalVersion.get()).resolve("graalvm-ce-" + graalVersion.get());
|
||||
public final Provider<Directory> getOutputDirectory() {
|
||||
return outputDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Spec<? super TaskInternal> getOnlyIf() {
|
||||
return spec -> !getOutputDirectory().toFile().exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getGroup() {
|
||||
return GradleGraalPlugin.TASK_GROUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getDescription() {
|
||||
return "Extracts GraalVM tooling from downloaded tgz archive using the system's tar command.";
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:hiddenfield")
|
||||
public final void configure(Provider<File> inputTgz, Provider<String> graalVersion) {
|
||||
this.inputTgz = inputTgz;
|
||||
this.graalVersion = graalVersion;
|
||||
final void setCacheDir(Path value) {
|
||||
cacheDir.set(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@ public class GraalExtension {
|
|||
private static final String DEFAULT_DOWNLOAD_BASE_URL = "https://github.com/oracle/graal/releases/download/";
|
||||
private static final String DEFAULT_GRAAL_VERSION = "1.0.0-rc6";
|
||||
|
||||
private Property<String> downloadBaseUrl;
|
||||
private Property<String> graalVersion;
|
||||
private Property<String> mainClass;
|
||||
private Property<String> outputName;
|
||||
private final Property<String> downloadBaseUrl;
|
||||
private final Property<String> graalVersion;
|
||||
private final Property<String> mainClass;
|
||||
private final Property<String> outputName;
|
||||
|
||||
public GraalExtension(Project project) {
|
||||
downloadBaseUrl = project.getObjects().property(String.class);
|
||||
|
@ -86,7 +86,7 @@ public class GraalExtension {
|
|||
*
|
||||
* <p>Defaults to {@link #DEFAULT_GRAAL_VERSION}</p>
|
||||
*/
|
||||
public final Property<String> getGraalVersion() {
|
||||
public final Provider<String> getGraalVersion() {
|
||||
return graalVersion;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,12 @@ package com.palantir.gradle.graal;
|
|||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Transformer;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
import org.gradle.jvm.tasks.Jar;
|
||||
|
||||
/**
|
||||
* Adds tasks to download, extract and interact with GraalVM tooling.
|
||||
|
@ -44,61 +44,51 @@ import org.gradle.api.provider.Provider;
|
|||
*/
|
||||
public class GradleGraalPlugin implements Plugin<Project> {
|
||||
|
||||
/** Location to cache downloaded and extracted GraalVM tooling. */
|
||||
public static final Path CACHE_DIR =
|
||||
Paths.get(System.getProperty("user.home"), ".gradle", "caches", "com.palantir.graal");
|
||||
|
||||
public static final String TASK_GROUP = "Graal";
|
||||
static final String TASK_GROUP = "Graal";
|
||||
|
||||
@Override
|
||||
public final void apply(Project project) {
|
||||
project.getPluginManager().apply(JavaPlugin.class);
|
||||
GraalExtension extension = project.getExtensions().create("graal", GraalExtension.class, project);
|
||||
|
||||
DownloadGraalTask downloadGraal = project.getTasks().create(
|
||||
"downloadGraalTooling", DownloadGraalTask.class, task -> {
|
||||
task.configure(extension.getGraalVersion(), extension.getDownloadBaseUrl());
|
||||
Path cacheDir = Optional.ofNullable((String) project.getProperties().get("com.palantir.graal.cache.dir"))
|
||||
.map(Paths::get)
|
||||
.orElse(project.getGradle().getGradleUserHomeDir().toPath()
|
||||
.resolve("caches")
|
||||
.resolve("com.palantir.graal"));
|
||||
|
||||
TaskProvider<DownloadGraalTask> downloadGraal = project.getTasks().register(
|
||||
"downloadGraalTooling",
|
||||
DownloadGraalTask.class,
|
||||
task -> {
|
||||
task.setGraalVersion(extension.getGraalVersion());
|
||||
task.setDownloadBaseUrl(extension.getDownloadBaseUrl());
|
||||
task.setCacheDir(cacheDir);
|
||||
});
|
||||
|
||||
ExtractGraalTask extractGraal = project.getTasks().create(
|
||||
"extractGraalTooling", ExtractGraalTask.class, task -> {
|
||||
TaskProvider<ExtractGraalTask> extractGraal = project.getTasks().register(
|
||||
"extractGraalTooling",
|
||||
ExtractGraalTask.class,
|
||||
task -> {
|
||||
task.setGraalVersion(extension.getGraalVersion());
|
||||
task.setInputTgz(downloadGraal.get().getTgz());
|
||||
task.setCacheDir(cacheDir);
|
||||
task.dependsOn(downloadGraal);
|
||||
task.configure(asProvider(() -> downloadGraal.getOutput().toFile()), extension.getGraalVersion());
|
||||
});
|
||||
|
||||
project.getTasks().create("nativeImage", NativeImageTask.class, task -> {
|
||||
task.dependsOn(extractGraal);
|
||||
task.dependsOn("jar");
|
||||
task.configure(extension.getMainClass(), extension.getOutputName(), extension.getGraalVersion());
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> Provider<T> asProvider(Supplier<T> supplier) {
|
||||
return new Provider<T>() {
|
||||
@Override
|
||||
public T get() {
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public T getOrNull() {
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getOrElse(T other) {
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> Provider<S> map(Transformer<? extends S, ? super T> transformer) {
|
||||
return asProvider(() -> transformer.transform(get()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
TaskProvider<Jar> jar = project.getTasks().withType(Jar.class).named("jar");
|
||||
project.getTasks().register(
|
||||
"nativeImage",
|
||||
NativeImageTask.class,
|
||||
task -> {
|
||||
task.setMainClass(extension.getMainClass());
|
||||
task.setOutputName(extension.getOutputName());
|
||||
task.setGraalVersion(extension.getGraalVersion());
|
||||
task.setJarFile(jar.map(j -> j.getOutputs().getFiles().getSingleFile()));
|
||||
task.setClasspath(project.getConfigurations().named("runtimeClasspath"));
|
||||
task.setCacheDir(cacheDir);
|
||||
task.dependsOn(extractGraal);
|
||||
task.dependsOn(jar);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
package com.palantir.gradle.graal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
|
@ -25,90 +27,82 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.file.RegularFile;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Classpath;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.OutputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
/** Runs GraalVM's native-image command with configured options and parameters. */
|
||||
public class NativeImageTask extends DefaultTask {
|
||||
|
||||
@Input private Provider<String> mainClass;
|
||||
@Input private Provider<String> outputName;
|
||||
@Input private Provider<String> graalVersion;
|
||||
private final Property<String> mainClass = getProject().getObjects().property(String.class);
|
||||
private final Property<String> outputName = getProject().getObjects().property(String.class);
|
||||
private final Property<String> graalVersion = getProject().getObjects().property(String.class);
|
||||
private final Property<Configuration> classpath = getProject().getObjects().property(Configuration.class);
|
||||
private final RegularFileProperty jarFile = newInputFile();
|
||||
private final RegularFileProperty outputFile = newOutputFile();
|
||||
private final Property<Path> cacheDir = getProject().getObjects().property(Path.class);
|
||||
|
||||
public NativeImageTask() {
|
||||
setGroup(GradleGraalPlugin.TASK_GROUP);
|
||||
setDescription("Runs GraalVM's native-image command with configured options and parameters.");
|
||||
|
||||
this.outputFile.set(getProject().getLayout().getBuildDirectory()
|
||||
.dir("graal")
|
||||
.map(d -> d.file(outputName.get())));
|
||||
|
||||
doLast(t -> {
|
||||
getLogger().warn("native-image available at {} ({}MB)",
|
||||
getProject().relativePath(outputFile.get().getAsFile()),
|
||||
fileSizeMegabytes(outputFile.get()));
|
||||
});
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public final void nativeImage() {
|
||||
// TODO(rfink): declare classpath list as @Input in order to unlock incremental builds
|
||||
public final void nativeImage() throws IOException {
|
||||
List<String> args = new ArrayList<>();
|
||||
args.add("-cp");
|
||||
args.add(generateClasspathArgument());
|
||||
args.add("-H:Path=" + maybeCreateOutputDirectory().getAbsolutePath());
|
||||
if (outputName.isPresent()) {
|
||||
args.add("-H:Name=" + outputName.get());
|
||||
}
|
||||
args.add(mainClass.get());
|
||||
|
||||
getProject().exec(spec -> {
|
||||
if (!mainClass.isPresent()) {
|
||||
throw new IllegalArgumentException("nativeImage requires graal.mainClass to be defined.");
|
||||
}
|
||||
if (!graalVersion.isPresent()) {
|
||||
throw new IllegalStateException("nativeImage requires graal.version to be defined.");
|
||||
}
|
||||
|
||||
List<String> args = new ArrayList<>();
|
||||
args.add("-cp");
|
||||
args.add(generateClasspathArgument());
|
||||
|
||||
args.add("-H:Path=" + getOutputDirectory());
|
||||
|
||||
if (outputName.isPresent()) {
|
||||
args.add("-H:Name=" + outputName.get());
|
||||
}
|
||||
|
||||
args.add(mainClass.get());
|
||||
|
||||
spec.executable(getExecutable(graalVersion.get()));
|
||||
spec.executable(getExecutable());
|
||||
spec.args(args);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getGroup() {
|
||||
return GradleGraalPlugin.TASK_GROUP;
|
||||
private File maybeCreateOutputDirectory() throws IOException {
|
||||
File directory = getOutputFile().get().getAsFile().getParentFile();
|
||||
Files.createDirectories(directory.toPath());
|
||||
return directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getDescription() {
|
||||
return "Runs GraalVM's native-image command with configured options and parameters.";
|
||||
}
|
||||
|
||||
private String getOutputDirectory() {
|
||||
File outputDirectory = getProject().getProjectDir().toPath().resolve(Paths.get("build", "graal")).toFile();
|
||||
|
||||
if (!(outputDirectory.mkdirs() || outputDirectory.exists())) {
|
||||
throw new IllegalStateException(
|
||||
"Output directory does not exist and cannot be created: " + outputDirectory);
|
||||
}
|
||||
|
||||
return outputDirectory.getAbsolutePath();
|
||||
}
|
||||
|
||||
private String getExecutable(String version) {
|
||||
return GradleGraalPlugin.CACHE_DIR
|
||||
.resolve(Paths.get(version, "graalvm-ce-" + version))
|
||||
private String getExecutable() {
|
||||
return cacheDir.get()
|
||||
.resolve(Paths.get(graalVersion.get(), "graalvm-ce-" + graalVersion.get()))
|
||||
.resolve(getArchitectureSpecifiedBinaryPath())
|
||||
.toFile()
|
||||
.getAbsolutePath();
|
||||
}
|
||||
|
||||
private String generateClasspathArgument() {
|
||||
Set<File> classpath = new LinkedHashSet<>();
|
||||
classpath.addAll(getProject().getConfigurations().getByName("runtimeClasspath").getFiles());
|
||||
classpath.addAll(getProject().getTasks().getByName("jar").getOutputs().getFiles().getFiles());
|
||||
Set<File> classpathArgument = new LinkedHashSet<>();
|
||||
|
||||
return classpath.stream()
|
||||
.map(File::getAbsolutePath)
|
||||
.collect(Collectors.joining(":"));
|
||||
}
|
||||
classpathArgument.addAll(classpath.get().getFiles());
|
||||
classpathArgument.add(jarFile.getAsFile().get());
|
||||
|
||||
@SuppressWarnings("checkstyle:hiddenfield")
|
||||
public final void configure(Provider<String> mainClass, Provider<String> outputName,
|
||||
Provider<String> graalVersion) {
|
||||
this.mainClass = mainClass;
|
||||
this.outputName = outputName;
|
||||
this.graalVersion = graalVersion;
|
||||
return classpathArgument.stream().map(File::getAbsolutePath).collect(Collectors.joining(":"));
|
||||
}
|
||||
|
||||
private Path getArchitectureSpecifiedBinaryPath() {
|
||||
|
@ -120,4 +114,66 @@ public class NativeImageTask extends DefaultTask {
|
|||
}
|
||||
}
|
||||
|
||||
private long fileSizeMegabytes(RegularFile regularFile) {
|
||||
try {
|
||||
return Files.size(regularFile.getAsFile().toPath()) / (1000 * 1000);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Input
|
||||
public final Provider<String> getMainClass() {
|
||||
return mainClass;
|
||||
}
|
||||
|
||||
public final void setMainClass(Provider<String> provider) {
|
||||
mainClass.set(provider);
|
||||
}
|
||||
|
||||
@Input
|
||||
public final Provider<String> getOutputName() {
|
||||
return outputName;
|
||||
}
|
||||
|
||||
@Input
|
||||
public final Provider<String> getGraalVersion() {
|
||||
return graalVersion;
|
||||
}
|
||||
|
||||
public final void setGraalVersion(Provider<String> provider) {
|
||||
graalVersion.set(provider);
|
||||
}
|
||||
|
||||
@InputFiles
|
||||
@Classpath
|
||||
public final Provider<Configuration> getClasspath() {
|
||||
return classpath;
|
||||
}
|
||||
|
||||
public final void setClasspath(Provider<Configuration> provider) {
|
||||
classpath.set(provider);
|
||||
}
|
||||
|
||||
@InputFile
|
||||
public final Provider<RegularFile> getJarFiles() {
|
||||
return jarFile;
|
||||
}
|
||||
|
||||
public final void setJarFile(Provider<File> provider) {
|
||||
jarFile.set(getProject().getLayout().file(provider));
|
||||
}
|
||||
|
||||
@OutputFile
|
||||
public final Provider<RegularFile> getOutputFile() {
|
||||
return outputFile;
|
||||
}
|
||||
|
||||
public final void setOutputName(Provider<String> provider) {
|
||||
outputName.set(provider);
|
||||
}
|
||||
|
||||
final void setCacheDir(Path value) {
|
||||
cacheDir.set(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
implementation-class=com.palantir.gradle.graal.GradleGraalPlugin
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* (c) Copyright 2018 Palantir Technologies Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 com.palantir.gradle.graal
|
||||
|
||||
import nebula.test.IntegrationSpec
|
||||
import nebula.test.functional.ExecutionResult
|
||||
|
||||
class GradleGraalEndToEndSpec extends IntegrationSpec {
|
||||
|
||||
def 'test default version nativeImage'() {
|
||||
setup:
|
||||
directory("src/main/java/com/palantir/test")
|
||||
file("src/main/java/com/palantir/test/Main.java") << '''
|
||||
package com.palantir.test;
|
||||
|
||||
public final class Main {
|
||||
public static final void main(String[] args) {
|
||||
System.out.println("hello, world!");
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
buildFile << '''
|
||||
apply plugin: 'com.palantir.graal'
|
||||
|
||||
graal {
|
||||
mainClass 'com.palantir.test.Main'
|
||||
outputName 'hello-world'
|
||||
graalVersion '1.0.0-rc5'
|
||||
}
|
||||
'''
|
||||
|
||||
when:
|
||||
ExecutionResult result = runTasksSuccessfully('nativeImage') // note, this accesses your real ~/.gradle cache
|
||||
println "Gradle Standard Out:\n" + result.standardOutput
|
||||
println "Gradle Standard Error:\n" + result.standardError
|
||||
File output = new File(getProjectDir(), "build/graal/hello-world");
|
||||
|
||||
then:
|
||||
output.exists()
|
||||
output.getAbsolutePath().execute().text.equals("hello, world!\n")
|
||||
|
||||
when:
|
||||
ExecutionResult result2 = runTasksSuccessfully('nativeImage')
|
||||
|
||||
then:
|
||||
result2.wasUpToDate(':nativeImage')
|
||||
|
||||
when:
|
||||
new File(getProjectDir(), "src/main/java/com/palantir/test/Main.java").text = '''
|
||||
package com.palantir.test;
|
||||
|
||||
public final class Main {
|
||||
public static final void main(String[] args) {
|
||||
System.out.println("hello, world (modified)!");
|
||||
}
|
||||
}
|
||||
'''
|
||||
ExecutionResult result3 = runTasksSuccessfully('nativeImage')
|
||||
|
||||
then:
|
||||
println result3.standardOutput
|
||||
!result3.wasUpToDate(':nativeImage')
|
||||
output.getAbsolutePath().execute().text.equals("hello, world (modified)!\n")
|
||||
}
|
||||
}
|
|
@ -18,12 +18,20 @@ package com.palantir.gradle.graal
|
|||
|
||||
import nebula.test.IntegrationSpec
|
||||
import nebula.test.functional.ExecutionResult
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.Rule
|
||||
|
||||
class GradleGraalPluginIntegrationSpec extends IntegrationSpec {
|
||||
def 'test default version nativeImage'() {
|
||||
setup:
|
||||
new File(getProjectDir(), "src/main/java/com/palantir/test").mkdirs()
|
||||
new File(getProjectDir(), "src/main/java/com/palantir/test/Main.java") << '''
|
||||
|
||||
@Rule MockWebServer server = new MockWebServer()
|
||||
String fakeBaseUrl
|
||||
|
||||
def setup() {
|
||||
fakeBaseUrl = String.format("http://localhost:%s/oracle/graal/releases/download/", server.getPort())
|
||||
|
||||
directory("src/main/java/com/palantir/test")
|
||||
file("src/main/java/com/palantir/test/Main.java") << '''
|
||||
package com.palantir.test;
|
||||
|
||||
public final class Main {
|
||||
|
@ -33,26 +41,53 @@ class GradleGraalPluginIntegrationSpec extends IntegrationSpec {
|
|||
}
|
||||
'''
|
||||
|
||||
buildFile << '''
|
||||
apply plugin: 'java'
|
||||
file('gradle.properties') << "com.palantir.graal.cache.dir=${getProjectDir().toPath().resolve("cacheDir").toAbsolutePath()}"
|
||||
}
|
||||
|
||||
def 'allows specifying different graal version'() {
|
||||
setup:
|
||||
buildFile << """
|
||||
apply plugin: 'com.palantir.graal'
|
||||
|
||||
graal {
|
||||
mainClass 'com.palantir.test.Main'
|
||||
outputName 'hello-world'
|
||||
graalVersion '1.0.0-rc3'
|
||||
downloadBaseUrl '${fakeBaseUrl}'
|
||||
}
|
||||
'''
|
||||
"""
|
||||
server.enqueue(new MockResponse().setBody('<<tgz>>'));
|
||||
|
||||
when:
|
||||
ExecutionResult result = runTasks('nativeImage')
|
||||
// capture output from Gradle runs
|
||||
println "Gradle Standard Out:\n" + result.standardOutput
|
||||
println "Gradle Standard Error:\n" + result.standardError
|
||||
File output = new File(getProjectDir(), "build/graal/hello-world");
|
||||
ExecutionResult result = runTasksSuccessfully('downloadGraalTooling')
|
||||
|
||||
then:
|
||||
result.success
|
||||
output.exists()
|
||||
output.getAbsolutePath().execute().text.equals("hello, world!\n")
|
||||
println result.getStandardOutput()
|
||||
result.wasExecuted(':downloadGraalTooling')
|
||||
!result.wasUpToDate(':downloadGraalTooling')
|
||||
!result.wasSkipped(':downloadGraalTooling')
|
||||
|
||||
server.takeRequest().requestUrl.toString() =~ "http://localhost:${server.port}" +
|
||||
"/oracle/graal/releases/download//vm-1.0.0-rc3/graalvm-ce-1.0.0-rc3-(macos|linux)-amd64.tar.gz"
|
||||
|
||||
file("cacheDir/1.0.0-rc3/graalvm-ce-1.0.0-rc3-amd64.tar.gz").text == '<<tgz>>'
|
||||
}
|
||||
|
||||
def 'downloadGraalTooling behaves incrementally'() {
|
||||
setup:
|
||||
buildFile << """
|
||||
apply plugin: 'com.palantir.graal'
|
||||
|
||||
graal {
|
||||
downloadBaseUrl '${fakeBaseUrl}'
|
||||
}
|
||||
"""
|
||||
server.enqueue(new MockResponse().setBody('<<tgz>>'));
|
||||
|
||||
when:
|
||||
ExecutionResult result1 = runTasksSuccessfully('downloadGraalTooling')
|
||||
ExecutionResult result2 = runTasksSuccessfully('downloadGraalTooling')
|
||||
|
||||
then:
|
||||
result1.wasSkipped(':downloadGraalTooling') == false
|
||||
result2.wasSkipped(':downloadGraalTooling') == true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,6 @@ package com.palantir.gradle.graal
|
|||
|
||||
import nebula.test.PluginProjectSpec
|
||||
|
||||
/**
|
||||
* Tests for {@link GradleGraalPlugin}.
|
||||
*/
|
||||
class GradleGraalPluginProjectSpec extends PluginProjectSpec {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
com.netflix.nebula:nebula-test = 6.7.1
|
||||
com.squareup.okhttp3:* = 3.11.0
|
||||
|
|
Loading…
Reference in a new issue