From 9eb1e37e948194af8faab6a036a80846102da545 Mon Sep 17 00:00:00 2001
From: Dmitry Spikhalskiy <dmitry@spikhalskiy.com>
Date: Wed, 16 Mar 2022 21:59:17 -0400
Subject: [PATCH] Support for Graal Dev builds

Issue #374
---
 .../gradle/graal/DownloadGraalTask.java       | 15 +++++------
 .../gradle/graal/ExtractGraalTask.java        | 25 +++++++++++--------
 .../palantir/gradle/graal/GraalExtension.java | 18 ++++++++++---
 .../gradle/graal/GraalVersionUtil.java        | 13 ++++++++++
 4 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/src/main/java/com/palantir/gradle/graal/DownloadGraalTask.java b/src/main/java/com/palantir/gradle/graal/DownloadGraalTask.java
index 2990433c9..83bfcfda3 100644
--- a/src/main/java/com/palantir/gradle/graal/DownloadGraalTask.java
+++ b/src/main/java/com/palantir/gradle/graal/DownloadGraalTask.java
@@ -36,6 +36,8 @@ public class DownloadGraalTask extends DefaultTask {
     // RC versions don't have a windows variant, so no [ext] is needed
     private static final String ARTIFACT_PATTERN_RC_VERSION =
             "[url]/vm-[version]/graalvm-ce-[javaVersion]-[version]-[os]-[arch].tar.gz";
+    private static final String ARTIFACT_PATTERN_DEV_VERSION =
+            "[url]/[version]/graalvm-ce-[javaVersion]-[os]-[arch]-dev.[ext]";
     private static final String ARTIFACT_PATTERN_RELEASE_VERSION =
             "[url]/vm-[version]/graalvm-ce-[javaVersion]-[os]-[arch]-[version].[ext]";
 
@@ -57,8 +59,11 @@ public DownloadGraalTask() {
     public final void downloadGraal() throws IOException {
         Files.createDirectories(getArchive().get().getAsFile().toPath().getParent());
 
-        final String artifactPattern =
-                isGraalRcVersion() ? ARTIFACT_PATTERN_RC_VERSION : ARTIFACT_PATTERN_RELEASE_VERSION;
+        final String artifactPattern = GraalVersionUtil.isGraalRcVersion(graalVersion.get())
+                ? ARTIFACT_PATTERN_RC_VERSION
+                : (GraalVersionUtil.isGraalDevVersion(graalVersion.get())
+                        ? ARTIFACT_PATTERN_DEV_VERSION
+                        : ARTIFACT_PATTERN_RELEASE_VERSION);
 
         try (InputStream in = new URL(render(artifactPattern)).openStream()) {
             Files.copy(in, getArchive().get().getAsFile().toPath(), StandardCopyOption.REPLACE_EXISTING);
@@ -119,7 +124,7 @@ private String render(String pattern) {
     private String getOperatingSystem() {
         switch (Platform.operatingSystem()) {
             case MAC:
-                return isGraalRcVersion() ? "macos" : "darwin";
+                return GraalVersionUtil.isGraalRcVersion(graalVersion.get()) ? "macos" : "darwin";
             case LINUX:
                 return "linux";
             case WINDOWS:
@@ -150,10 +155,6 @@ private String getArchiveExtension() {
         }
     }
 
-    private boolean isGraalRcVersion() {
-        return graalVersion.get().startsWith("1.0.0-rc");
-    }
-
     final void setCacheDir(Path value) {
         cacheDir.set(value);
     }
diff --git a/src/main/java/com/palantir/gradle/graal/ExtractGraalTask.java b/src/main/java/com/palantir/gradle/graal/ExtractGraalTask.java
index edb178e20..e407a058b 100644
--- a/src/main/java/com/palantir/gradle/graal/ExtractGraalTask.java
+++ b/src/main/java/com/palantir/gradle/graal/ExtractGraalTask.java
@@ -84,22 +84,25 @@ public final void extractGraal() {
         } else {
             // ideally this would be a CopyTask, but through Gradle 4.9 CopyTask fails to correctly extract symlinks
             project.exec(spec -> {
-                spec.executable("tar");
-                spec.args("-xzf", inputArchiveFile.getAbsolutePath());
-                spec.workingDir(versionedCacheDir);
-            });
+                        spec.executable("tar");
+                        spec.args("-xzf", inputArchiveFile.getAbsolutePath());
+                        spec.workingDir(versionedCacheDir);
+                    })
+                    .assertNormalExitValue();
         }
 
         File nativeImageExecutable = getExecutable("native-image");
         if (!nativeImageExecutable.isFile()) {
             project.exec(spec -> {
-                File graalUpdateExecutable = getExecutable("gu");
-                if (!graalUpdateExecutable.isFile()) {
-                    throw new IllegalStateException("Failed to find Graal update binary: " + graalUpdateExecutable);
-                }
-                spec.executable(graalUpdateExecutable.getAbsolutePath());
-                spec.args("install", "native-image");
-            });
+                        File graalUpdateExecutable = getExecutable("gu");
+                        if (!graalUpdateExecutable.isFile()) {
+                            throw new IllegalStateException(
+                                    "Failed to find Graal update binary: " + graalUpdateExecutable);
+                        }
+                        spec.executable(graalUpdateExecutable.getAbsolutePath());
+                        spec.args("install", "native-image");
+                    })
+                    .assertNormalExitValue();
         }
     }
 
diff --git a/src/main/java/com/palantir/gradle/graal/GraalExtension.java b/src/main/java/com/palantir/gradle/graal/GraalExtension.java
index f2f39b637..fd3c7ecb5 100644
--- a/src/main/java/com/palantir/gradle/graal/GraalExtension.java
+++ b/src/main/java/com/palantir/gradle/graal/GraalExtension.java
@@ -40,9 +40,13 @@ public class GraalExtension {
             + "{version}\\{edition}\\VC\\Auxiliary\\"
             + "Build\\vcvars64.bat";
 
-    private static final String DEFAULT_DOWNLOAD_BASE_URL = "https://github.com/oracle/graal/releases/download/";
+    private static final String RELEASES_DOWNLOAD_POSTFIX = "/releases/download";
+    private static final String DEFAULT_DOWNLOAD_BASE_URL =
+            "https://github.com/oracle/graal" + RELEASES_DOWNLOAD_POSTFIX;
     private static final String DOWNLOAD_BASE_URL_GRAAL_19_3 =
-            "https://github.com/graalvm/graalvm-ce-builds/" + "releases/download/";
+            "https://github.com/graalvm/graalvm-ce-builds" + RELEASES_DOWNLOAD_POSTFIX;
+    private static final String DOWNLOAD_BASE_DEV =
+            "https://github.com/graalvm/graalvm-ce-dev-builds" + RELEASES_DOWNLOAD_POSTFIX;
     private static final String DEFAULT_GRAAL_VERSION = "20.2.0";
     private static final List<String> SUPPORTED_JAVA_VERSIONS = Arrays.asList("17", "16", "11", "8");
     private static final String DEFAULT_JAVA_VERSION = "8";
@@ -215,10 +219,14 @@ public final void option(String option) {
 
     public final Provider<String> getGraalDirectoryName() {
         return providerFactory.provider(() -> {
-            if (GraalVersionUtil.isGraalVersionGreaterOrEqualThan(graalVersion.get(), 19, 3)) {
+            if (GraalVersionUtil.isGraalDevVersion(graalVersion.get())) {
+                return "graalvm-ce-java" + javaVersion.get() + "-"
+                        + GraalVersionUtil.cutDevSignature(graalVersion.get());
+            } else if (GraalVersionUtil.isGraalVersionGreaterOrEqualThan(graalVersion.get(), 19, 3)) {
                 return "graalvm-ce-java" + javaVersion.get() + "-" + graalVersion.get();
+            } else {
+                return "graalvm-ce-" + graalVersion.get();
             }
-            return "graalvm-ce-" + graalVersion.get();
         });
     }
 
@@ -231,6 +239,8 @@ private String getDefaultDownloadBaseUrl() {
                 && !GraalVersionUtil.isGraalVersionGreaterOrEqualThan(graalVersion.get(), 21, 1)) {
             throw new GradleException(
                     "Unsupported GraalVM version " + graalVersion.get() + " for Java 16, needs >= 21.1.0.");
+        } else if (GraalVersionUtil.isGraalDevVersion(graalVersion.get())) {
+            return DOWNLOAD_BASE_DEV;
         } else if (GraalVersionUtil.isGraalVersionGreaterOrEqualThan(graalVersion.get(), 19, 3)) {
             return DOWNLOAD_BASE_URL_GRAAL_19_3;
         } else if (!javaVersion.get().equals("8")) {
diff --git a/src/main/java/com/palantir/gradle/graal/GraalVersionUtil.java b/src/main/java/com/palantir/gradle/graal/GraalVersionUtil.java
index bd55a3547..8224904b8 100644
--- a/src/main/java/com/palantir/gradle/graal/GraalVersionUtil.java
+++ b/src/main/java/com/palantir/gradle/graal/GraalVersionUtil.java
@@ -28,5 +28,18 @@ public static boolean isGraalVersionGreaterOrEqualThan(String graalVersion, int
         }
     }
 
+    public static boolean isGraalRcVersion(String graalVersion) {
+        return graalVersion.startsWith("1.0.0-rc");
+    }
+
+    public static boolean isGraalDevVersion(String graalVersion) {
+        return graalVersion.contains("-dev-");
+    }
+
+    // 22.1.0-dev-20220314_2252 -> 22.1.0-dev
+    public static String cutDevSignature(String graalVersion) {
+        return graalVersion.substring(0, graalVersion.indexOf("-dev") + 4);
+    }
+
     private GraalVersionUtil() {}
 }