Skip to content

Commit 53975eb

Browse files
committed
Rewrite rewatch in OCaml
# Conflicts: # .github/actions/setup-ocaml/action.yml
1 parent fb35986 commit 53975eb

338 files changed

Lines changed: 30004 additions & 302 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/actions/setup-ocaml/action.yml‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ runs:
8282
run: |
8383
dependency_flags_key="${DEPENDENCY_FLAGS//--/}"
8484
dependency_flags_key="${dependency_flags_key// /_}"
85-
key="$CACHE_PREFIX-$OS-3.9.0-$COMPILER-$dependency_flags_key-${{ hashFiles('*.opam') }}"
85+
dependency_hash="${{ hashFiles('*.opam', '.github/opam-repository/repo', '.github/opam-repository/packages/**') }}"
86+
key="$CACHE_PREFIX-$OS-3.9.0-$COMPILER-$dependency_flags_key-$dependency_hash"
8687
echo "value=${key//,/-}" >> "$GITHUB_OUTPUT"
8788
echo "setup-version=3.9.0" >> "$GITHUB_OUTPUT"
8889
@@ -104,6 +105,11 @@ runs:
104105
uses: ocaml/setup-ocaml@v3.9.0
105106
with:
106107
ocaml-compiler: ${{ inputs.compiler }}
108+
# Use the HTTP repository to prevent intermittent CI setup failures:
109+
# the Git-backed default can race with detached Git maintenance while
110+
# OPAM scans it (https://github.com/ocaml/opam/issues/7031).
111+
opam-repositories: |
112+
default: https://opam.ocaml.org
107113
opam-pin: false
108114
cache: false
109115

@@ -125,12 +131,21 @@ runs:
125131
env:
126132
DEPENDENCY_FLAGS: ${{ inputs.dependency-flags }}
127133
run: |
134+
opam repository add rescript-overrides "$GITHUB_WORKSPACE/.github/opam-repository"
128135
read -ra dependency_flags <<< "$DEPENDENCY_FLAGS"
136+
if [[ "$RUNNER_OS" == "Windows" ]]; then
137+
export AR=x86_64-w64-mingw32-ar
138+
export RANLIB=x86_64-w64-mingw32-ranlib
139+
export STRIP=x86_64-w64-mingw32-strip
140+
export NM=x86_64-w64-mingw32-nm
141+
export DLLTOOL=x86_64-w64-mingw32-dlltool
142+
export OBJDUMP=x86_64-w64-mingw32-objdump
143+
fi
129144
opam install . "${dependency_flags[@]}"
130145
131146
- name: Cache OPAM environment
132147
# Caches created by pull_request runs are scoped to that PR's merge ref
133-
# and cannot seed other PRs or branches. Only pushes create shared caches.
148+
# and cannot seed other PRs or branches, so only push runs save them.
134149
if: steps.cache.outputs.cache-hit != 'true' && github.event_name == 'push'
135150
uses: actions/cache/save@v6
136151
with:

