diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4afa0ff..bc65496 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,7 +6,86 @@ on: - main jobs: + build_linux: + name: ${{ matrix.os }} + runs-on: ${{ matrix.os }} + defaults: + run: + working-directory: ./packages/vector/ppx_vector + strategy: + matrix: + os: [ubuntu-18.04] + ocaml-compiler: + - 4.12.1 + + steps: + - uses: actions/checkout@v2 + + - name: Use OCaml ${{ matrix.ocaml-compiler}} + uses: ocaml/setup-ocaml@v2 + with: + ocaml-compiler: ${{ matrix.ocaml-compiler }} + + - name: Install deps + run: opam install . --deps-only --with-test + + - name: Build + run: opam exec -- dune build + + - name: Copy built PPX file + run: | + mv ./_build/default/bin/bin.exe ppx.exe + + - name: (only on release) Upload artifacts ${{ matrix.os }} + uses: actions/upload-artifact@master + with: + name: ${{ matrix.os }} + path: ./packages/vector/ppx_vector/ppx.exe + if-no-files-found: error + + build_macos: + name: ${{ matrix.os }} + runs-on: ${{ matrix.os }} + defaults: + run: + working-directory: ./packages/vector/ppx_vector + strategy: + matrix: + os: [macOS-latest] + ocaml-compiler: + - 4.12.1 + + steps: + - uses: actions/checkout@v2 + + - name: Use OCaml ${{ matrix.ocaml-compiler}} + uses: ocaml/setup-ocaml@v2 + with: + ocaml-compiler: ${{ matrix.ocaml-compiler }} + + - name: Install deps + run: opam install . --deps-only --with-test + + - name: Build + run: opam exec -- dune build + + - name: Copy built PPX file + run: | + mv ./_build/default/bin/bin.exe ppx.exe + + - name: ls + run: | + echo $(ls) + + - name: (only on release) Upload artifacts ${{ matrix.os }} + uses: actions/upload-artifact@master + with: + name: ${{ matrix.os }} + path: ./packages/vector/ppx_vector/ppx.exe + if-no-files-found: error + release: + needs: [build_linux, build_macos] name: Release runs-on: ubuntu-latest permissions: @@ -24,6 +103,27 @@ jobs: with: node-version: 14.x + - name: Download linux artifacts + if: success() + uses: actions/download-artifact@master + with: + name: ubuntu-18.04 + path: binaries/linux + + - name: Download macOS artifacts + if: success() + uses: actions/download-artifact@master + with: + name: macOS-latest + path: binaries/darwin + + - name: Move artifacts + if: success() + run: | + mkdir -p bin + mv binaries/linux/ppx.exe ./packages/vector/ppx-linux.exe + mv binaries/darwin/ppx.exe ./packages/vector/ppx-osx.exe + - name: Install Dependencies run: yarn install --immutable diff --git a/packages/vector/package.json b/packages/vector/package.json index 82e33e8..db36ba1 100644 --- a/packages/vector/package.json +++ b/packages/vector/package.json @@ -38,7 +38,8 @@ "clean": "rescript clean", "test": "node tests/vector_test.mjs | faucet", "test:watch": "yarn test || true && watchlist src tests -- yarn test", - "test:coverage": "c8 -r text -r lcov yarn test" + "test:coverage": "c8 -r text -r lcov yarn test", + "postinstall": "node ./postInstall.js" }, "files": [ "dist", diff --git a/packages/vector/postInstall.js b/packages/vector/postInstall.js new file mode 100644 index 0000000..fe2edbd --- /dev/null +++ b/packages/vector/postInstall.js @@ -0,0 +1,51 @@ +const path = require("path"); +const fs = require("fs"); + +const installMacLinuxBinary = (binary) => { + const source = path.join(__dirname, binary); + if (fs.existsSync(source)) { + // mac and linux support extension-less executables + // so just overwrite the shell script + const target = path.join(__dirname, "ppx"); + fs.renameSync(source, target); + + // The ppx should be executable in the bundle, but just in case + fs.chmodSync(target, 0777); + } else { + // assume we're in dev mode - nothing will break if the script + // isn't overwritten, it will just be slower + } +}; + +const installWindowsBinary = () => { + const source = path.join(__dirname, "ppx-windows.exe"); + if (fs.existsSync(source)) { + const target = path.join(__dirname, "ppx.exe"); + fs.renameSync(source, target); + + // windows scripts use a different file extension to executables + // so we delete the script to make sure windows uses the exe now + const windowsScript = path.join(__dirname, "ppx.cmd"); + fs.unlinkSync(windowsScript); + } else { + // assume we're in dev mode - nothing will break if the script + // isn't overwritten, it will just be slower + } +}; + +switch (process.platform) { + case "linux": + installMacLinuxBinary("ppx-linux.exe"); + break; + case "darwin": + installMacLinuxBinary("ppx-osx.exe"); + break; + case "win32": + installWindowsBinary(); + break; + default: + // This won't break the installation because the `ppx` shell script remains + // but that script will throw an error in this case anyway + console.warn(`No release available for "${process.platform}"`); + process.exit(1); +} diff --git a/packages/vector/ppx_vector/.gitignore b/packages/vector/ppx_vector/.gitignore new file mode 100644 index 0000000..e3ee242 --- /dev/null +++ b/packages/vector/ppx_vector/.gitignore @@ -0,0 +1,3 @@ +.vscode +_build +.merlin diff --git a/packages/vector/ppx_vector/.ocamlformat b/packages/vector/ppx_vector/.ocamlformat new file mode 100644 index 0000000..e69de29 diff --git a/packages/vector/ppx_vector/README.md b/packages/vector/ppx_vector/README.md new file mode 100644 index 0000000..d5686fc --- /dev/null +++ b/packages/vector/ppx_vector/README.md @@ -0,0 +1,22 @@ +# Ppx Vector + +## Install + +``` +yarn add rescript-vector +``` + +``` +// bsconfig.json + +"ppx-flags": [ + ..., + ["rescript-vector/ppx"] +], +``` + +## Example + +```rescript +let rv = %vec([1, 2, 3]) +``` diff --git a/packages/vector/ppx_vector/bin/bin.ml b/packages/vector/ppx_vector/bin/bin.ml new file mode 100644 index 0000000..491feba --- /dev/null +++ b/packages/vector/ppx_vector/bin/bin.ml @@ -0,0 +1 @@ +let () = Ppxlib.Driver.run_as_ppx_rewriter () diff --git a/packages/vector/ppx_vector/bin/dune b/packages/vector/ppx_vector/bin/dune new file mode 100644 index 0000000..cec8c38 --- /dev/null +++ b/packages/vector/ppx_vector/bin/dune @@ -0,0 +1,5 @@ +(executable + (package ppx_vector) + (name bin) + (public_name ppx_vector) + (libraries ppx_vector)) diff --git a/packages/vector/ppx_vector/dune b/packages/vector/ppx_vector/dune new file mode 100644 index 0000000..047f9fd --- /dev/null +++ b/packages/vector/ppx_vector/dune @@ -0,0 +1 @@ +(dirs src bin) diff --git a/packages/vector/ppx_vector/dune-project b/packages/vector/ppx_vector/dune-project new file mode 100644 index 0000000..594be3f --- /dev/null +++ b/packages/vector/ppx_vector/dune-project @@ -0,0 +1,2 @@ +(lang dune 3.0) +(name ppx_vector) diff --git a/packages/vector/ppx_vector/dune-workspace b/packages/vector/ppx_vector/dune-workspace new file mode 100644 index 0000000..a91e0a0 --- /dev/null +++ b/packages/vector/ppx_vector/dune-workspace @@ -0,0 +1,3 @@ +(lang dune 3.0) + +(env (release-static (flags (:standard -ccopt -static)))) diff --git a/packages/vector/ppx_vector/ppx b/packages/vector/ppx_vector/ppx new file mode 100755 index 0000000..c67eb06 --- /dev/null +++ b/packages/vector/ppx_vector/ppx @@ -0,0 +1,18 @@ +#!/usr/bin/env sh + +# Get the directory of the script to work from. +DIR=$(dirname "$0") + +if [ -f $DIR/_build/default/bin/bin.exe ]; then + # Use the dev build + $DIR/_build/default/bin/bin.exe $@ +elif [ "$(uname)" = "Darwin" ]; then + # Run the Mac PPX + $DIR/ppx-osx.exe $@ +elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then + # Run the Linux PPX + $DIR/ppx-linux.exe $@ +else + echo "No release available for '$(uname)'" + exit 1 +fi diff --git a/packages/vector/ppx_vector/ppx.cmd b/packages/vector/ppx_vector/ppx.cmd new file mode 100644 index 0000000..efdf45e --- /dev/null +++ b/packages/vector/ppx_vector/ppx.cmd @@ -0,0 +1,3 @@ +@echo off +REM no need to branch on OS here, it will only be used on windows +%~dp0\ppx-windows.exe %* diff --git a/packages/vector/ppx_vector/ppx_vector.opam b/packages/vector/ppx_vector/ppx_vector.opam new file mode 100644 index 0000000..d1eaca6 --- /dev/null +++ b/packages/vector/ppx_vector/ppx_vector.opam @@ -0,0 +1,36 @@ +opam-version: "2.0" +name: "ppx_vector" +version: "0.0.1" +synopsis: "PPX generates ReScript vector" +description: """ +PPX generates ReScript vector. +""" +maintainer: "Woonki Moon " +authors: "Woonki Moon " +license: "MIT" +homepage: "https://github.com/reason-seoul/rescript-collection" +bug-reports: "https://github.com/reason-seoul/rescript-collection/issues" +depends: [ + "ocaml" {>= "4.12.1"} + "dune" {>= "3.0"} + "ppxlib" {>= "0.22.0"} + "ppx_inline_test" + "ppx_expect" + "ppx_deriving" + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/reason-seoul/rescript-collection.git" diff --git a/packages/vector/ppx_vector/src/dune b/packages/vector/ppx_vector/src/dune new file mode 100644 index 0000000..ee63dad --- /dev/null +++ b/packages/vector/ppx_vector/src/dune @@ -0,0 +1,9 @@ +(library + (name ppx_vector) + (public_name ppx_vector) + (kind ppx_rewriter) + (libraries ppxlib str) + (flags + (:standard -w -9)) + (preprocess + (pps ppxlib.metaquot ppx_inline_test ppx_expect ppx_deriving.show))) diff --git a/packages/vector/ppx_vector/src/ppx_vector.ml b/packages/vector/ppx_vector/src/ppx_vector.ml new file mode 100644 index 0000000..aa4af91 --- /dev/null +++ b/packages/vector/ppx_vector/src/ppx_vector.ml @@ -0,0 +1,14 @@ +open Ppxlib + +let expand ~ctxt xs = + let loc = Expansion_context.Extension.extension_point_loc ctxt in + let arr = Ast_builder.Default.pexp_array ~loc xs in + [%expr Vector.fromArray [%e arr]] + +let extension = + Extension.V3.declare "vec" Extension.Context.expression + Ast_pattern.(single_expr_payload (pexp_array __)) + expand + +let rule = Ppxlib.Context_free.Rule.extension extension +let () = Ppxlib.Driver.register_transformation ~rules:[ rule ] "res_vector"