Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,68 @@ jobs:
# Headless display required because @vscode/test-electron launches
# the real Electron-based VS Code binary.
run: xvfb-run -a npm test

migration-assistant:
# Build pinned tree-sitter-rescript grammar consumed by the
# `.res → .affine` migration assistant (#57 Phase 2). The grammar
# is manifest-vendored (`editors/tree-sitter-rescript/package.json`)
# so this job exists to (a) verify the install script and pinned
# commit still build cleanly and (b) gate `tools/res-to-affine/`
# walker work that depends on the generated parser.
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v4
with:
node-version: "20"

- name: Install tree-sitter CLI
# npm install of tree-sitter-cli is the fast CI path (~5 s vs.
# ~5 min for `cargo install tree-sitter-cli`). The repo's
# preferred local path is cargo (see editors/tree-sitter-rescript/
# README.md) — both produce the same `tree-sitter` binary that
# the install script invokes via `command -v`. The version
# tracks `tree-sitter-rescript`'s package.json devDependency
# range.
run: npm install -g tree-sitter-cli@^0.25.0

- name: Build pinned tree-sitter-rescript grammar
# Direct script invocation rather than `just install-grammar` —
# GitHub Actions runners do not ship `just` preinstalled, and
# there is no other recipe used in this workflow that justifies
# adding a setup step for it. The justfile recipe still exists
# for local developer ergonomics; both call the same script.
run: ./editors/tree-sitter-rescript/scripts/install.sh

- name: Verify generated parser
# `tree-sitter generate` is supposed to drop src/parser.c into
# the cloned grammar. If it didn't, the install path is broken
# and Phase-2 walker work cannot proceed; fail loudly here
# rather than at the OCaml link step in a downstream PR.
run: |
test -f tools/vendor/tree-sitter-rescript/src/parser.c \
|| { echo "error: parser.c not produced by tree-sitter generate" >&2; exit 1; }
echo "parser.c size: $(wc -c < tools/vendor/tree-sitter-rescript/src/parser.c) bytes"

- name: Smoke-parse a sample .res file
# Sanity-check that the grammar actually parses a non-trivial
# ReScript source. Picks the existing res-to-affine test fixture
# so any drift in the pinned commit's syntactic surface area
# surfaces here rather than at walker-rule writing time.
run: |
shopt -s nullglob
fixtures=(tools/res-to-affine/test/fixtures/*.res)
if [ ${#fixtures[@]} -eq 0 ]; then
echo "no .res fixtures to smoke-parse; skipping"
exit 0
fi
tree-sitter parse \
--quiet \
"${fixtures[0]}" \
--paths tools/vendor/tree-sitter-rescript \
> /dev/null
echo "smoke-parsed: ${fixtures[0]}"
29 changes: 27 additions & 2 deletions editors/tree-sitter-rescript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,38 @@ snapshots, since AST shapes may shift.

## Install

From the repo root:

```sh
./scripts/install.sh
just install-grammar # justfile recipe
# or directly:
./editors/tree-sitter-rescript/scripts/install.sh
```

This writes a `tree-sitter-rescript` directory under `tools/vendor/`
(gitignored — same convention as the WASI adapter pinning), containing
the generated parser. Requires `git` and `tree-sitter` CLI on PATH.
the generated parser. Requires `git` and the `tree-sitter` CLI on PATH.

The `tree-sitter` CLI can be installed either way:

```sh
cargo install tree-sitter-cli # Rust-native, repo-preferred
npm install -g tree-sitter-cli # Node-based, also fine
```

CI installs via `npm` for speed (`tree-sitter-cli` from npm is a pre-built
binary, ~5 s install). The `cargo` path builds from source (~5 min on a
cold cache) and is the recommended local install because it keeps the
contributor toolchain centred on Rust rather than Node. The
`package.json` in this directory pins the version range; bump it in
sync when the upstream grammar pin moves.

## Continuous integration

The `migration-assistant` job in `.github/workflows/ci.yml` runs `just
install-grammar` on every PR, then smoke-parses
`tools/res-to-affine/test/fixtures/sample.res`. If the pinned commit
stops building cleanly, this job is the first signal.

## Why manifest, not copy

Expand Down
4 changes: 3 additions & 1 deletion editors/tree-sitter-rescript/scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ BUILD_DIR="${REPO_ROOT}/tools/vendor/tree-sitter-rescript"

if ! command -v tree-sitter >/dev/null 2>&1; then
echo "error: tree-sitter CLI not found on PATH" >&2
echo " install via: npm install -g tree-sitter-cli" >&2
echo " install via either:" >&2
echo " cargo install tree-sitter-cli (Rust-native, repo-preferred)" >&2
echo " npm install -g tree-sitter-cli (Node-based, also fine)" >&2
exit 2
fi

Expand Down
10 changes: 10 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ regen-idaptik-wasm:
dune exec affinescript -- tea-bridge -o ../../idaptik/public/assets/wasm/titlescreen.wasm
@echo "[AffineTEA] titlescreen.wasm regenerated"

# ── Tooling (manifest-driven dev deps) ────────────────────────────────────────

# Fetch + build the pinned tree-sitter-rescript grammar used by the
# `.res → .affine` migration assistant (#57 Phase 2). Output is written
# to `tools/vendor/tree-sitter-rescript/` (gitignored). Requires the
# `tree-sitter` CLI on PATH — install via `cargo install tree-sitter-cli`
# (Rust-native, repo-preferred) or `npm install -g tree-sitter-cli`.
install-grammar:
./editors/tree-sitter-rescript/scripts/install.sh

# ── Validation ────────────────────────────────────────────────────────────────

# Verify golden path end-to-end
Expand Down
Loading