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..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 @@ -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"; @@ -894,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; } @@ -917,30 +918,17 @@ 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) { - // we do not bother checking if it exists and has correct java home, since it is - // simple - // to regenerate the launcher - var script = formatMultiline(""" - #!/usr/bin/env bash - %s --enable-native-access=ALL-UNNAMED %s -classpath %s %s --python.Executable="$0" "$@" - """, java, extraJavaOptions, String.join(File.pathSeparator, classpath), GRAALPY_MAIN_CLASS); - try { - Files.writeString(launcherArgs.launcherPath, script); - var perms = Files.getPosixFilePermissions(launcherArgs.launcherPath); - perms.addAll(List.of(PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.GROUP_EXECUTE, - PosixFilePermission.OTHERS_EXECUTE)); - Files.setPosixFilePermissions(launcherArgs.launcherPath, perms); - } catch (IOException e) { - throw new IOException(String.format("failed to create launcher %s", launcherArgs.launcherPath), e); + if (IS_MAC || IS_WINDOWS) { + if (Files.exists(launcherArgs.launcherPath) + && checkPyVenvCfgFile(launcherArgs.launcherPath.getParent().resolve("pyvenv.cfg"), java)) { + return; } - } 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 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', 'nt', 'graalpy.exe') + 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) @@ -949,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) - """, 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"); @@ -968,6 +957,23 @@ with open(pyvenvcfg, 'w', encoding='utf-8') as f: } catch (InterruptedException e) { throw new IOException("failed to run Graalpy launcher", e); } + } else { + // we do not bother checking if it exists and has correct java home, since it is + // simple + // to regenerate the launcher + var script = formatMultiline(""" + #!/usr/bin/env bash + %s --enable-native-access=ALL-UNNAMED %s -classpath %s %s --python.Executable="$0" "$@" + """, java, extraJavaOptions, String.join(File.pathSeparator, classpath), GRAALPY_MAIN_CLASS); + try { + Files.writeString(launcherArgs.launcherPath, script); + var perms = Files.getPosixFilePermissions(launcherArgs.launcherPath); + perms.addAll(List.of(PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.GROUP_EXECUTE, + PosixFilePermission.OTHERS_EXECUTE)); + Files.setPosixFilePermissions(launcherArgs.launcherPath, perms); + } catch (IOException e) { + throw new IOException(String.format("failed to create launcher %s", launcherArgs.launcherPath), e); + } } } 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