[fix] isolate REPL behind a build tag so the core compiles for js/wasm (LET-30)#169
[fix] isolate REPL behind a build tag so the core compiles for js/wasm (LET-30)#169vt128 wants to merge 3 commits into
Conversation
The interactive Machine.REPL() imported go.starlark.net/repl, which pulls in github.com/chzyer/readline — a terminal library that does not compile for GOOS=js. Because run.go is always compiled, importing it there forced chzyer/readline into every consumer's build and made the whole starlet package fail to cross-compile for js/wasm (e.g. a browser WASM playground), even though no js code uses the REPL. Move REPL() out of run.go into build-tagged files: - run_repl.go (//go:build !js): the real REPL + the go.starlark.net/repl import — unchanged behavior on linux/macos/windows. - run_repl_js.go (//go:build js): a no-op stub keeping the API present so consumer code referencing REPL still compiles for wasm. readline stays in go.mod (the non-js REPL still needs it) but is no longer in the js import graph: `GOOS=js GOARCH=wasm go list -deps .` no longer shows readline/repl, and the package now cross-compiles for js/wasm. Test-first: TestBuildsForJSWASM cross-compiles the package for js/wasm and fails on the old code (chzyer/readline undefined symbols). Requirement: LET-30. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 8 |
| Duplication | 0 |
🟢 Coverage 100.00% diff coverage · +0.00% coverage variation
Metric Results Coverage variation ✅ +0.00% coverage variation (-1.00%) Diff coverage ✅ 100.00% diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (5de5dbf) 7773 7357 94.65% Head commit (d91a3cd) 7773 (+0) 7357 (+0) 94.65% (+0.00%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#169) 6 6 100.00% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #169 +/- ##
=======================================
Coverage 93.44% 93.44%
=======================================
Files 49 50 +1
Lines 6222 6222
=======================================
Hits 5814 5814
Misses 259 259
Partials 149 149 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
What
Machine.REPL()(inrun.go, always compiled) importsgo.starlark.net/repl, which transitively pulls ingithub.com/chzyer/readline— a terminal library that does not compile forGOOS=js(it referencesState,ClearScreen,GetScreenWidth, … which don't exist on js).Because
run.gois part of the always-compiled core, this forcedchzyer/readlineinto every consumer's build and made the wholestarletpackage fail to cross-compile forjs/wasm— even though no js code path uses the REPL. This blocks, for example, a browser WASM playground that runs starlet's pure modules (json/regex/serial/…) client-side.The root cause is upstream-rooted (
go.starlark.net/repl→readline), but the right place to contain it is at our boundary: an interactive terminal REPL is meaningless in a browser, so it shouldn't drag a terminal dependency into the js build.Fix — build-tag isolation (no fork, no upstream change, no behavior change off-js)
Move
REPL()out ofrun.gointo two build-tagged files:run.goreplimport + theREPL()methodrun_repl.go//go:build !jsREPL()+import "go.starlark.net/repl"run_repl_js.go//go:build jsREPL()(keeps the API present so consumer code still compiles for wasm)run_repl.gois compiled → REPL andreadlinebehave exactly as before.run_repl.gois excluded by!js→repl/readlineare never in the import graph → the package cross-compiles for js/wasm.chzyer/readlinestays ingo.mod(the non-js REPL still needs it) but is no longer compiled for js —GOOS=js GOARCH=wasm go list -deps .no longer listsreadline/repl.Test-first
TestBuildsForJSWASMcross-compiles the package withGOOS=js GOARCH=wasm go build .and asserts success. It fails on the old code (readline undefined-symbol errors) and passes after the fix — a regression guard against re-importing a terminal dependency into the core.Verification
go test -race -count=2 ./...,go vet,gofmt -lclean, and Dockergolang:1.19 go test -raceall green (the new test cross-builds for js under go1.19 too). ExistingTestMachine_REPL_OK/Errorstill pass (real REPL on the native build).Why a PR if "don't merge"
This surfaced while proving a WASM playground for the Star* ecosystem site is feasible (it is — starlet runs in the browser after this fix). Flagging the portability issue + approach for review before merging.
Requirement: LET-30