diff --git a/README.md b/README.md index 969367c..4985a31 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,10 @@ installing engines to make eshost automatically find the installed engines. | Engine | Binary Names | `darwin-x64` | `darwin-arm64` | `linux-ia32` | `linux-x64` | `linux-arm64` | `win32-ia32` | `win32-x64` | | ------------------ | -------------------------------- | ------------ | -------------- | ------------ | ----------- | ------------- | ------------ | ----------- | -| [Chakra][] | `ch`, `chakra` | ✅ | | | ✅ | | ✅ | ✅ | -| [engine262][] | `engine262` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [GraalJS][] | `graaljs` | ✅ | ✅ | | ✅ | ✅ | | ✅ | +| [Boa][] | `boa`, | ✅ | | | ✅ | | | ✅ | +| [Chakra][] | `ch`, `chakra` | ✅ | | | ✅ | | ✅ | ✅ | +| [engine262][] | `engine262` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [GraalJS][] | `graaljs` | ✅ | ✅ | | ✅ | ✅ | | ✅ | | [Hermes][] | `hermes` | ✅ | ✅ | | | | | ✅ | | [LibJS][] | `serenity-js` | ✅ | ✅ | | ✅ | | | | | [JavaScriptCore][] | `jsc`, `javascriptcore` | ✅ | ✅ | | ✅ | | | ✅ | @@ -50,6 +51,7 @@ installing engines to make eshost automatically find the installed engines. Some binaries may be exposed as batch/shell scripts to properly handling shared library loading. Some binaries on 64-bit systems may be natively 32-bit. +[Boa]: https://boajs.dev/ [eshost-cli]: https://github.com/bterlson/eshost-cli [Chakra]: https://github.com/microsoft/chakracore [engine262]: https://engine262.js.org diff --git a/src/engines/boa.js b/src/engines/boa.js new file mode 100644 index 0000000..289db0d --- /dev/null +++ b/src/engines/boa.js @@ -0,0 +1,81 @@ +'use strict'; + +const assert = require('assert'); +const execa = require('execa'); +const { join } = require('path'); +const fetch = require('node-fetch'); +const { copyFileSync, chmodSync, existsSync, mkdirSync } = require('fs'); +const Installer = require('../installer'); +const { platform } = require('../common'); + +const binaryName = platform.startsWith('win') ? 'boa.exe' : 'boa'; + +function getFilename() { + switch (platform) { + case 'darwin-x64': + return 'boa-macos-amd64'; + case 'linux-x64': + return 'boa-linux-amd64'; + case 'win32-x64': + return 'boa-windows-amd64'; + default: + throw new Error(`No Boa builds available for ${platform}`); + } +} + +class BoaInstaller extends Installer { + constructor(...args) { + super(...args); + this.binPath = undefined; + } + + static resolveVersion(version) { + if (version === 'latest') { + return fetch('https://api.github.com/repos/boa-dev/boa/releases/latest') + .then((r) => r.json()) + .then((r) => r.tag_name); + } + return version; + } + + getDownloadURL(version) { + return `https://github.com/boa-dev/boa/releases/download/${version}/${getFilename()}`; + } + + async extract() { + // The file is not zipped so we don't need to do any extraction here + // The file doesn't seem to be executable so we need to set it manually + chmodSync(this.downloadPath, '755'); + // Windows will fail if the extractedPath doesn't exist + if (!existsSync(this.extractedPath)) { + mkdirSync(this.extractedPath); + } + return copyFileSync(this.downloadPath, join(this.extractedPath, binaryName)); + } + + async install() { + this.binPath = await this.registerBinary(binaryName); + } + + async test() { + const program = 'console.log("42");'; + const output = '42\nundefined'; + + assert.strictEqual( + (await execa(this.binPath, [], { input: program })).stdout, + output, + ); + } +} + +BoaInstaller.config = { + name: 'Boa', + id: 'boa', + supported: [ + 'linux-x64', + 'win32-x64', + 'darwin-x64', + ], +}; + +module.exports = BoaInstaller;