From 849837d29b77c0c79c2c451c2c416b5d6137ba5e Mon Sep 17 00:00:00 2001 From: Ivo Horak Date: Tue, 2 Sep 2025 17:30:38 +0200 Subject: [PATCH 1/6] Add initial support for macos launcher --- .../python/embedding/tools/vfs/VFSUtils.java | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java b/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java index cb602fe..43ee5cf 100644 --- a/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java +++ b/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java @@ -175,8 +175,9 @@ public final class VFSUtils { """; private static final boolean IS_WINDOWS = System.getProperty("os.name").startsWith("Windows"); + private static final boolean IS_MAC = System.getProperty("os.name").startsWith("Mac"); - public static final String LAUNCHER_NAME = IS_WINDOWS ? "graalpy.exe" : "graalpy.sh"; + public static final String LAUNCHER_NAME = IS_WINDOWS ? "graalpy.exe" : IS_MAC ? "graalpy" : "graalpy.sh"; private static final String GRAALPY_MAIN_CLASS = "com.oracle.graal.python.shell.GraalPythonMain"; @@ -917,7 +918,42 @@ private static void generateLaunchers(Launcher launcherArgs, BuildToolLog log) t Path java = Paths.get(System.getProperty("java.home"), "bin", "java"); String classpath = String.join(File.pathSeparator, launcherArgs.computeClassPath()); String extraJavaOptions = String.join(" ", GraalPyRunner.getExtraJavaOptions()); - if (!IS_WINDOWS) { + if (IS_MAC) { + var script = formatMultiline(""" + import os, shutil, struct, venv + from pathlib import Path + adjusted = os.path.dirname(os.path.dirname(venv.__path__[0])) + vl = os.path.join(adjusted, 'venv', 'scripts', 'macos', 'graalpy') + tl = os.path.join(r'%s') + os.makedirs(Path(tl).parent.absolute(), exist_ok=True) + shutil.copy(vl, tl) + cmd = r'%s --enable-native-access=ALL-UNNAMED %s -classpath "%s" %s' + pyvenvcfg = os.path.join(os.path.dirname(tl), "pyvenv.cfg") + with open(pyvenvcfg, 'w', encoding='utf-8') as f: + f.write('venvlauncher_command = ') + f.write(cmd) + """, launcherArgs.launcherPath, java, extraJavaOptions, classpath, GRAALPY_MAIN_CLASS); + File tmp; + try { + tmp = File.createTempFile("create_launcher", ".py"); + } catch (IOException e) { + throw new IOException("failed to create tmp launcher", e); + } + System.out.println("Created temporary launcher file: " + tmp); + tmp.deleteOnExit(); + try (var wr = new FileWriter(tmp, StandardCharsets.UTF_8)) { + wr.write(script); + } catch (IOException e) { + throw new IOException(String.format("failed to write tmp launcher %s", tmp), e); + } + + try { + GraalPyRunner.run(classpath, log, tmp.getAbsolutePath()); + } catch (InterruptedException e) { + throw new IOException("failed to run Graalpy launcher", e); + } + } + else if (!IS_WINDOWS) { // we do not bother checking if it exists and has correct java home, since it is // simple // to regenerate the launcher From 15adac215b5a94dc2698f021ab8f24626a6d5564 Mon Sep 17 00:00:00 2001 From: Ivo Horak Date: Tue, 9 Sep 2025 11:40:39 +0200 Subject: [PATCH 2/6] Adjusting venv_launcher path --- .../java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java b/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java index 43ee5cf..70bc3d9 100644 --- a/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java +++ b/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java @@ -922,8 +922,7 @@ private static void generateLaunchers(Launcher launcherArgs, BuildToolLog log) t var script = formatMultiline(""" import os, shutil, struct, venv from pathlib import Path - adjusted = os.path.dirname(os.path.dirname(venv.__path__[0])) - vl = os.path.join(adjusted, 'venv', 'scripts', 'macos', 'graalpy') + vl = os.path.join(venv.__path__[0], 'scripts', 'macos', 'graalpy') tl = os.path.join(r'%s') os.makedirs(Path(tl).parent.absolute(), exist_ok=True) shutil.copy(vl, tl) From 20a5d36757c7e1c79acd621d8132d876f948a495 Mon Sep 17 00:00:00 2001 From: Ivo Horak Date: Fri, 12 Sep 2025 10:40:52 +0200 Subject: [PATCH 3/6] Merging generation of launchers for MacOS and Windows --- .../python/embedding/tools/vfs/VFSUtils.java | 51 ++++--------------- 1 file changed, 11 insertions(+), 40 deletions(-) diff --git a/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java b/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java index 70bc3d9..f04b8a8 100644 --- a/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java +++ b/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java @@ -895,9 +895,9 @@ private static Path ensureLauncher(Launcher launcherArgs, BuildToolLog log) thro } } - private static boolean checkWinLauncherJavaPath(Path venvCfg, Path java) { + private static boolean checkPyVenvCfgFile(Path pyVenvCfg, Path java) { try { - for (String line : Files.readAllLines(venvCfg)) { + for (String line : Files.readAllLines(pyVenvCfg)) { if (line.trim().startsWith("venvlauncher_command = " + java)) { return true; } @@ -918,11 +918,16 @@ private static void generateLaunchers(Launcher launcherArgs, BuildToolLog log) t Path java = Paths.get(System.getProperty("java.home"), "bin", "java"); String classpath = String.join(File.pathSeparator, launcherArgs.computeClassPath()); String extraJavaOptions = String.join(" ", GraalPyRunner.getExtraJavaOptions()); - if (IS_MAC) { + if (IS_MAC || IS_WINDOWS) { + if (Files.exists(launcherArgs.launcherPath) && checkPyVenvCfgFile(launcherArgs.launcherPath.getParent().resolve("pyvenv.cfg"), java)) { + return; + } + var launcherFolder = IS_WINDOWS ? "nt" : "macos"; + var launcherName = IS_WINDOWS ? "graalpy.exe" : "graalpy"; var script = formatMultiline(""" import os, shutil, struct, venv from pathlib import Path - vl = os.path.join(venv.__path__[0], 'scripts', 'macos', 'graalpy') + vl = os.path.join(venv.__path__[0], 'scripts', '%s', '%s') tl = os.path.join(r'%s') os.makedirs(Path(tl).parent.absolute(), exist_ok=True) shutil.copy(vl, tl) @@ -931,7 +936,7 @@ private static void generateLaunchers(Launcher launcherArgs, BuildToolLog log) t with open(pyvenvcfg, 'w', encoding='utf-8') as f: f.write('venvlauncher_command = ') f.write(cmd) - """, launcherArgs.launcherPath, java, extraJavaOptions, classpath, GRAALPY_MAIN_CLASS); + """, launcherFolder, launcherName, launcherArgs.launcherPath, java, extraJavaOptions, classpath, GRAALPY_MAIN_CLASS); File tmp; try { tmp = File.createTempFile("create_launcher", ".py"); @@ -952,7 +957,7 @@ with open(pyvenvcfg, 'w', encoding='utf-8') as f: throw new IOException("failed to run Graalpy launcher", e); } } - else if (!IS_WINDOWS) { + else { // we do not bother checking if it exists and has correct java home, since it is // simple // to regenerate the launcher @@ -969,40 +974,6 @@ else if (!IS_WINDOWS) { } catch (IOException e) { throw new IOException(String.format("failed to create launcher %s", launcherArgs.launcherPath), e); } - } else if (!Files.exists(launcherArgs.launcherPath) - || !checkWinLauncherJavaPath(launcherArgs.launcherPath.getParent().resolve("pyenv.cfg"), java)) { - // on windows, generate a venv launcher that executes the java command - var script = formatMultiline(""" - import os, shutil, struct, venv - from pathlib import Path - vl = os.path.join(venv.__path__[0], 'scripts', 'nt', 'graalpy.exe') - tl = os.path.join(r'%s') - os.makedirs(Path(tl).parent.absolute(), exist_ok=True) - shutil.copy(vl, tl) - cmd = r'%s --enable-native-access=ALL-UNNAMED %s -classpath "%s" %s' - pyvenvcfg = os.path.join(os.path.dirname(tl), "pyvenv.cfg") - with open(pyvenvcfg, 'w', encoding='utf-8') as f: - f.write('venvlauncher_command = ') - f.write(cmd) - """, launcherArgs.launcherPath, java, extraJavaOptions, classpath, GRAALPY_MAIN_CLASS); - File tmp; - try { - tmp = File.createTempFile("create_launcher", ".py"); - } catch (IOException e) { - throw new IOException("failed to create tmp launcher", e); - } - tmp.deleteOnExit(); - try (var wr = new FileWriter(tmp, StandardCharsets.UTF_8)) { - wr.write(script); - } catch (IOException e) { - throw new IOException(String.format("failed to write tmp launcher %s", tmp), e); - } - - try { - GraalPyRunner.run(classpath, log, tmp.getAbsolutePath()); - } catch (InterruptedException e) { - throw new IOException("failed to run Graalpy launcher", e); - } } } From 61ad4726bd99e9893157744aaa378d04d43d7baf Mon Sep 17 00:00:00 2001 From: ivohorak Date: Wed, 17 Sep 2025 12:02:14 +0200 Subject: [PATCH 4/6] Remove left out code --- .../java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java | 1 - 1 file changed, 1 deletion(-) diff --git a/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java b/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java index f04b8a8..001be06 100644 --- a/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java +++ b/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java @@ -943,7 +943,6 @@ with open(pyvenvcfg, 'w', encoding='utf-8') as f: } catch (IOException e) { throw new IOException("failed to create tmp launcher", e); } - System.out.println("Created temporary launcher file: " + tmp); tmp.deleteOnExit(); try (var wr = new FileWriter(tmp, StandardCharsets.UTF_8)) { wr.write(script); From 84df94ea1f8b17cdc5e5f2f230b4ea66d60cf647 Mon Sep 17 00:00:00 2001 From: ivohorak Date: Wed, 17 Sep 2025 13:57:49 +0200 Subject: [PATCH 5/6] fix: style issues --- .../org/graalvm/python/embedding/tools/vfs/VFSUtils.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java b/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java index 001be06..471ed52 100644 --- a/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java +++ b/org.graalvm.python.embedding.tools/src/main/java/org/graalvm/python/embedding/tools/vfs/VFSUtils.java @@ -919,7 +919,8 @@ private static void generateLaunchers(Launcher launcherArgs, BuildToolLog log) t String classpath = String.join(File.pathSeparator, launcherArgs.computeClassPath()); String extraJavaOptions = String.join(" ", GraalPyRunner.getExtraJavaOptions()); if (IS_MAC || IS_WINDOWS) { - if (Files.exists(launcherArgs.launcherPath) && checkPyVenvCfgFile(launcherArgs.launcherPath.getParent().resolve("pyvenv.cfg"), java)) { + if (Files.exists(launcherArgs.launcherPath) + && checkPyVenvCfgFile(launcherArgs.launcherPath.getParent().resolve("pyvenv.cfg"), java)) { return; } var launcherFolder = IS_WINDOWS ? "nt" : "macos"; @@ -936,7 +937,8 @@ private static void generateLaunchers(Launcher launcherArgs, BuildToolLog log) t with open(pyvenvcfg, 'w', encoding='utf-8') as f: f.write('venvlauncher_command = ') f.write(cmd) - """, launcherFolder, launcherName, launcherArgs.launcherPath, java, extraJavaOptions, classpath, GRAALPY_MAIN_CLASS); + """, launcherFolder, launcherName, launcherArgs.launcherPath, java, extraJavaOptions, classpath, + GRAALPY_MAIN_CLASS); File tmp; try { tmp = File.createTempFile("create_launcher", ".py"); @@ -955,8 +957,7 @@ with open(pyvenvcfg, 'w', encoding='utf-8') as f: } catch (InterruptedException e) { throw new IOException("failed to run Graalpy launcher", e); } - } - else { + } else { // we do not bother checking if it exists and has correct java home, since it is // simple // to regenerate the launcher From f3f3a8ccc7ca1d9c1f128906ac6d870678d73c7e Mon Sep 17 00:00:00 2001 From: stepan Date: Fri, 28 Nov 2025 11:46:56 +0100 Subject: [PATCH 6/6] Change version to 25.1.0-SNAPSHOT, update script to download the EA bundle --- pom.xml | 2 +- scripts/maven-bundle-url.sh | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index dfd49f7..e575913 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ - 26.0.0-SNAPSHOT + 25.1.0-SNAPSHOT UTF-8 UTF-8 ${revision} diff --git a/scripts/maven-bundle-url.sh b/scripts/maven-bundle-url.sh index f42085f..886ff8f 100755 --- a/scripts/maven-bundle-url.sh +++ b/scripts/maven-bundle-url.sh @@ -14,7 +14,6 @@ project_root="$( cd -P "$( dirname "$source" )/.." && pwd )" revision="$(mvn -f "${project_root}/pom.xml" help:evaluate -Dexpression=revision -q -DforceStdout)" revision="${revision%-SNAPSHOT}" # remove -SNAPSHOT -revision_quoted_for_jq="${revision//./\\\\.}" echo "Trying to find the release for revision: ${revision}" curl -sSL "https://api.github.com/repos/graalvm/oracle-graalvm-ea-builds/releases" -o github_releases.json @@ -23,12 +22,28 @@ echo "Downloaded releases JSON from GitHub, head:" head -n 20 github_releases.json echo "===========================================" -asset_url=$(cat github_releases.json \ - | jq -r 'map(select(.tag_name | test("'${revision_quoted_for_jq}'"))) | max_by(.published_at) | .assets[] | select(.name | test("^maven-resource-.*\\.zip$")) | .browser_download_url') +# Find the newest maven-resource-bundle ZIP whose name contains the desired revision. +# Scan all releases and their assets, guard against nulls, and pick the latest by published_at. +asset_url=$( + jq -r --arg rev "$revision" ' + [ .[] as $rel + | ($rel.assets // [])[] + | select( + (.name | startswith("maven-resource-bundle-")) and + (.name | contains($rev)) and + (.name | endswith(".zip")) + ) + | {published_at: $rel.published_at, url: .browser_download_url} + ] + | sort_by(.published_at) + | last? + | .url // empty + ' github_releases.json +) rm github_releases.json if [[ -z "$asset_url" ]]; then - echo "Failed to find a maven-resource-bundle zip" >&2 + echo "Failed to find a maven-resource-bundle zip for revision ${revision}" >&2 exit 1 fi echo $asset_url