‎.github/opam-repository/README.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# ReScript opam overrides
2+
3+
This repository contains narrowly scoped dependency fixes needed by CI before
4+
they are available from the main opam repository.
5+
6+
The Luv 0.5.14 override preserves the ARM64 musl compiler's
7+
`-mno-outline-atomics` requirement while building vendored libuv. Without it,
8+
the static executable fails to link because libuv refers to glibc's internal
9+
`__getauxval` symbol. The patch should be contributed upstream and this
10+
override removed once a fixed Luv release is available.
11+
12+
Luv 0.5.14 also vendors libuv 1.48.0. Evaluating and contributing an update to
13+
a current libuv 1.x release is a separate upstream follow-up; changing the
14+
vendored library is intentionally outside the OCaml rewatch port.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--- a/src/c/dune
2+
+++ b/src/c/dune
3+
@@ -82,8 +82,14 @@
4+
(action (progn
5+
(bash "cp -r vendor/configure/* vendor/libuv/")
6+
(chdir vendor/libuv (progn
7+
(bash
8+
- "sh configure --host `ocamlc -config | awk '/^host:/ {print $NF}'` \
9+
- 'CC=%{cc}' CFLAGS=-DNDEBUG --silent --enable-silent-rules")
10+
+ "architecture=`ocamlc -config-var architecture`
11+
+ c_compiler=`ocamlc -config-var c_compiler`
12+
+ extra_cflags=
13+
+ case \"$architecture:$c_compiler\" in
14+
+ arm64:*musl*) extra_cflags=-mno-outline-atomics ;;
15+
+ esac
16+
+ sh configure --host `ocamlc -config | awk '/^host:/ {print $NF}'` \
17+
+ 'CC=%{cc}' CFLAGS=\"-DNDEBUG $extra_cflags\" --silent --enable-silent-rules")
18+
(ignore-outputs (bash
19+
"$([ '%{os_type}' = Unix ] && echo %{make} || echo make) V=0 -j 4 \
20+
-o aclocal.m4 -o Makefile.in -o configure \
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
opam-version: "2.0"
2+
name: "luv"
3+
version: "0.5.14"
4+
synopsis: "Binding to libuv: cross-platform asynchronous I/O"
5+
description: """\
6+
Luv is a binding to libuv, the cross-platform C library that does
7+
asynchronous I/O in Node.js and runs its main loop.
8+
9+
Besides asynchronous I/O, libuv also supports multiprocessing and
10+
multithreading. Multiple event loops can be run in different threads. libuv also
11+
exposes a lot of other functionality, amounting to a full OS API, and an
12+
alternative to the standard module Unix."""
13+
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
14+
authors: "Anton Bachin <antonbachin@yahoo.com>"
15+
license: "MIT"
16+
homepage: "https://github.com/aantron/luv"
17+
doc: "https://aantron.github.io/luv"
18+
bug-reports: "https://github.com/aantron/luv/issues"
19+
depends: [
20+
"base-unix" {build}
21+
"ctypes" {>= "0.14.0"}
22+
"dune" {>= "2.7.0"}
23+
"ocaml" {>= "4.03.0"}
24+
"alcotest" {with-test & >= "0.8.1"}
25+
"base-unix" {with-test}
26+
"odoc" {with-doc & = "2.4.0"}
27+
]
28+
build: ["dune" "build" "-p" name "-j" jobs]
29+
patches: ["arm64-musl-outline-atomics.patch"]
30+
extra-files: [
31+
[
32+
"arm64-musl-outline-atomics.patch"
33+
"sha256=c15c4c4d34c9b545197c5160e19c69a128cc186b65a54e0e9a779c2543528a4f"
34+
]
35+
]
36+
dev-repo: "git+https://github.com/aantron/luv.git"
37+
url {
38+
src:
39+
"https://github.com/aantron/luv/releases/download/0.5.14/luv-0.5.14.tar.gz"
40+
checksum:
41+
"sha256=8e01b4a50c8876cdd98d8e245c0687c4dc4d883aed161ad9c5ace1fb1fdaae99"
42+
}

‎.github/opam-repository/repo‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
opam-version: "2.0"

‎.github/workflows/ci.yml‎

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,61 @@ jobs:
212212
run: echo "C:\Program Files\Git\bin" >> $GITHUB_PATH
213213
shell: bash
214214

215-
- name: Run rewatch tests
216-
run: ./rewatch/tests/suite.sh rewatch/target/release/rescript
215+
- name: Run OCaml rewatch parity tests
216+
timeout-minutes: 20
217+
run: |
218+
bash rewatch-ocaml/tests/check_rust_test_coverage.sh --require-complete
219+
bash rewatch-ocaml/tests/check_canonical_test_coverage.sh
220+
bash rewatch-ocaml/tests/check_config_acceptance.sh \
221+
packages/@rescript/${{ matrix.node-target }}/bin/rescript-rust.exe \
222+
packages/@rescript/${{ matrix.node-target }}/bin/rescript.exe
223+
bash rewatch-ocaml/tests/check_command_validation.sh \
224+
packages/@rescript/${{ matrix.node-target }}/bin/rescript-rust.exe \
225+
packages/@rescript/${{ matrix.node-target }}/bin/rescript.exe
226+
shell: bash
227+
228+
- name: Run OCaml rewatch interactive output tests
229+
# Terminal rendering depends on the host OS, not the CPU architecture.
230+
# Use the faster ARM runners for one Linux and one macOS check. Windows
231+
# does not provide a reliable native equivalent of the `script` PTY.
232+
if: matrix.node-target == 'linux-arm64' || matrix.node-target == 'darwin-arm64'
233+
timeout-minutes: 15
234+
run: |
235+
bash rewatch-ocaml/tests/check_interactive_output.sh \
236+
packages/@rescript/${{ matrix.node-target }}/bin/rescript-rust.exe \
237+
packages/@rescript/${{ matrix.node-target }}/bin/rescript.exe
238+
shell: bash
239+
240+
- name: Run OCaml rewatch verbose output tests
241+
timeout-minutes: 10
242+
run: |
243+
bash rewatch-ocaml/tests/check_verbose_output.sh \
244+
packages/@rescript/${{ matrix.node-target }}/bin/rescript-rust.exe \
245+
packages/@rescript/${{ matrix.node-target }}/bin/rescript.exe
246+
shell: bash
247+
248+
- name: Run OCaml rewatch unit tests
249+
timeout-minutes: 10
250+
run: |
251+
opam exec -- dune build tests/rewatch_ounit_tests/rewatch_ounit_tests_main.exe
252+
# Run the executable directly so a stuck test leaves live progress;
253+
# dune otherwise buffers the test output until the action exits.
254+
opam exec -- ./_build/default/tests/rewatch_ounit_tests/rewatch_ounit_tests_main.exe -runner sequential
255+
shell: bash
256+
257+
- name: Run OCaml rewatch focused integration tests
258+
timeout-minutes: 30
259+
run: |
260+
sh rewatch-ocaml/tests/run.sh packages/@rescript/${{ matrix.node-target }}/bin/rescript.exe
261+
shell: bash
262+
263+
- name: Run OCaml rewatch canonical tests
264+
run: ./rewatch/tests/suite.sh packages/@rescript/${{ matrix.node-target }}/bin/rescript.exe
265+
shell: bash
266+
267+
- name: Run Rust rewatch reference tests on Windows
268+
if: runner.os == 'Windows'
269+
run: ./rewatch/tests/suite.sh packages/@rescript/${{ matrix.node-target }}/bin/rescript-rust.exe
217270
shell: bash
218271

219272
- name: Run syntax benchmarks
@@ -623,6 +676,10 @@ jobs:
623676
shell: bash
624677
working-directory: rewatch/testrepo
625678

626-
- name: Run rewatch integration tests
679+
- name: Run installed default OCaml rewatch integration tests
627680
run: ./rewatch/tests/suite.sh rewatch/testrepo/node_modules/.bin/rescript
628681
shell: bash
682+
683+
- name: Run installed Rust rewatch reference integration tests
684+
run: ./rewatch/tests/suite.sh rewatch/testrepo/node_modules/.bin/rescript-rust
685+
shell: bash

‎Makefile‎

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ $(YARN_INSTALL_STAMP): $(YARN_INSTALL_SOURCES)
7979

8080
REWATCH_SOURCES = $(shell find rewatch/src -name '*.rs') rewatch/Cargo.toml rewatch/Cargo.lock rewatch/rust-toolchain.toml
8181
RESCRIPT_EXE = $(BIN_DIR)/rescript.exe
82+
RESCRIPT_RUST_EXE := $(BIN_DIR)/rescript-rust.exe
83+
PACKAGED_RUST_EXE := $(RESCRIPT_RUST_EXE)
8284
ifdef CI
8385
REWATCH_PROFILE := release
8486
REWATCH_CARGO_FLAGS := --release
@@ -88,22 +90,22 @@ else
8890
endif
8991
REWATCH_TARGET := rewatch/target/$(REWATCH_PROFILE)/rescript$(PLATFORM_EXE_EXT)
9092

91-
rewatch: $(RESCRIPT_EXE)
93+
rewatch: $(PACKAGED_RUST_EXE)
9294

93-
$(RESCRIPT_EXE): $(REWATCH_TARGET)
95+
$(PACKAGED_RUST_EXE): $(REWATCH_TARGET)
9496
$(call COPY_EXE,$<,$@)
9597

9698
$(REWATCH_TARGET): $(REWATCH_SOURCES)
9799
cargo build --manifest-path rewatch/Cargo.toml $(REWATCH_CARGO_FLAGS)
98100

99101
clean-rewatch:
100-
cargo clean --manifest-path rewatch/Cargo.toml && rm -rf rewatch/target && rm -f $(RESCRIPT_EXE)
102+
cargo clean --manifest-path rewatch/Cargo.toml && rm -rf rewatch/target && rm -f $(PACKAGED_RUST_EXE)
101103

102104
# Compiler
103105

104-
COMPILER_SOURCE_DIRS := compiler tests analysis tools
105-
COMPILER_SOURCES = $(shell find $(COMPILER_SOURCE_DIRS) -type f \( -name '*.ml' -o -name '*.mli' -o -name '*.dune' -o -name dune -o -name dune-project \))
106-
COMPILER_BIN_NAMES := bsc rescript-editor-analysis rescript-tools
106+
COMPILER_SOURCE_DIRS := compiler tests analysis tools rewatch-ocaml
107+
COMPILER_SOURCES = $(shell find $(COMPILER_SOURCE_DIRS) -type f \( -name '*.ml' -o -name '*.mli' -o -name '*.c' -o -name '*.h' -o -name '*.dune' -o -name dune -o -name dune-project \))
108+
COMPILER_BIN_NAMES := bsc rescript-editor-analysis rescript-tools rescript
107109
COMPILER_EXES := $(addsuffix .exe,$(addprefix $(BIN_DIR)/,$(COMPILER_BIN_NAMES)))
108110

109111
compiler: $(COMPILER_EXES)
@@ -279,9 +281,13 @@ COVERAGE_TEST_ENV := BISECT_FILE=$(COVERAGE_BISECT_PREFIX) BISECT_SILENT=YES
279281
.PHONY: coverage-build
280282
coverage-build: | $(YARN_INSTALL_STAMP)
281283
dune build --instrument-with bisect_ppx
282-
@$(foreach bin,$(COMPILER_BIN_NAMES), \
284+
@$(foreach bin,$(filter-out rescript,$(COMPILER_BIN_NAMES)), \
283285
cp $(DUNE_BIN_DIR)/$(bin)$(PLATFORM_EXE_EXT) $(BIN_DIR)/$(bin).exe && \
284286
chmod 755 $(BIN_DIR)/$(bin).exe;)
287+
ifneq ($(OS),Windows_NT)
288+
cp _build/default/rewatch-ocaml/rescript_ocaml.exe $(RESCRIPT_EXE)
289+
chmod 755 $(RESCRIPT_EXE)
290+
endif
285291

286292
.PHONY: coverage-prepare
287293
coverage-prepare: clean-coverage coverage-build

0 commit comments

Comments
 (0)