From cd31532f5fbcc7427cb6d087a301d1aa1489066a Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Jun 2026 00:20:11 +0000 Subject: [PATCH 1/6] Replace Makefiles with just Convert the three Makefiles (ext, web_ext/sseq_gui, web_ext/steenrod_calculator) to justfiles and update every caller. - ext/justfile: benchmark pattern rules become parametrized recipes (bench/bench-concurrent/fix-bench NAME) plus loop recipes over examples/benchmarks/*. The benchmark first line is expanded unquoted into an inner `bash -c`, reproducing the Makefile's quote-removal of the literal "" tokens. Also fixes the long-standing fix-benchmarks bug (bare BENCHMARKS instead of $(BENCHMARKS)). - web_ext/sseq_gui/justfile: WASM_UNWIND becomes a justfile variable (override via `just WASM_UNWIND=1 wasm`) driving if/else flag vars; test-wasm-unwind re-invokes the lib build with the override. - CI (.github/workflows/ext.yaml): swap `make -C ` for `just --working-directory --justfile /justfile ` and add an extractions/setup-just step to every job that runs recipes. - Nix: add pkgs.just to the root flake's devTools (subflakes inherit it) and swap make->just in the ext/sseq_gui app run scripts. - READMEs: update documented commands. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01DSAx1G1eMeCYPwNH7WNMVo --- .github/workflows/ext.yaml | 72 +++++++++----- ext/Makefile | 81 ---------------- ext/README.md | 18 ++-- ext/flake.nix | 12 +-- ext/justfile | 140 +++++++++++++++++++++++++++ flake.nix | 1 + web_ext/sseq_gui/Makefile | 96 ------------------ web_ext/sseq_gui/README.md | 10 +- web_ext/sseq_gui/flake.nix | 20 ++-- web_ext/sseq_gui/justfile | 102 +++++++++++++++++++ web_ext/steenrod_calculator/Makefile | 25 ----- web_ext/steenrod_calculator/justfile | 29 ++++++ 12 files changed, 351 insertions(+), 255 deletions(-) delete mode 100644 ext/Makefile create mode 100644 ext/justfile delete mode 100644 web_ext/sseq_gui/Makefile create mode 100644 web_ext/sseq_gui/justfile delete mode 100644 web_ext/steenrod_calculator/Makefile create mode 100644 web_ext/steenrod_calculator/justfile diff --git a/.github/workflows/ext.yaml b/.github/workflows/ext.yaml index 3ea2204896..f2cec5cc5b 100644 --- a/.github/workflows/ext.yaml +++ b/.github/workflows/ext.yaml @@ -20,6 +20,9 @@ jobs: - uses: actions/setup-python@v5 with: python-version: "3.9" + - uses: extractions/setup-just@v2 + with: + just-version: "1.34" - name: Install rustup id: rustup @@ -40,16 +43,16 @@ jobs: run: pip install pytest - name: Run ext tests - run: make -C ext test + run: just --working-directory ext --justfile ext/justfile test - name: Run ext examples - run: make -C ext benchmarks + run: just --working-directory ext --justfile ext/justfile benchmarks - name: Run ext examples (nassau) - run: make -C ext benchmarks-nassau + run: just --working-directory ext --justfile ext/justfile benchmarks-nassau - name: Run ext examples (concurrent) - run: make -C ext benchmarks-concurrent + run: just --working-directory ext --justfile ext/justfile benchmarks-concurrent - name: Benchmark executable size run: | @@ -65,6 +68,9 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: extractions/setup-just@v2 + with: + just-version: "1.34" - name: Install rustup id: rustup @@ -83,7 +89,7 @@ jobs: key: miri-${{ steps.rustup.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.*') }} - name: Run miri - run: make -C ext miri + run: just --working-directory ext --justfile ext/justfile miri lint: if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository }} @@ -95,6 +101,9 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: extractions/setup-just@v2 + with: + just-version: "1.34" - name: Install rustup id: rustup @@ -116,13 +125,13 @@ jobs: key: lint-${{ steps.rustup.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.*') }} - name: Run lint - run: make -C ext lint + run: just --working-directory ext --justfile ext/justfile lint - name: Lint sseq_gui - run: make -C web_ext/sseq_gui lint + run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile lint - name: Lint sseq_gui tests - run: make -C web_ext/sseq_gui lint-selenium + run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile lint-selenium # Build the wasm webserver with the default `panic=abort` configuration on # stable/beta. This is the compatibility build; the deployed artifact is @@ -143,6 +152,10 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: extractions/setup-just@v2 + with: + just-version: "1.34" + - name: Install rustup uses: dtolnay/rust-toolchain@v1 id: rustup @@ -164,16 +177,16 @@ jobs: run: sudo apt-get install binaryen - name: Setup build environment - run: make -C web_ext/sseq_gui setup-wasm + run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile setup-wasm - name: Lint sseq_gui wasm - run: make -C web_ext/sseq_gui lint-wasm + run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile lint-wasm - name: Test worker panic handling - run: make -C web_ext/sseq_gui test-wasm-js + run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile test-wasm-js - name: Build wasm - run: make -C web_ext/sseq_gui wasm + run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile wasm - name: Benchmark wasm size run: ls -l web_ext/sseq_gui/dist/sseq_gui_wasm_bg.wasm @@ -198,6 +211,10 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: extractions/setup-just@v2 + with: + just-version: "1.34" + - name: Install rustup uses: dtolnay/rust-toolchain@v1 id: rustup @@ -220,13 +237,13 @@ jobs: run: sudo apt-get install -y binaryen wabt - name: Setup build environment - run: make -C web_ext/sseq_gui setup-wasm + run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile setup-wasm - name: Build wasm (panic=unwind) - run: make -C web_ext/sseq_gui wasm WASM_UNWIND=1 + run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile WASM_UNWIND=1 wasm - name: Verify wasm unwinding - run: make -C web_ext/sseq_gui test-wasm-unwind + run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile test-wasm-unwind - name: Benchmark wasm size run: ls -l web_ext/sseq_gui/dist/sseq_gui_wasm_bg.wasm @@ -259,6 +276,9 @@ jobs: continue-on-error: ${{ matrix.toolchain != 'stable' }} steps: - uses: actions/checkout@v4 + - uses: extractions/setup-just@v2 + with: + just-version: "1.34" - name: Download webserver uses: actions/download-artifact@v4 @@ -295,20 +315,20 @@ jobs: - name: Test wasm run: | - make serve-wasm & - (sleep 1 && xvfb-run -a -s "-screen 0 1280x720x24" make selenium) + just serve-wasm & + (sleep 1 && xvfb-run -a -s "-screen 0 1280x720x24" just selenium) - name: Test local run: | cargo build && (target/debug/sseq_gui & - (sleep 1 && xvfb-run -a -s "-screen 0 1280x720x24" make selenium)) + (sleep 1 && xvfb-run -a -s "-screen 0 1280x720x24" just selenium)) - name: Test local concurrent run: | cargo build --features concurrent && (target/debug/sseq_gui & - (sleep 1 && xvfb-run -a -s "-screen 0 1280x720x24" make selenium)) + (sleep 1 && xvfb-run -a -s "-screen 0 1280x720x24" just selenium)) - name: Upload Artifact if: ${{ failure() }} @@ -332,6 +352,9 @@ jobs: continue-on-error: ${{ matrix.toolchain != 'stable' }} steps: - uses: actions/checkout@v4 + - uses: extractions/setup-just@v2 + with: + just-version: "1.34" - name: Install rustup id: rustup @@ -354,13 +377,13 @@ jobs: run: sudo apt-get install binaryen - name: Setup build environment - run: make -C web_ext/steenrod_calculator setup-wasm + run: just --working-directory web_ext/steenrod_calculator --justfile web_ext/steenrod_calculator/justfile setup-wasm - name: Lint sseq_gui wasm - run: make -C web_ext/steenrod_calculator lint + run: just --working-directory web_ext/steenrod_calculator --justfile web_ext/steenrod_calculator/justfile lint - name: Build wasm - run: make -C web_ext/steenrod_calculator + run: just --working-directory web_ext/steenrod_calculator --justfile web_ext/steenrod_calculator/justfile all - name: Benchmark wasm size run: ls -l web_ext/steenrod_calculator/dist/steenrod_calculator_wasm_bg.wasm @@ -387,6 +410,9 @@ jobs: continue-on-error: ${{ matrix.toolchain != 'stable' }} steps: - uses: actions/checkout@v4 + - uses: extractions/setup-just@v2 + with: + just-version: "1.34" - name: Install rustup id: rustup @@ -405,7 +431,7 @@ jobs: key: docs-${{ steps.rustup.outputs.rustc_hash }}-${{ hashFiles('ext/Cargo.*') }} - name: Generate docs - run: make -C ext docs + run: just --working-directory ext --justfile ext/justfile docs - name: Upload docs uses: actions/upload-artifact@v4 diff --git a/ext/Makefile b/ext/Makefile deleted file mode 100644 index 963bc530a6..0000000000 --- a/ext/Makefile +++ /dev/null @@ -1,81 +0,0 @@ -.PHONY: all test test-concurrent lint dummy - -all: - cargo build - -test: - cargo test --examples - cargo test --features concurrent --lib --tests --workspace - cargo test --features concurrent --doc --workspace - pytest - -lint: - cargo fmt --all -- --check - cargo clippy --workspace --no-default-features --profile test - cargo clippy --workspace --all-targets --profile test - cargo check --workspace --no-default-features --profile test - cargo check --workspace --all-targets --all-features --profile test - -docs: - # Prevent the cached crates.js from confusing the current run - rm target/doc/crates.js || true - RUSTDOCFLAGS="--html-in-header gh-pages/katex-header.html $(RUSTDOCFLAGS)" cargo rustdoc --examples --all-features - RUSTDOCFLAGS="--html-in-header gh-pages/katex-header.html $(RUSTDOCFLAGS)" cargo doc --all --no-deps --document-private-items --all-features - # Prevent the examples from showing up in the sidebar - echo "window.ALL_CRATES = [$$(ls crates/ | sed "s/.*/'&',/; s/-/_/g")'ext'];" > target/doc/crates.js - - -BENCHMARKS = $(filter-out examples/benchmarks/%-nassau, $(wildcard examples/benchmarks/*)) - -benchmarks: $(BENCHMARKS) -benchmarks-nassau: $(wildcard examples/benchmarks/*-nassau) - -fix-benchmarks: $(patsubst examples/benchmarks/%, examples/benchmarks/%-fixed, BENCHMARKS) -fix-benchmarks-nassau: $(patsubst examples/benchmarks/%, examples/benchmarks/%-fixed, $(wildcard examples/benchmarks/*-nassau)) - -benchmarks-concurrent: $(patsubst examples/benchmarks/%, examples/benchmarks/%-concurrent, $(BENCHMARKS)) - -examples/benchmarks/%-fixed: FILE = examples/benchmarks/$* -examples/benchmarks/%-fixed: dummy - (head -n 1 $(FILE) && bash -c "echo '' | cargo run --example $$(head -n 1 $(FILE))") > $@ - if diff --color $(FILE) $@; then \ - rm $@; \ - else \ - mv $@ $(FILE); \ - fi -examples/benchmarks/%-nassau-fixed: dummy - (head -n 1 $(FILE)-nassau && bash -c "echo '' | cargo run --features nassau --example $$(head -n 1 $(FILE)-nassau)") > $@ - if diff --color $(FILE)-nassau $@; then \ - rm $@; \ - else \ - mv $@ $(FILE)-nassau; \ - fi - - -examples/benchmarks/%: dummy - (head -n 1 $@ && bash -c "echo '' | cargo run --example $$(head -n 1 $@)") | diff --color $@ - - -examples/benchmarks/%-nassau: dummy - (head -n 1 $@ && bash -c "echo '' | cargo run --features nassau --example $$(head -n 1 $@)") | diff --color $@ - - -examples/benchmarks/%-concurrent: FILE = examples/benchmarks/$* -examples/benchmarks/%-concurrent: dummy - @{ \ - head -n 1 $(FILE); \ - timeout 30 bash -c "echo '' | cargo run --features concurrent --example $$(head -n 1 $(FILE))"; \ - ec=$$?; \ - } > output.txt; \ - if [ $$ec -eq 124 ]; then \ - echo "Timeout occurred, but treating as success."; \ - elif [ $$ec -eq 0 ]; then \ - diff --color output.txt $(FILE); \ - rm output.txt; \ - else \ - echo "Command failed with code $$ec."; \ - rm output.txt; \ - exit 1; \ - fi - -miri: - cargo miri test -p once - MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-disable-isolation" cargo miri test -p once --features concurrent diff --git a/ext/README.md b/ext/README.md index 3bc6c3872a..cbdd482901 100644 --- a/ext/README.md +++ b/ext/README.md @@ -81,7 +81,7 @@ Documentation for both the examples and the library itself is hosted at If documentation for a specific version of the library is sought, it can be generated by running ```shell -make docs +just docs ``` after which the documentation is placed at `target/doc/`. The link above opens @@ -94,7 +94,7 @@ the file `target/doc/ext/index.html`. Lint scripts can be run with ```shell -make lint +just lint ``` This runs `clippy` and `rustfmt`. @@ -108,7 +108,7 @@ There are multiple types of tests These can be run by ```shell -make test +just test ``` #### Example benchmarks @@ -121,14 +121,14 @@ the output should be. These can be run by ```shell -make benchmarks -make benchmarks-concurrent +just benchmarks +just benchmarks-concurrent ``` Running ```shell -make fix-benchmarks +just fix-benchmarks ``` updates the outputs in all benchmark files to match the current program output. @@ -137,7 +137,7 @@ This is useful for adding new benchmarks. These can be run for individual benchmarks by e.g. ```shell -make examples/benchmarks/resolve-S_2 -make examples/benchmarks/resolve-S_2-concurrent -make examples/benchmarks/resolve-S_2-fixed +just bench resolve-S_2 +just bench-concurrent resolve-S_2 +just fix-bench resolve-S_2 ``` diff --git a/ext/flake.nix b/ext/flake.nix index cfc98ca094..35e0d02fc8 100644 --- a/ext/flake.nix +++ b/ext/flake.nix @@ -44,12 +44,12 @@ export RUSTFLAGS="-D warnings" export RUSTDOCFLAGS="-D warnings" - make lint - make test - make benchmarks - make benchmarks-nassau - make benchmarks-concurrent - make miri + just lint + just test + just benchmarks + just benchmarks-nassau + just benchmarks-concurrent + just miri ''); }; }); diff --git a/ext/justfile b/ext/justfile new file mode 100644 index 0000000000..b28d60221f --- /dev/null +++ b/ext/justfile @@ -0,0 +1,140 @@ +# Command runner for the `ext` library. Replaces the old Makefile. +# Requires `just` >= 1.5 (shebang recipes, if/else expressions, CLI overrides). + +set shell := ["bash", "-c"] + +BENCH_DIR := "examples/benchmarks" + +# Build the library (default recipe). +all: + cargo build + +test: + cargo test --examples + cargo test --features concurrent --lib --tests --workspace + cargo test --features concurrent --doc --workspace + pytest + +lint: + cargo fmt --all -- --check + cargo clippy --workspace --no-default-features --profile test + cargo clippy --workspace --all-targets --profile test + cargo check --workspace --no-default-features --profile test + cargo check --workspace --all-targets --all-features --profile test + +docs: + # Prevent the cached crates.js from confusing the current run + rm target/doc/crates.js || true + RUSTDOCFLAGS="--html-in-header gh-pages/katex-header.html $RUSTDOCFLAGS" cargo rustdoc --examples --all-features + RUSTDOCFLAGS="--html-in-header gh-pages/katex-header.html $RUSTDOCFLAGS" cargo doc --all --no-deps --document-private-items --all-features + # Prevent the examples from showing up in the sidebar + echo "window.ALL_CRATES = [$(ls crates/ | sed "s/.*/'&',/; s/-/_/g")'ext'];" > target/doc/crates.js + +miri: + cargo miri test -p once + MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-disable-isolation" cargo miri test -p once --features concurrent + +# ---- Benchmarks ---------------------------------------------------------- +# +# Each file in examples/benchmarks/ has the example argument on its first line +# and the expected output on the rest. Names ending in `-nassau` are run with +# `--features nassau`. + +# Run a single benchmark, e.g. `just bench resolve-S_2`. +bench NAME: + #!/usr/bin/env bash + set -euo pipefail + file="{{BENCH_DIR}}/{{NAME}}" + features="" + [[ "{{NAME}}" == *-nassau ]] && features="--features nassau" + # The first line is the example invocation. It is expanded UNQUOTED into the + # inner `bash -c` string, which then word-splits it into separate cargo args + # (e.g. `resolve -- S_2 "" 30 11 ""`) with the `""` tokens becoming empty + # arguments via the inner shell's quote removal — matching the old Makefile. + example="$(head -n 1 "$file")" + (echo "$example" && bash -c "echo '' | cargo run $features --example $example") | diff --color "$file" - + +# Run a single benchmark with --features concurrent (30s timeout = success). +bench-concurrent NAME: + #!/usr/bin/env bash + set -euo pipefail + file="{{BENCH_DIR}}/{{NAME}}" + example="$(head -n 1 "$file")" + { + echo "$example" + timeout 30 bash -c "echo '' | cargo run --features concurrent --example $example" + ec=$? + } > output.txt || ec=$? + if [ "${ec:-0}" -eq 124 ]; then + echo "Timeout occurred, but treating as success." + rm -f output.txt + elif [ "${ec:-0}" -eq 0 ]; then + diff --color output.txt "$file" + rm -f output.txt + else + echo "Command failed with code ${ec}." + rm -f output.txt + exit 1 + fi + +# Rewrite a single benchmark's expected output to the current program output. +fix-bench NAME: + #!/usr/bin/env bash + set -euo pipefail + file="{{BENCH_DIR}}/{{NAME}}" + features="" + [[ "{{NAME}}" == *-nassau ]] && features="--features nassau" + example="$(head -n 1 "$file")" + out="${file}-fixed" + (echo "$example" && bash -c "echo '' | cargo run $features --example $example") > "$out" + if diff --color "$file" "$out"; then + rm "$out" + else + mv "$out" "$file" + fi + +# All non-nassau benchmarks. +benchmarks: + #!/usr/bin/env bash + set -euo pipefail + for file in {{BENCH_DIR}}/*; do + name="$(basename "$file")" + [[ "$name" == *-nassau ]] && continue + just bench "$name" + done + +# All nassau benchmarks. +benchmarks-nassau: + #!/usr/bin/env bash + set -euo pipefail + for file in {{BENCH_DIR}}/*-nassau; do + just bench "$(basename "$file")" + done + +# All non-nassau benchmarks, concurrent. +benchmarks-concurrent: + #!/usr/bin/env bash + set -euo pipefail + for file in {{BENCH_DIR}}/*; do + name="$(basename "$file")" + [[ "$name" == *-nassau ]] && continue + just bench-concurrent "$name" + done + +# Rewrite all non-nassau benchmark outputs. +fix-benchmarks: + #!/usr/bin/env bash + set -euo pipefail + for file in {{BENCH_DIR}}/*; do + name="$(basename "$file")" + [[ "$name" == *-nassau ]] && continue + just fix-bench "$name" + done + +# Rewrite all nassau benchmark outputs. +fix-benchmarks-nassau: + #!/usr/bin/env bash + set -euo pipefail + for file in {{BENCH_DIR}}/*-nassau; do + just fix-bench "$(basename "$file")" + done diff --git a/flake.nix b/flake.nix index 705d06043b..2cc6fafcf6 100644 --- a/flake.nix +++ b/flake.nix @@ -33,6 +33,7 @@ pkgs = import nixpkgs {inherit system;}; in [ pkgs.git + pkgs.just pkgs.hyperfine pkgs.binutils pkgs.cargo-binutils diff --git a/web_ext/sseq_gui/Makefile b/web_ext/sseq_gui/Makefile deleted file mode 100644 index 6406b02d73..0000000000 --- a/web_ext/sseq_gui/Makefile +++ /dev/null @@ -1,96 +0,0 @@ -WASM_TARGET = wasm32-unknown-unknown -NAME = sseq_gui -WASM_LIB = target/$(WASM_TARGET)/release/$(NAME).wasm -WASM_OUT = dist/ -WASM_FILE = $(WASM_OUT)/$(NAME)_wasm_bg.wasm -EXT = ../../ext/ - -# Building with `panic=unwind` lets Rust panics unwind into JS exceptions -# instead of aborting the whole wasm module. The prebuilt std for -# wasm32-unknown-unknown is compiled with `panic=abort`, so `-C panic=unwind` -# alone is silently ignored: we must rebuild std with `-Z build-std` (nightly -# only) and enable the wasm exception-handling proposal. -# -# This is opt-in via `WASM_UNWIND=1` so the default build still works on -# stable/beta (panic=abort). CI builds stable/beta with panic=abort and the -# deployed build with `WASM_UNWIND=1` on nightly. -ifdef WASM_UNWIND -WASM_RUSTFLAGS = -C panic=unwind -C target-feature=+exception-handling -WASM_BUILD_STD = -Z build-std=std,panic_unwind -WASM_OPT_FLAGS = --enable-exception-handling -endif - -export PATH := $(HOME)/.cargo/bin:$(PATH) - -lint: - cargo clippy --all-features --all-targets - cargo clippy --no-default-features --all-targets - cargo fmt -- --check - -lint-wasm: - cargo clippy --lib --target $(WASM_TARGET) - -setup-wasm: - cargo install wasm-bindgen-cli --debug - rustup target add wasm32-unknown-unknown - # rust-src is required by `-Z build-std` (see the WASM_BUILD_STD note above). - rustup component add rust-src - -# Always defer to cargo to decide whether a rebuild is needed: it fingerprints -# RUSTFLAGS and the build-std setting, so it correctly rebuilds when toggling -# between panic=abort and panic=unwind (which `make`'s timestamp check cannot -# detect, as the sources are unchanged). -$(WASM_LIB): FORCE - RUSTFLAGS="$$RUSTFLAGS $(WASM_RUSTFLAGS)" \ - cargo build --lib --target $(WASM_TARGET) --release $(WASM_BUILD_STD) - -FORCE: - -$(WASM_FILE): $(WASM_LIB) - wasm-bindgen --no-typescript --target no-modules --out-dir $(WASM_OUT) --out-name $(NAME)_wasm $(WASM_LIB) - wasm-opt -O3 $(WASM_OPT_FLAGS) $(WASM_FILE) -o $(WASM_FILE) || true - -# Assert that the wasm is actually built with unwinding support: a wasm module -# using the exception-handling proposal contains a `Tag` section. If unwinding -# silently regressed to `panic=abort` (e.g. build-std got dropped), this fails. -# Forces a WASM_UNWIND=1 build of the lib so the check is meaningful regardless -# of how it was invoked. -test-wasm-unwind: - $(MAKE) WASM_UNWIND=1 $(WASM_LIB) - wasm-objdump -h $(WASM_LIB) | grep -qi '^ *Tag ' \ - || { echo "ERROR: $(WASM_LIB) has no Tag section; panic=unwind is not in effect"; exit 1; } - @echo "OK: wasm built with exception-handling (panic=unwind)" - -# Unit-test the panic-catching logic in the worker JS (wasm/*_worker.js). -# Runs in plain Node with mocked wasm globals, so no browser/wasm build needed. -test-wasm-js: - node --test wasm/*.test.mjs - -.PHONY: wasm serve-wasm clean-wasm clean dummy test selenium selenium-update test-wasm-unwind test-wasm-js FORCE - -wasm: $(WASM_FILE) $(wildcard interface/*) $(wildcard wasm/*) $(wildcard $(EXT)/steenrod_modules/*) - # Must be done in this order since both contain index.js and we want the wasm version - cp interface/* $(WASM_OUT) - cp wasm/* $(WASM_OUT) - cp vendor/* $(WASM_OUT) - cp -r $(EXT)/steenrod_modules $(WASM_OUT) - -serve-wasm: - python3 -m http.server --directory dist 8080 - -clean-wasm: - rm -r dist/* - -clean: clean-wasm - rm -r target - -lint-selenium: - flake8 --ignore E501 tests - black --diff --check tests - -selenium: - python3 -m pytest -s tests --driver chrome - python3 -m pytest -s tests --driver firefox - -selenium-update: - python3 -m pytest tests --driver firefox --update diff --git a/web_ext/sseq_gui/README.md b/web_ext/sseq_gui/README.md index 5fbcbaa9f6..58536342e7 100644 --- a/web_ext/sseq_gui/README.md +++ b/web_ext/sseq_gui/README.md @@ -32,7 +32,7 @@ distribution but is slower. A live version is available at To setup the build environment, run ```shell -make setup-wasm +just setup-wasm ``` By default the wasm is built with `panic=abort`, which works on stable. Passing @@ -41,18 +41,18 @@ By default the wasm is built with `panic=abort`, which works on stable. Passing than aborting the whole module: ```shell -make wasm WASM_UNWIND=1 +just WASM_UNWIND=1 wasm ``` This requires a **nightly** toolchain with the `rust-src` component (installed -by `make setup-wasm`). The deployed build uses `WASM_UNWIND=1`; CI also builds +by `just setup-wasm`). The deployed build uses `WASM_UNWIND=1`; CI also builds the default `panic=abort` configuration on stable/beta. Afterwards, build and serve with ```shell -make wasm -make serve-wasm +just wasm +just serve-wasm ``` This serves the website at `localhost:[port]`. The `[port]` argument is optional and defaults to `8000`. diff --git a/web_ext/sseq_gui/flake.nix b/web_ext/sseq_gui/flake.nix index d9c6b96039..ec9f48b4f2 100644 --- a/web_ext/sseq_gui/flake.nix +++ b/web_ext/sseq_gui/flake.nix @@ -33,7 +33,7 @@ pythonEnv pkgs.openssl - # wabt provides wasm-objdump, used by `make test-wasm-unwind` to + # wabt provides wasm-objdump, used by `just test-wasm-unwind` to # assert the wasm is actually built with unwinding support. pkgs.wabt ] @@ -45,24 +45,24 @@ export RUSTFLAGS="-D warnings" export RUSTDOCFLAGS="-D warnings" - make lint - make lint-selenium + just lint + just lint-selenium cargo install wasm-bindgen-cli --debug - make lint-wasm - make wasm - make test-wasm-unwind + just lint-wasm + just wasm + just test-wasm-unwind - make serve-wasm & - (sleep 1 && make selenium) + just serve-wasm & + (sleep 1 && just selenium) cargo build && (target/debug/sseq_gui & - (sleep 1 && make selenium)) + (sleep 1 && just selenium)) cargo build --features concurrent && (target/debug/sseq_gui & - (sleep 1 && make selenium)) + (sleep 1 && just selenium)) ''; in { devShells.default = pkgs.mkShell { diff --git a/web_ext/sseq_gui/justfile b/web_ext/sseq_gui/justfile new file mode 100644 index 0000000000..2e79c5f164 --- /dev/null +++ b/web_ext/sseq_gui/justfile @@ -0,0 +1,102 @@ +# Command runner for sseq_gui. Replaces the old Makefile. +# Requires `just` >= 1.5 (shebang recipes, if/else expressions, CLI overrides). + +set shell := ["bash", "-c"] + +WASM_TARGET := "wasm32-unknown-unknown" +NAME := "sseq_gui" +WASM_LIB := "target/" + WASM_TARGET + "/release/" + NAME + ".wasm" +WASM_OUT := "dist/" +WASM_FILE := WASM_OUT + "/" + NAME + "_wasm_bg.wasm" +EXT := "../../ext/" + +# Building with `panic=unwind` lets Rust panics unwind into JS exceptions +# instead of aborting the whole wasm module. The prebuilt std for +# wasm32-unknown-unknown is compiled with `panic=abort`, so `-C panic=unwind` +# alone is silently ignored: we must rebuild std with `-Z build-std` (nightly +# only) and enable the wasm exception-handling proposal. +# +# This is opt-in via `WASM_UNWIND=1` so the default build still works on +# stable/beta (panic=abort). Override on the command line, e.g. +# `just WASM_UNWIND=1 wasm`. CI builds stable/beta with panic=abort and the +# deployed build with `WASM_UNWIND=1` on nightly. +WASM_UNWIND := "" +WASM_RUSTFLAGS := if WASM_UNWIND != "" { "-C panic=unwind -C target-feature=+exception-handling" } else { "" } +WASM_BUILD_STD := if WASM_UNWIND != "" { "-Z build-std=std,panic_unwind" } else { "" } +WASM_OPT_FLAGS := if WASM_UNWIND != "" { "--enable-exception-handling" } else { "" } + +lint: + cargo clippy --all-features --all-targets + cargo clippy --no-default-features --all-targets + cargo fmt -- --check + +lint-wasm: + cargo clippy --lib --target {{WASM_TARGET}} + +setup-wasm: + cargo install wasm-bindgen-cli --debug + rustup target add wasm32-unknown-unknown + # rust-src is required by `-Z build-std` (see the WASM_UNWIND note above). + rustup component add rust-src + +# Always rebuild: cargo fingerprints RUSTFLAGS and the build-std setting, so it +# correctly rebuilds when toggling between panic=abort and panic=unwind (which a +# timestamp check cannot detect, as the sources are unchanged). +wasm-lib: + #!/usr/bin/env bash + set -euo pipefail + export PATH="$HOME/.cargo/bin:$PATH" + RUSTFLAGS="${RUSTFLAGS:-} {{WASM_RUSTFLAGS}}" \ + cargo build --lib --target {{WASM_TARGET}} --release {{WASM_BUILD_STD}} + +wasm-bindgen-step: wasm-lib + #!/usr/bin/env bash + set -euo pipefail + export PATH="$HOME/.cargo/bin:$PATH" + wasm-bindgen --no-typescript --target no-modules --out-dir {{WASM_OUT}} --out-name {{NAME}}_wasm {{WASM_LIB}} + wasm-opt -O3 {{WASM_OPT_FLAGS}} {{WASM_FILE}} -o {{WASM_FILE}} || true + +wasm: wasm-bindgen-step + # Must be done in this order since both contain index.js and we want the wasm version + cp interface/* {{WASM_OUT}} + cp wasm/* {{WASM_OUT}} + cp vendor/* {{WASM_OUT}} + cp -r {{EXT}}/steenrod_modules {{WASM_OUT}} + +# Assert that the wasm is actually built with unwinding support: a wasm module +# using the exception-handling proposal contains a `Tag` section. If unwinding +# silently regressed to `panic=abort`, this fails. Forces a WASM_UNWIND=1 build +# of the lib so the check is meaningful regardless of how it was invoked. +test-wasm-unwind: + #!/usr/bin/env bash + set -euo pipefail + export PATH="$HOME/.cargo/bin:$PATH" + just WASM_UNWIND=1 wasm-lib + wasm-objdump -h {{WASM_LIB}} | grep -qi '^ *Tag ' \ + || { echo "ERROR: {{WASM_LIB}} has no Tag section; panic=unwind is not in effect"; exit 1; } + echo "OK: wasm built with exception-handling (panic=unwind)" + +# Unit-test the panic-catching logic in the worker JS (wasm/*_worker.js). +# Runs in plain Node with mocked wasm globals, so no browser/wasm build needed. +test-wasm-js: + node --test wasm/*.test.mjs + +serve-wasm: + python3 -m http.server --directory dist 8080 + +clean-wasm: + rm -r dist/* + +clean: clean-wasm + rm -r target + +lint-selenium: + flake8 --ignore E501 tests + black --diff --check tests + +selenium: + python3 -m pytest -s tests --driver chrome + python3 -m pytest -s tests --driver firefox + +selenium-update: + python3 -m pytest tests --driver firefox --update diff --git a/web_ext/steenrod_calculator/Makefile b/web_ext/steenrod_calculator/Makefile deleted file mode 100644 index fae7193cc0..0000000000 --- a/web_ext/steenrod_calculator/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -WASM_TARGET = wasm32-unknown-unknown -NAME = steenrod_calculator -WASM_LIB = target/$(WASM_TARGET)/release/$(NAME).wasm -WASM_OUT = dist/ -WASM_FILE = $(WASM_OUT)/$(NAME)_wasm_bg.wasm - -EXT_SRC = ../../ext/Cargo.toml $(shell find ../../ext/src/) $(wildcard ../../ext/crates/*/Cargo.tml) $(shell find ../../ext/crates/*/src/) - -all: $(WASM_FILE) $(wildcard files/*) - cp files/* $(WASM_OUT) - -lint: - cargo fmt -- --check - cargo clippy --lib --target $(WASM_TARGET) - -setup-wasm: - cargo install wasm-bindgen-cli --debug - rustup target add wasm32-unknown-unknown - -$(WASM_LIB): Cargo.toml $(wildcard src/*) $(EXT_SRC) - cargo build --lib --target $(WASM_TARGET) --release - -$(WASM_FILE): $(WASM_LIB) - wasm-bindgen --no-typescript --target no-modules --out-dir $(WASM_OUT) --out-name $(NAME)_wasm $(WASM_LIB) - wasm-opt -O3 $(WASM_FILE) -o $(WASM_FILE) || true diff --git a/web_ext/steenrod_calculator/justfile b/web_ext/steenrod_calculator/justfile new file mode 100644 index 0000000000..3901e0390a --- /dev/null +++ b/web_ext/steenrod_calculator/justfile @@ -0,0 +1,29 @@ +# Command runner for the Steenrod calculator. Replaces the old Makefile. +# Requires `just` >= 1.5. + +set shell := ["bash", "-c"] + +WASM_TARGET := "wasm32-unknown-unknown" +NAME := "steenrod_calculator" +WASM_LIB := "target/" + WASM_TARGET + "/release/" + NAME + ".wasm" +WASM_OUT := "dist/" +WASM_FILE := WASM_OUT + "/" + NAME + "_wasm_bg.wasm" + +# Build the wasm and copy the static files (default recipe). +all: wasm-bindgen-step + cp files/* {{WASM_OUT}} + +lint: + cargo fmt -- --check + cargo clippy --lib --target {{WASM_TARGET}} + +setup-wasm: + cargo install wasm-bindgen-cli --debug + rustup target add wasm32-unknown-unknown + +wasm-lib: + cargo build --lib --target {{WASM_TARGET}} --release + +wasm-bindgen-step: wasm-lib + wasm-bindgen --no-typescript --target no-modules --out-dir {{WASM_OUT}} --out-name {{NAME}}_wasm {{WASM_LIB}} + wasm-opt -O3 {{WASM_FILE}} -o {{WASM_FILE}} || true From 68a2043f5cd1f5b57f1b87f83cd167de55f3cc1e Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 1 Jul 2026 23:22:31 +0000 Subject: [PATCH 2/6] Fix test-wasm-unwind pipefail regression; bump setup-just The migration added `set -euo pipefail` to the sseq_gui `test-wasm-unwind` recipe, which changed the behavior of wasm-objdump -h $WASM_LIB | grep -qi '^ *Tag ' wasm-objdump prints the section headers (including `Tag`) to stdout but can exit non-zero on a later section it cannot parse. Under the old Makefile's plain `sh` (no pipefail) the pipe's exit came from `grep`, so a present `Tag` section passed. With `pipefail`, wasm-objdump's non-zero exit propagated and failed the check even though `Tag` was found. Drop `pipefail` for this recipe (use `set -eu`) to restore the Makefile behavior. Also bump the CI tooling as suggested in review: extractions/setup-just@v2 -> @v4 and just-version 1.34 -> 1.54.0. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01DSAx1G1eMeCYPwNH7WNMVo --- .github/workflows/ext.yaml | 32 ++++++++++++++++---------------- web_ext/sseq_gui/justfile | 8 +++++++- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ext.yaml b/.github/workflows/ext.yaml index f2cec5cc5b..4ec93ab125 100644 --- a/.github/workflows/ext.yaml +++ b/.github/workflows/ext.yaml @@ -20,9 +20,9 @@ jobs: - uses: actions/setup-python@v5 with: python-version: "3.9" - - uses: extractions/setup-just@v2 + - uses: extractions/setup-just@v4 with: - just-version: "1.34" + just-version: "1.54.0" - name: Install rustup id: rustup @@ -68,9 +68,9 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: extractions/setup-just@v2 + - uses: extractions/setup-just@v4 with: - just-version: "1.34" + just-version: "1.54.0" - name: Install rustup id: rustup @@ -101,9 +101,9 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: extractions/setup-just@v2 + - uses: extractions/setup-just@v4 with: - just-version: "1.34" + just-version: "1.54.0" - name: Install rustup id: rustup @@ -152,9 +152,9 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: extractions/setup-just@v2 + - uses: extractions/setup-just@v4 with: - just-version: "1.34" + just-version: "1.54.0" - name: Install rustup uses: dtolnay/rust-toolchain@v1 @@ -211,9 +211,9 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: extractions/setup-just@v2 + - uses: extractions/setup-just@v4 with: - just-version: "1.34" + just-version: "1.54.0" - name: Install rustup uses: dtolnay/rust-toolchain@v1 @@ -276,9 +276,9 @@ jobs: continue-on-error: ${{ matrix.toolchain != 'stable' }} steps: - uses: actions/checkout@v4 - - uses: extractions/setup-just@v2 + - uses: extractions/setup-just@v4 with: - just-version: "1.34" + just-version: "1.54.0" - name: Download webserver uses: actions/download-artifact@v4 @@ -352,9 +352,9 @@ jobs: continue-on-error: ${{ matrix.toolchain != 'stable' }} steps: - uses: actions/checkout@v4 - - uses: extractions/setup-just@v2 + - uses: extractions/setup-just@v4 with: - just-version: "1.34" + just-version: "1.54.0" - name: Install rustup id: rustup @@ -410,9 +410,9 @@ jobs: continue-on-error: ${{ matrix.toolchain != 'stable' }} steps: - uses: actions/checkout@v4 - - uses: extractions/setup-just@v2 + - uses: extractions/setup-just@v4 with: - just-version: "1.34" + just-version: "1.54.0" - name: Install rustup id: rustup diff --git a/web_ext/sseq_gui/justfile b/web_ext/sseq_gui/justfile index 2e79c5f164..f4e20c4f83 100644 --- a/web_ext/sseq_gui/justfile +++ b/web_ext/sseq_gui/justfile @@ -69,7 +69,13 @@ wasm: wasm-bindgen-step # of the lib so the check is meaningful regardless of how it was invoked. test-wasm-unwind: #!/usr/bin/env bash - set -euo pipefail + # NB: deliberately no `pipefail`. `wasm-objdump` prints the section headers + # (including `Tag`) to stdout but may then exit non-zero on a later section + # it cannot parse (newer toolchains emit wasm features wabt doesn't grok). + # We only care whether a `Tag` section was printed, so the pipe's exit must + # come from `grep`, not `wasm-objdump` — matching the old Makefile, which ran + # this under plain `sh` without pipefail. + set -eu export PATH="$HOME/.cargo/bin:$PATH" just WASM_UNWIND=1 wasm-lib wasm-objdump -h {{WASM_LIB}} | grep -qi '^ *Tag ' \ From fb49feac58e9ed8bdb25a7c6c8ca568d0e6826f5 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 1 Jul 2026 23:32:39 +0000 Subject: [PATCH 3/6] Address review comments on the wasm justfiles - test-wasm-unwind (sseq_gui): build the full WASM_UNWIND=1 `wasm` pipeline and inspect the shipped WASM_FILE (wasm-bindgen/wasm-opt output) instead of the raw WASM_LIB, so breakage in the bindgen/opt stage is caught too. - WASM_FILE path: drop the doubled separator (WASM_OUT already names the dir), so it is `dist/_wasm_bg.wasm` rather than `dist//_wasm_bg.wasm`, in both the sseq_gui and steenrod_calculator justfiles. - setup-wasm: pin wasm-bindgen-cli to the version the crate resolves to (derived via `cargo tree`) rather than installing an unpinned CLI that can drift out of sync with the schema-locked wasm-bindgen dependency. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01DSAx1G1eMeCYPwNH7WNMVo --- web_ext/sseq_gui/justfile | 22 +++++++++++++++------- web_ext/steenrod_calculator/justfile | 11 +++++++++-- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/web_ext/sseq_gui/justfile b/web_ext/sseq_gui/justfile index f4e20c4f83..d0afe131a1 100644 --- a/web_ext/sseq_gui/justfile +++ b/web_ext/sseq_gui/justfile @@ -6,7 +6,7 @@ set shell := ["bash", "-c"] WASM_TARGET := "wasm32-unknown-unknown" NAME := "sseq_gui" WASM_LIB := "target/" + WASM_TARGET + "/release/" + NAME + ".wasm" -WASM_OUT := "dist/" +WASM_OUT := "dist" WASM_FILE := WASM_OUT + "/" + NAME + "_wasm_bg.wasm" EXT := "../../ext/" @@ -34,7 +34,14 @@ lint-wasm: cargo clippy --lib --target {{WASM_TARGET}} setup-wasm: - cargo install wasm-bindgen-cli --debug + #!/usr/bin/env bash + set -euo pipefail + # Install wasm-bindgen-cli at the exact version the crate resolves to: the + # generated glue and the CLI share an unstable schema and must be + # version-matched, so an unpinned install can drift out of sync and break + # the build. Deriving the version keeps this in step with the crate. + version="$(cargo tree --package wasm-bindgen --depth 0 --prefix none | head -1 | awk '{gsub(/^v/,"",$2); print $2}')" + cargo install wasm-bindgen-cli --version "$version" --debug rustup target add wasm32-unknown-unknown # rust-src is required by `-Z build-std` (see the WASM_UNWIND note above). rustup component add rust-src @@ -65,8 +72,9 @@ wasm: wasm-bindgen-step # Assert that the wasm is actually built with unwinding support: a wasm module # using the exception-handling proposal contains a `Tag` section. If unwinding -# silently regressed to `panic=abort`, this fails. Forces a WASM_UNWIND=1 build -# of the lib so the check is meaningful regardless of how it was invoked. +# silently regressed to `panic=abort`, this fails. Builds the full WASM_UNWIND=1 +# pipeline and inspects the shipped WASM_FILE (the wasm-bindgen/wasm-opt output), +# so breakage anywhere in the pipeline is caught regardless of how it was invoked. test-wasm-unwind: #!/usr/bin/env bash # NB: deliberately no `pipefail`. `wasm-objdump` prints the section headers @@ -77,9 +85,9 @@ test-wasm-unwind: # this under plain `sh` without pipefail. set -eu export PATH="$HOME/.cargo/bin:$PATH" - just WASM_UNWIND=1 wasm-lib - wasm-objdump -h {{WASM_LIB}} | grep -qi '^ *Tag ' \ - || { echo "ERROR: {{WASM_LIB}} has no Tag section; panic=unwind is not in effect"; exit 1; } + just WASM_UNWIND=1 wasm + wasm-objdump -h {{WASM_FILE}} | grep -qi '^ *Tag ' \ + || { echo "ERROR: {{WASM_FILE}} has no Tag section; panic=unwind is not in effect"; exit 1; } echo "OK: wasm built with exception-handling (panic=unwind)" # Unit-test the panic-catching logic in the worker JS (wasm/*_worker.js). diff --git a/web_ext/steenrod_calculator/justfile b/web_ext/steenrod_calculator/justfile index 3901e0390a..bdac2e9af0 100644 --- a/web_ext/steenrod_calculator/justfile +++ b/web_ext/steenrod_calculator/justfile @@ -6,7 +6,7 @@ set shell := ["bash", "-c"] WASM_TARGET := "wasm32-unknown-unknown" NAME := "steenrod_calculator" WASM_LIB := "target/" + WASM_TARGET + "/release/" + NAME + ".wasm" -WASM_OUT := "dist/" +WASM_OUT := "dist" WASM_FILE := WASM_OUT + "/" + NAME + "_wasm_bg.wasm" # Build the wasm and copy the static files (default recipe). @@ -18,7 +18,14 @@ lint: cargo clippy --lib --target {{WASM_TARGET}} setup-wasm: - cargo install wasm-bindgen-cli --debug + #!/usr/bin/env bash + set -euo pipefail + # Install wasm-bindgen-cli at the exact version the crate resolves to: the + # generated glue and the CLI share an unstable schema and must be + # version-matched, so an unpinned install can drift out of sync and break + # the build. Deriving the version keeps this in step with the crate. + version="$(cargo tree --package wasm-bindgen --depth 0 --prefix none | head -1 | awk '{gsub(/^v/,"",$2); print $2}')" + cargo install wasm-bindgen-cli --version "$version" --debug rustup target add wasm32-unknown-unknown wasm-lib: From b3fcf2423e441d1fa1cb770bd5590a816fcb8fa4 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 1 Jul 2026 23:51:54 +0000 Subject: [PATCH 4/6] Address review feedback: simpler CI, `fix` recipe, `bless-*` benchmarks Per maintainer review on the upstream PR: - CI: replace `just --working-directory --justfile /justfile ` with the shorter `cd && just ` across ext.yaml. - ext/justfile: add a `fix` recipe that applies what `lint` only checks (`cargo fmt --all` + `cargo clippy --fix`). - ext/justfile: rename the benchmark-updating recipes fix-bench / fix-benchmarks / fix-benchmarks-nassau to bless-bench / bless-benchmarks / bless-benchmarks-nassau ("bless the current output as correct"); update ext/README.md accordingly. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01DSAx1G1eMeCYPwNH7WNMVo --- .github/workflows/ext.yaml | 38 +++++++++++++++++++------------------- ext/README.md | 4 ++-- ext/justfile | 21 +++++++++++++-------- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ext.yaml b/.github/workflows/ext.yaml index 4ec93ab125..5bceade40a 100644 --- a/.github/workflows/ext.yaml +++ b/.github/workflows/ext.yaml @@ -43,16 +43,16 @@ jobs: run: pip install pytest - name: Run ext tests - run: just --working-directory ext --justfile ext/justfile test + run: cd ext && just test - name: Run ext examples - run: just --working-directory ext --justfile ext/justfile benchmarks + run: cd ext && just benchmarks - name: Run ext examples (nassau) - run: just --working-directory ext --justfile ext/justfile benchmarks-nassau + run: cd ext && just benchmarks-nassau - name: Run ext examples (concurrent) - run: just --working-directory ext --justfile ext/justfile benchmarks-concurrent + run: cd ext && just benchmarks-concurrent - name: Benchmark executable size run: | @@ -89,7 +89,7 @@ jobs: key: miri-${{ steps.rustup.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.*') }} - name: Run miri - run: just --working-directory ext --justfile ext/justfile miri + run: cd ext && just miri lint: if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository }} @@ -125,13 +125,13 @@ jobs: key: lint-${{ steps.rustup.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.*') }} - name: Run lint - run: just --working-directory ext --justfile ext/justfile lint + run: cd ext && just lint - name: Lint sseq_gui - run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile lint + run: cd web_ext/sseq_gui && just lint - name: Lint sseq_gui tests - run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile lint-selenium + run: cd web_ext/sseq_gui && just lint-selenium # Build the wasm webserver with the default `panic=abort` configuration on # stable/beta. This is the compatibility build; the deployed artifact is @@ -177,16 +177,16 @@ jobs: run: sudo apt-get install binaryen - name: Setup build environment - run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile setup-wasm + run: cd web_ext/sseq_gui && just setup-wasm - name: Lint sseq_gui wasm - run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile lint-wasm + run: cd web_ext/sseq_gui && just lint-wasm - name: Test worker panic handling - run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile test-wasm-js + run: cd web_ext/sseq_gui && just test-wasm-js - name: Build wasm - run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile wasm + run: cd web_ext/sseq_gui && just wasm - name: Benchmark wasm size run: ls -l web_ext/sseq_gui/dist/sseq_gui_wasm_bg.wasm @@ -237,13 +237,13 @@ jobs: run: sudo apt-get install -y binaryen wabt - name: Setup build environment - run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile setup-wasm + run: cd web_ext/sseq_gui && just setup-wasm - name: Build wasm (panic=unwind) - run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile WASM_UNWIND=1 wasm + run: cd web_ext/sseq_gui && just WASM_UNWIND=1 wasm - name: Verify wasm unwinding - run: just --working-directory web_ext/sseq_gui --justfile web_ext/sseq_gui/justfile test-wasm-unwind + run: cd web_ext/sseq_gui && just test-wasm-unwind - name: Benchmark wasm size run: ls -l web_ext/sseq_gui/dist/sseq_gui_wasm_bg.wasm @@ -377,13 +377,13 @@ jobs: run: sudo apt-get install binaryen - name: Setup build environment - run: just --working-directory web_ext/steenrod_calculator --justfile web_ext/steenrod_calculator/justfile setup-wasm + run: cd web_ext/steenrod_calculator && just setup-wasm - name: Lint sseq_gui wasm - run: just --working-directory web_ext/steenrod_calculator --justfile web_ext/steenrod_calculator/justfile lint + run: cd web_ext/steenrod_calculator && just lint - name: Build wasm - run: just --working-directory web_ext/steenrod_calculator --justfile web_ext/steenrod_calculator/justfile all + run: cd web_ext/steenrod_calculator && just all - name: Benchmark wasm size run: ls -l web_ext/steenrod_calculator/dist/steenrod_calculator_wasm_bg.wasm @@ -431,7 +431,7 @@ jobs: key: docs-${{ steps.rustup.outputs.rustc_hash }}-${{ hashFiles('ext/Cargo.*') }} - name: Generate docs - run: just --working-directory ext --justfile ext/justfile docs + run: cd ext && just docs - name: Upload docs uses: actions/upload-artifact@v4 diff --git a/ext/README.md b/ext/README.md index cbdd482901..172661a578 100644 --- a/ext/README.md +++ b/ext/README.md @@ -128,7 +128,7 @@ just benchmarks-concurrent Running ```shell -just fix-benchmarks +just bless-benchmarks ``` updates the outputs in all benchmark files to match the current program output. @@ -139,5 +139,5 @@ These can be run for individual benchmarks by e.g. ```shell just bench resolve-S_2 just bench-concurrent resolve-S_2 -just fix-bench resolve-S_2 +just bless-bench resolve-S_2 ``` diff --git a/ext/justfile b/ext/justfile index b28d60221f..41af09b875 100644 --- a/ext/justfile +++ b/ext/justfile @@ -22,6 +22,11 @@ lint: cargo check --workspace --no-default-features --profile test cargo check --workspace --all-targets --all-features --profile test +# Apply the fixes that `lint` only checks: rustfmt formatting + clippy autofixes. +fix: + cargo fmt --all + cargo clippy --workspace --all-targets --fix --allow-dirty --allow-staged + docs: # Prevent the cached crates.js from confusing the current run rm target/doc/crates.js || true @@ -77,8 +82,8 @@ bench-concurrent NAME: exit 1 fi -# Rewrite a single benchmark's expected output to the current program output. -fix-bench NAME: +# Bless a single benchmark: overwrite its expected output with the current output. +bless-bench NAME: #!/usr/bin/env bash set -euo pipefail file="{{BENCH_DIR}}/{{NAME}}" @@ -121,20 +126,20 @@ benchmarks-concurrent: just bench-concurrent "$name" done -# Rewrite all non-nassau benchmark outputs. -fix-benchmarks: +# Bless all non-nassau benchmarks. +bless-benchmarks: #!/usr/bin/env bash set -euo pipefail for file in {{BENCH_DIR}}/*; do name="$(basename "$file")" [[ "$name" == *-nassau ]] && continue - just fix-bench "$name" + just bless-bench "$name" done -# Rewrite all nassau benchmark outputs. -fix-benchmarks-nassau: +# Bless all nassau benchmarks. +bless-benchmarks-nassau: #!/usr/bin/env bash set -euo pipefail for file in {{BENCH_DIR}}/*-nassau; do - just fix-bench "$(basename "$file")" + just bless-bench "$(basename "$file")" done From ceb4c679844df21b02dbdf90351e05e9950baa6b Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Jul 2026 00:18:21 +0000 Subject: [PATCH 5/6] setup-wasm: resolve wasm-bindgen version with `cargo tree --target all` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In sseq_gui, `wasm-bindgen` is a `wasm32`-only dependency (`[target.'cfg(target_arch = "wasm32")'.dependencies]`), so a host-target `cargo tree` prints nothing and the derived version came out empty — making `cargo install wasm-bindgen-cli --version ''` fail and breaking the webserver / webserver-deploy jobs. Use `--target all` so the wasm-only dependency is seen, and guard against an empty result so any future breakage fails with a clear message instead of a cryptic cargo error. Applied to both wasm justfiles. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01DSAx1G1eMeCYPwNH7WNMVo --- web_ext/sseq_gui/justfile | 5 ++++- web_ext/steenrod_calculator/justfile | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/web_ext/sseq_gui/justfile b/web_ext/sseq_gui/justfile index d0afe131a1..bb067608ea 100644 --- a/web_ext/sseq_gui/justfile +++ b/web_ext/sseq_gui/justfile @@ -40,7 +40,10 @@ setup-wasm: # generated glue and the CLI share an unstable schema and must be # version-matched, so an unpinned install can drift out of sync and break # the build. Deriving the version keeps this in step with the crate. - version="$(cargo tree --package wasm-bindgen --depth 0 --prefix none | head -1 | awk '{gsub(/^v/,"",$2); print $2}')" + # `--target all` is required: wasm-bindgen is a wasm32-only dependency, so a + # host-target `cargo tree` would print nothing and leave the version empty. + version="$(cargo tree --target all --package wasm-bindgen --depth 0 --prefix none | head -1 | awk '{gsub(/^v/,"",$2); print $2}')" + test -n "$version" || { echo "could not determine wasm-bindgen version" >&2; exit 1; } cargo install wasm-bindgen-cli --version "$version" --debug rustup target add wasm32-unknown-unknown # rust-src is required by `-Z build-std` (see the WASM_UNWIND note above). diff --git a/web_ext/steenrod_calculator/justfile b/web_ext/steenrod_calculator/justfile index bdac2e9af0..212168065b 100644 --- a/web_ext/steenrod_calculator/justfile +++ b/web_ext/steenrod_calculator/justfile @@ -24,7 +24,10 @@ setup-wasm: # generated glue and the CLI share an unstable schema and must be # version-matched, so an unpinned install can drift out of sync and break # the build. Deriving the version keeps this in step with the crate. - version="$(cargo tree --package wasm-bindgen --depth 0 --prefix none | head -1 | awk '{gsub(/^v/,"",$2); print $2}')" + # `--target all` so this keeps working even if wasm-bindgen becomes a + # wasm32-only dependency (a host-target `cargo tree` would print nothing). + version="$(cargo tree --target all --package wasm-bindgen --depth 0 --prefix none | head -1 | awk '{gsub(/^v/,"",$2); print $2}')" + test -n "$version" || { echo "could not determine wasm-bindgen version" >&2; exit 1; } cargo install wasm-bindgen-cli --version "$version" --debug rustup target add wasm32-unknown-unknown From cf1e646eb12e33e30f26da2208100eefffd3ac14 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Jul 2026 00:27:52 +0000 Subject: [PATCH 6/6] Address review: fix step label, complete `fix` recipe, document it - ext.yaml: rename the calculator job's mislabeled "Lint sseq_gui wasm" step to "Lint calculator wasm" (it runs the calculator lint, not sseq_gui). - ext/justfile: make `fix` mirror all of `lint`'s clippy configurations (`--no-default-features --profile test` and `--all-targets --profile test`), so `just fix` autofixes everything `just lint` would flag. - ext/README.md: mention `just fix` alongside `just lint` in the Linting section. Skipped CodeRabbit's suggestion to SHA-pin `extractions/setup-just@v4`: the repo consistently pins actions by tag (actions/checkout@v4, dtolnay/rust-toolchain@v1, actions/cache@v4), so a lone SHA-pinned action would break that convention. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01DSAx1G1eMeCYPwNH7WNMVo --- .github/workflows/ext.yaml | 2 +- ext/README.md | 7 ++++++- ext/justfile | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ext.yaml b/.github/workflows/ext.yaml index 5bceade40a..c9107cf76c 100644 --- a/.github/workflows/ext.yaml +++ b/.github/workflows/ext.yaml @@ -379,7 +379,7 @@ jobs: - name: Setup build environment run: cd web_ext/steenrod_calculator && just setup-wasm - - name: Lint sseq_gui wasm + - name: Lint calculator wasm run: cd web_ext/steenrod_calculator && just lint - name: Build wasm diff --git a/ext/README.md b/ext/README.md index 172661a578..eac8133e61 100644 --- a/ext/README.md +++ b/ext/README.md @@ -97,7 +97,12 @@ Lint scripts can be run with just lint ``` -This runs `clippy` and `rustfmt`. +This runs `clippy` and `rustfmt`. To apply the formatting and clippy autofixes +instead of just checking, run + +```shell +just fix +``` ### Tests diff --git a/ext/justfile b/ext/justfile index 41af09b875..c9b3206bd7 100644 --- a/ext/justfile +++ b/ext/justfile @@ -22,10 +22,12 @@ lint: cargo check --workspace --no-default-features --profile test cargo check --workspace --all-targets --all-features --profile test -# Apply the fixes that `lint` only checks: rustfmt formatting + clippy autofixes. +# Apply the fixes that `lint` only checks: rustfmt formatting + clippy autofixes +# (mirrors the clippy configurations run by `lint`). fix: cargo fmt --all - cargo clippy --workspace --all-targets --fix --allow-dirty --allow-staged + cargo clippy --workspace --no-default-features --profile test --fix --allow-dirty --allow-staged + cargo clippy --workspace --all-targets --profile test --fix --allow-dirty --allow-staged docs: # Prevent the cached crates.js from confusing the current run