diff --git a/src/engines/graaljs.js b/src/engines/graaljs.js index 1783af7..67b5f28 100644 --- a/src/engines/graaljs.js +++ b/src/engines/graaljs.js @@ -27,6 +27,42 @@ function getArchiveExtension() { return platform.startsWith('win') ? '.zip' : '.tar.gz'; } +class GraalJSVersion { + constructor(tagName) { + const match = /((\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?.*)$/.exec(tagName); + if (match == null) { + throw new Error(`Unable to parse version from tag name '${tagName}'`); + } + const [, fullVersion, ...parts] = match; + this.fullVersion = fullVersion; + this.numParts = parts.filter((s) => s !== undefined).map((s) => parseInt(s, 10)); + } + + static from(a) { + return a instanceof GraalJSVersion ? a : new GraalJSVersion(a); + } + + static compare(a, b) { + a = GraalJSVersion.from(a); + b = GraalJSVersion.from(b); + for (let i = 0; i < Math.max(a.numParts.length, b.numParts.length); i += 1) { + const cmp = Math.sign((a.numParts[i] || 0) - (b.numParts[i] || 0)); + if (cmp !== 0) { + return cmp; + } + } + return a.fullVersion.localeCompare(b.fullVersion); + } + + toString() { + return this.fullVersion; + } + + get majorVersion() { + return this.numParts[0]; + } +} + class GraalJSInstaller extends Installer { constructor(...args) { super(...args); @@ -38,10 +74,14 @@ class GraalJSInstaller extends Installer { if (version === 'latest') { const body = await fetch('https://api.github.com/repos/oracle/graaljs/releases') .then((r) => r.json()); - return body + const versions = body .filter((b) => !b.prerelease) - .sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime())[0] - .tag_name.slice(3); + .map((b) => GraalJSVersion.from(b.tag_name)) + .sort((a, b) => GraalJSVersion.compare(b, a)); + if (versions.length === 0) { + throw new Error('Could not find a release version'); + } + return versions[0].toString(); } return version; } @@ -60,12 +100,22 @@ class GraalJSInstaller extends Installer { async install() { const root = `graaljs-${this.version}-${getFilename()}`; + const libjsvm = GraalJSVersion.from(this.version).majorVersion >= 22; let graaljs; - if (platform === 'darwin-x64') { - graaljs = await this.registerAsset(`${root}/Contents/Home/bin/js`); - } else if (platform === 'win32-x64') { + if (platform.startsWith('darwin')) { + if (libjsvm) { + await this.registerAsset(`${root}/lib/libjsvm.dylib`); + } + graaljs = await this.registerAsset(`${root}/bin/js`); + } else if (platform.startsWith('win')) { + if (libjsvm) { + await this.registerAsset(`${root}/lib/jsvm.dll`); + } graaljs = await this.registerAsset(`${root}/bin/js.exe`); } else { + if (libjsvm) { + await this.registerAsset(`${root}/lib/libjsvm.so`); + } graaljs = await this.registerAsset(`${root}/bin/js`); } this.binPath = await this.registerScript('graaljs', `${graaljs}`); @@ -85,7 +135,9 @@ class GraalJSInstaller extends Installer { GraalJSInstaller.config = { name: 'GraalJS', id: 'graaljs', - supported: [], + supported: [ + 'linux-x64', 'win32-x64', 'darwin-x64', 'linux-arm64', 'darwin-arm64', + ], }; module.exports = GraalJSInstaller;