From 3087c21f4b8d687442f448e6ec74a0a04004aae3 Mon Sep 17 00:00:00 2001 From: shriraj pawar Date: Fri, 17 Apr 2026 11:26:52 +0530 Subject: [PATCH 1/2] fix(chore): migrating from tox to just for better devex --- .github/PULL_REQUEST_TEMPLATE.md | 4 +- .github/workflows/ci.yml | 47 +++++++++++------ CONTRIBUTING.md | 9 ++-- Justfile | 72 +++++++++++++++++++++++++ README.md | 88 ++++++++++++++++++++---------- tox.ini | 91 +++++++++++++++----------------- 6 files changed, 214 insertions(+), 97 deletions(-) create mode 100644 Justfile diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 355f6690..59a7f36a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,9 +7,9 @@ ## ✅ Checklist -- [ ] Ran `tox` checks to avoid unnecessary CI fails: +- [ ] Ran local quality checks to avoid unnecessary CI fails: ```console - uvx tox + just check ``` - [ ] Considered adding appropriate tests for the changes. - [ ] Considered updating the online docs in the [./docs/](/leanEthereum/leanSpec/tree/main/docs/) directory. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b579f1f..a33be85e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,8 +37,13 @@ jobs: enable-cache: true cache-dependency-glob: "pyproject.toml" - - name: Run all quality checks via tox - run: uvx tox -e all-checks + - name: Install just + uses: taiki-e/install-action@v2 + with: + tool: just + + - name: Run all quality checks + run: just check test: name: Tests - Python ${{ matrix.python-version }} on ${{ matrix.os }} @@ -63,8 +68,13 @@ jobs: enable-cache: true cache-dependency-glob: "pyproject.toml" - - name: Run tests via tox - run: uvx tox -e pytest + - name: Install just + uses: taiki-e/install-action@v2 + with: + tool: just + + - name: Run tests + run: just test coverage-gate: name: Coverage gate - Python 3.12 @@ -84,8 +94,13 @@ jobs: enable-cache: true cache-dependency-glob: "pyproject.toml" + - name: Install just + uses: taiki-e/install-action@v2 + with: + tool: just + - name: Run tests with coverage gate - run: uvx tox -e pytest-cov-gate + run: just test-cov-gate fill-tests: name: Fill test fixtures - Python 3.14 @@ -105,11 +120,13 @@ jobs: enable-cache: true cache-dependency-glob: "pyproject.toml" - - name: Sync dependencies - run: uv sync --no-progress + - name: Install just + uses: taiki-e/install-action@v2 + with: + tool: just - name: Fill test fixtures - run: uv run fill --fork=Lstar --clean -n auto + run: just fill interop-tests: name: Interop tests - Multi-node consensus @@ -130,14 +147,12 @@ jobs: enable-cache: true cache-dependency-glob: "pyproject.toml" + - name: Install just + uses: taiki-e/install-action@v2 + with: + tool: just + - name: Run interop tests - run: | - uv run pytest tests/interop/ \ - -v \ - --no-cov \ - --timeout=120 \ - -x \ - --tb=short \ - --log-cli-level=INFO + run: just interop env: LEAN_ENV: test diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6b7a0b65..6f818343 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,9 +5,10 @@ 1. Fork and clone the repository 2. Install dependencies: `uv sync` 3. Make your changes -4. Run checks: `uvx tox -e all-checks` -5. Run tests: `uvx tox -e pytest` -6. Submit a pull request +4. Install `just`: `uv tool install just-bin` +5. Run checks: `just check` +6. Run tests: `just test` +7. Submit a pull request ## Pull Request Guidelines @@ -22,7 +23,7 @@ - **Type hints**: Required for all functions and methods - **Docstrings**: Use Google style for public APIs - **Line length**: 100 characters (enforced by ruff) -- **Formatting**: Run `uvx tox -e fix` to auto-format +- **Formatting**: Run `just fix` to auto-format ## Adding New Subspecifications diff --git a/Justfile b/Justfile new file mode 100644 index 00000000..7135372c --- /dev/null +++ b/Justfile @@ -0,0 +1,72 @@ +set positional-arguments := true + +alias help := default + +[default] +default: + @just --list + +[group('quality')] +check: lint typecheck spellcheck mdformat + +[group('quality')] +lint *args: + uv run --group lint ruff check --no-fix --show-fixes "$@" + +[group('quality')] +format *args: + uv run --group lint ruff format "$@" + +[group('quality')] +fix: + uv run --group lint ruff check --fix + uv run --group lint ruff format + uv run --group docs mdformat docs/ + +[group('quality')] +typecheck *args: + uv run --group lint ty check "$@" + +[group('quality')] +spellcheck *args: + uv run --group lint codespell src tests packages docs README.md CLAUDE.md --skip="*.lock,*.svg,.git,__pycache__,.pytest_cache,tests/lean_spec/snappy/testdata" --ignore-words=.codespell-ignore-words.txt "$@" + +[group('quality')] +mdformat *args: + uv run --group docs mdformat --check docs/ "$@" + +[group('tests')] +test *args: + uv run --group test pytest tests -n auto --maxprocesses=10 --durations=10 --dist=worksteal "$@" + +[group('tests')] +test-cov *args: + uv run --group test pytest --cov --cov-report=html --cov-report=term "$@" + +[group('tests')] +test-cov-gate *args: + uv run --group test pytest --cov --cov-report=term-missing --cov-fail-under=80 "$@" + +[group('tests')] +test-consensus *args: + uv run --group test pytest -n auto --maxprocesses=10 --durations=10 --dist=worksteal tests/lean_spec/subspecs/containers tests/lean_spec/subspecs/forkchoice tests/lean_spec/subspecs/networking "$@" + +[group('tests')] +fill *args: + uv run --group test fill --fork=Lstar --clean -n auto "$@" + +[group('tests')] +apitest server_url *args: + uv run --group test apitest "{{server_url}}" "$@" + +[group('tests')] +interop *args: + uv run --group test pytest tests/interop/ -v --no-cov --timeout=120 -x --tb=short --log-cli-level=INFO "$@" + +[group('docs')] +docs *args: + uv run --group docs mkdocs build "$@" + +[group('docs')] +docs-serve *args: + uv run --group docs mkdocs serve "$@" diff --git a/README.md b/README.md index 657f019a..2e9db996 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,20 @@ The Lean Ethereum protocol specifications and cryptographic subspecifications. curl -LsSf https://astral.sh/uv/install.sh | sh ```` +#### Installing just + +[`just`](https://just.systems/) is the task runner used for common developer +workflows in this repository. + +```bash +# Recommended cross-platform install +uv tool install just-bin + +# Alternatives +brew install just +apt install just +``` + #### Installing Python 3.12+ This project requires Python 3.12 or later and should be installed via `uv`: @@ -57,8 +71,11 @@ cd leanSpec # Install and sync project and dev dependencies, using `uv.lock` versions uv sync +# See the available repo tasks +just + # Run tests to verify setup -uv run pytest +just test ``` ### Project Structure @@ -97,7 +114,10 @@ uv sync ### Running Tests ```bash -# Run all tests from workspace root +# Run the default test suite +just test + +# Run all tests from workspace root without just uv run pytest # Run tests in parallel, utilizing all available CPU cores @@ -121,37 +141,51 @@ uv run fill --clean --fork=devnet --scheme=prod # Run API conformance tests against an external client implementation # Usage: uv run apitest [pytest-args] uv run apitest http://localhost:5052 + +# Same API conformance test through the task runner +just apitest http://localhost:5052 ``` ### Code Quality ```bash +# Run the full quality gate +just check + # Check code style and errors -uv run ruff check +just lint # Auto-fix issues -uv run ruff check --fix +just fix # Format code -uv run ruff format +just format # Type checking -uv run ty check +just typecheck ``` -### Using Tox for Comprehensive Checks +### Using just for Common Tasks -You can use `tox` with `uvx`, which: -* Creates a temporary environment just for `tox` -* Doesn't require `uv sync` first -* Uses `tox-uv` for faster dependency installation +Run `just` with no arguments to see the available recipes. `just` is the +primary command surface for contributors, while raw `uv run ...` commands remain +available when you want to invoke tools directly. ```bash -# Run specific environment, like "all quality checks" (lint, typecheck, spellcheck) -uvx tox -e all-checks +# List available tasks +just + +# Run quality checks +just check + +# Run tests +just test + +# Build documentation +just docs -# Run all tox environments (all checks + tests + docs) -uvx tox +# Generate consensus fixtures +just fill ``` ### Documentation @@ -210,7 +244,7 @@ def test_withdrawal_amount_above_uint64_max(): - **uv**: Fast Python package manager - like npm/yarn but for Python - **ruff**: Linter and formatter - **ty**: Type checker -- **tox**: Automation tool for running tests across multiple environments (used via `uvx`) +- **just**: Task runner for repository workflows such as checks, tests, docs, and fixture generation - **mkdocs**: Documentation generator - write docs in Markdown, serve them locally ## Common Commands Reference @@ -218,16 +252,16 @@ def test_withdrawal_amount_above_uint64_max(): | Task | Command | |-----------------------------------------------|--------------------------------------------------------| | Install and sync project and dev dependencies | `uv sync` | -| Run tests | `uv run pytest ...` | -| Format code | `uv run ruff format` | -| Lint code | `uv run ruff check` | -| Fix lint errors | `uv run ruff check --fix` | -| Type check | `uv run ty check` | -| Build docs | `uv run mkdocs build` | -| Serve docs | `uv run mkdocs serve` | -| Run everything (checks + tests + docs) | `uvx tox` | -| Run all quality checks (no tests/docs) | `uvx tox -e all-checks` | -| Test external client API conformance | `uv run apitest http://localhost:5052` | +| List repo tasks | `just` | +| Run quality checks | `just check` | +| Run tests | `just test` | +| Format code | `just format` | +| Fix lint and formatting | `just fix` | +| Type check | `just typecheck` | +| Build docs | `just docs` | +| Serve docs | `just docs-serve` | +| Generate consensus fixtures | `just fill` | +| Test external client API conformance | `just apitest http://localhost:5052` | | Run consensus node | `uv run python -m lean_spec --genesis config.yaml` | | Build Docker test image | `docker build -t lean-spec:test .` | | Build Docker node image | `docker build --target node -t lean-spec:node .` | @@ -265,7 +299,7 @@ docker run --rm lean-spec:test # Run tests in parallel docker run --rm lean-spec:test uv run pytest -n auto -# Run the fill command +# Run the fill command directly docker run --rm lean-spec:test uv run fill --clean --fork=devnet ``` diff --git a/tox.ini b/tox.ini index ed9aa382..71e8d1f5 100644 --- a/tox.ini +++ b/tox.ini @@ -1,81 +1,76 @@ [tox] min_version = 4.0 -requires = - tox >=4.32.0,<5 - tox-uv >=1.29 -env_list = - # defines what runs when `uvx tox` is executed with no `-e` argument - all-checks - pytest - docs-build +env_list = all-checks [testenv] -uv_python = >=3.12 -package = editable -runner = uv-venv-lock-runner -set_env = - NUMBA_DISABLE_JIT = 1 +description = leanSpec now uses just for task orchestration +skip_install = true +allowlist_externals = printf, false +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Install just with:\n uv tool install just-bin\n\n Run \033[1mjust\033[0m to see available recipes.\n\n' + false [testenv:all-checks] -description = Run all quality checks (lint, typecheck, spellcheck, mdformat) commands = - {[testenv:lint]commands} - {[testenv:typecheck]commands} - {[testenv:spellcheck]commands} - {[testenv:mdformat]commands} + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust check\033[0m\n\n' + false [testenv:lint] -description = Lint and code formatting checks (ruff) commands = - ruff check --no-fix --show-fixes - ruff format --check + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust lint\033[0m\n\n' + false [testenv:fix] -description = Auto-fix linting and formatting issues (ruff) commands = - ruff check --fix - ruff format + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust fix\033[0m\n\n' + false [testenv:typecheck] -description = Run type checking (ty) -commands = ty check +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust typecheck\033[0m\n\n' + false [testenv:spellcheck] -description = Run spell checking (codespell) -commands = codespell src tests packages docs README.md CLAUDE.md --skip="*.lock,*.svg,.git,__pycache__,.pytest_cache,tests/lean_spec/snappy/testdata" --ignore-words=.codespell-ignore-words.txt +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust spellcheck\033[0m\n\n' + false [testenv:mdformat] -description = Check markdown formatting for docs (mdformat) -commands = mdformat docs/ +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust mdformat\033[0m\n\n' + false [testenv:fill] -description = Generate consensus layer test fixtures -commands = fill --fork=Devnet --clean -n auto {posargs} +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust fill\033[0m\n\n' + false [testenv:pytest] -description = Run tests (pytest) -# parallelize with `auto` but keep max processes reasonable for CI -commands = pytest {posargs} tests -n auto --maxprocesses=10 --durations=10 --dist=worksteal +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust test\033[0m\n\n' + false [testenv:pytest-cov] -description = Run tests with coverage (pytest) -commands = pytest --cov --cov-report=html --cov-report=term {posargs} +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust test-cov\033[0m\n\n' + false [testenv:pytest-cov-gate] -description = Run tests with coverage gate (fails below 80%) -commands = pytest --cov --cov-report=term-missing --cov-fail-under=80 {posargs} +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust test-cov-gate\033[0m\n\n' + false [testenv:pytest-consensus] -description = Run consensus tests (pytest) -commands = pytest {posargs} -n auto --maxprocesses=10 --durations=10 --dist=worksteal \ - tests/lean_spec/subspecs/containers \ - tests/lean_spec/subspecs/forkchoice \ - tests/lean_spec/subspecs/networking +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust test-consensus\033[0m\n\n' + false [testenv:docs-build] -description = Build documentation (mkdocs) -commands = mkdocs build {posargs} +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust docs\033[0m\n\n' + false [testenv:docs-serve] -description = Serve documentation locally (mkdocs) -commands = mkdocs serve {posargs} +commands = + printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust docs-serve\033[0m\n\n' + false From c23827b44ff79d7f95450fa19b5d02ac2446b675 Mon Sep 17 00:00:00 2001 From: fselmo Date: Tue, 5 May 2026 10:27:49 -0600 Subject: [PATCH 2/2] chore(tools): remove tox, use just; add list descriptions; cleanup --- .claude/agents/py-architect.md | 2 +- .claude/rules/workflow.md | 10 ++-- .claude/skills/checks/SKILL.md | 3 +- .claude/skills/fill/SKILL.md | 9 ++-- .claude/skills/fix/SKILL.md | 2 +- .claude/skills/review/SKILL.md | 4 +- .claude/skills/test/SKILL.md | 2 +- .claude/skills/workflows/SKILL.md | 20 ++++---- .github/workflows/ci.yml | 2 +- .github/workflows/prod-vectors.yml | 8 +-- CLAUDE.md | 2 +- Justfile | 78 ++++++++++++++++++++++++++++-- README.md | 14 +++--- tox.ini | 76 ----------------------------- 14 files changed, 115 insertions(+), 117 deletions(-) delete mode 100644 tox.ini diff --git a/.claude/agents/py-architect.md b/.claude/agents/py-architect.md index 554151ff..85664279 100644 --- a/.claude/agents/py-architect.md +++ b/.claude/agents/py-architect.md @@ -140,7 +140,7 @@ Follow this systematic approach: 2. **Identify** - Find code smells, duplication, unclear intent, type gaps 3. **Preserve** - Ensure tests exist before making changes 4. **Transform** - Make small, incremental improvements -5. **Verify** - Confirm tests pass, types check (`uvx tox -e typecheck`), lints clean (`uv run ruff check`) +5. **Verify** - Confirm tests pass, types check (`just typecheck`), lints clean (`just lint`) ## Quality Bar diff --git a/.claude/rules/workflow.md b/.claude/rules/workflow.md index b830a3a3..0d00fbca 100644 --- a/.claude/rules/workflow.md +++ b/.claude/rules/workflow.md @@ -14,11 +14,11 @@ uv run fill --fork=lstar --clean -n auto --scheme=prod # Generate test vectors ## Code Quality ```bash -uv run ruff format # Format code -uv run ruff check --fix # Lint and fix -uvx tox -e typecheck # Type check -uvx tox -e all-checks # All quality checks -uvx tox # Everything (checks + tests + docs) +just format # Format code +just fix # Auto-fix lint, formatting, and markdown +just typecheck # Type check +just check # All quality checks (lint, format, typecheck, spell, mdformat, lock) +just # List all available recipes ``` ## Common Tasks diff --git a/.claude/skills/checks/SKILL.md b/.claude/skills/checks/SKILL.md index 12fc1ed3..a082dffb 100644 --- a/.claude/skills/checks/SKILL.md +++ b/.claude/skills/checks/SKILL.md @@ -10,7 +10,7 @@ Run the complete quality check suite. ## Command ```bash -uvx tox -e all-checks +just check ``` ## What It Runs @@ -20,6 +20,7 @@ uvx tox -e all-checks 3. `ty check` - Type checking 4. `codespell` - Spell checking 5. `mdformat` - Markdown formatting +6. `uv lock --check` - Lockfile drift ## When to Use diff --git a/.claude/skills/fill/SKILL.md b/.claude/skills/fill/SKILL.md index dde3c891..22e3eed4 100644 --- a/.claude/skills/fill/SKILL.md +++ b/.claude/skills/fill/SKILL.md @@ -10,7 +10,7 @@ Run the test filler to generate consensus layer test fixtures. ## Default Usage ```bash -uvx tox -e fill +uv run fill --fork=Lstar --clean -n auto ``` ## Options @@ -18,13 +18,14 @@ uvx tox -e fill Pass additional arguments after `--`: - `/fill -- --scheme=prod` - Use production signature scheme (slower) -- `/fill -- --fork=Electra` - Generate for Electra fork +- `/fill -- --fork=` - Generate for a different fork - `/fill -- path/to/test.py` - Generate fixtures for specific test file ## What It Does -Runs `fill --fork=Devnet --clean -n auto` via tox, which: - 1. Discovers tests in `tests/consensus/` 2. Executes spec tests to generate fixtures 3. Outputs JSON fixtures to `fixtures/consensus/` + +The `just fill-ci` recipe wraps the same command for CI; contributors should +invoke `uv run fill` directly so flags like `--fork` and `--clean` stay visible. diff --git a/.claude/skills/fix/SKILL.md b/.claude/skills/fix/SKILL.md index d0dc287a..125ae6f9 100644 --- a/.claude/skills/fix/SKILL.md +++ b/.claude/skills/fix/SKILL.md @@ -10,7 +10,7 @@ Automatically fix linting and formatting issues. ## Command ```bash -uvx tox -e fix +just fix ``` ## What It Fixes diff --git a/.claude/skills/review/SKILL.md b/.claude/skills/review/SKILL.md index 0dd4db72..0a3156d8 100644 --- a/.claude/skills/review/SKILL.md +++ b/.claude/skills/review/SKILL.md @@ -51,6 +51,6 @@ A concise checklist distilled from CLAUDE.md for reviewing leanSpec code. ## Before Committing ```bash -uvx tox -e fix # Auto-fix formatting -uvx tox -e all-checks # Verify all checks pass +just fix # Auto-fix lint, formatting, and markdown +just check # Verify all checks pass ``` diff --git a/.claude/skills/test/SKILL.md b/.claude/skills/test/SKILL.md index ce4250d5..d3846188 100644 --- a/.claude/skills/test/SKILL.md +++ b/.claude/skills/test/SKILL.md @@ -10,7 +10,7 @@ Run pytest unit tests. ## Default ```bash -uvx tox -e pytest +just test ``` ## Options diff --git a/.claude/skills/workflows/SKILL.md b/.claude/skills/workflows/SKILL.md index ce2d482c..7456cf28 100644 --- a/.claude/skills/workflows/SKILL.md +++ b/.claude/skills/workflows/SKILL.md @@ -11,13 +11,13 @@ Common developer workflows and commands for working in leanSpec. ```bash # Single test file -uvx tox -e pytest -- tests/lean_spec/subspecs/networking/discovery/test_transport.py -v +just test tests/lean_spec/subspecs/networking/discovery/test_transport.py -v # Single test class or method -uvx tox -e pytest -- -k "TestDiscoveryTransport::test_start" -v +just test -k "TestDiscoveryTransport::test_start" -v # With print output visible -uvx tox -e pytest -- -s -k "test_name" +just test -s -k "test_name" ``` ## Resolving Type Errors @@ -26,10 +26,10 @@ The project uses two type checkers. Run them separately to isolate issues: ```bash # Full type check (ty — the primary checker used in CI) -uvx tox -e typecheck +just typecheck # Lint check (ruff — catches style and import issues) -uvx tox -e lint +just lint ``` Common type error patterns: @@ -43,7 +43,7 @@ After running tests, coverage reports are generated: ```bash # View coverage in terminal -uvx tox -e pytest +just test-cov # Open HTML report open htmlcov/index.html @@ -54,14 +54,14 @@ open htmlcov/index.html Interop tests are excluded from the default test run. Run them explicitly: ```bash -uv run pytest tests/interop/ -v +just interop ``` ## Spell Check Failures ```bash # Run spell check -uvx tox -e spellcheck +just spellcheck # Add legitimate words to the ignore list echo "newword" >> .codespell-ignore-words.txt @@ -71,11 +71,11 @@ echo "newword" >> .codespell-ignore-words.txt ```bash # Check markdown formatting (docs only) -uvx tox -e mdformat +just mdformat ``` ## Common Pitfalls - **Tests pass locally but CI fails**: CI runs checks across Python 3.12, 3.13, and 3.14. Ensure no version-specific syntax is used. - **`ruff format` changes after `ruff check --fix`**: Always run format after fix — the fixer doesn't guarantee formatting compliance. -- **Import ordering issues**: Run `uvx tox -e fix` to auto-sort imports. +- **Import ordering issues**: Run `just fix` to auto-sort imports. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a33be85e..e4bbdba5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -126,7 +126,7 @@ jobs: tool: just - name: Fill test fixtures - run: just fill + run: just fill-ci interop-tests: name: Interop tests - Multi-node consensus diff --git a/.github/workflows/prod-vectors.yml b/.github/workflows/prod-vectors.yml index 5b9ecf98..b42eaf0c 100644 --- a/.github/workflows/prod-vectors.yml +++ b/.github/workflows/prod-vectors.yml @@ -65,8 +65,10 @@ jobs: enable-cache: true cache-dependency-glob: "pyproject.toml" - - name: Sync dependencies - run: uv sync --no-progress + - name: Install just + uses: taiki-e/install-action@v2 + with: + tool: just - name: Restore prod key cache id: key-cache @@ -87,7 +89,7 @@ jobs: key: prod-keys-${{ hashFiles('src/lean_spec/subspecs/xmss/**', 'src/lean_spec/subspecs/poseidon2/**') }} - name: Fill production test fixtures - run: uv run fill --fork=Lstar --scheme prod --clean -n auto + run: just fill-ci --scheme=prod - name: Bundle keys with fixtures run: | diff --git a/CLAUDE.md b/CLAUDE.md index f9340d3b..d57f03d3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,7 +19,7 @@ subspecifications that the Lean Ethereum protocol relies on. - Use Pydantic models for validation - Keep specs simple, readable, and clear - Repository is `leanSpec` not `lean-spec` -- **Always run linter checks before finishing**: Run `uvx tox -e all-checks` at the end of any code changes to ensure all linting, formatting, type checking, and spell checking passes. +- **Always run linter checks before finishing**: Run `just check` at the end of any code changes to ensure all linting, formatting, type checking, and spell checking passes. - **CRITICAL - NO BACKWARD COMPATIBILITY**: This is a STRICT requirement. NEVER add backward compatibility code under any circumstances. This means: - NO legacy constants (like `KEY_TYPE_ED25519 = KeyType.ED25519`) - NO wrapper functions that delegate to new classes diff --git a/Justfile b/Justfile index 7135372c..88d20a35 100644 --- a/Justfile +++ b/Justfile @@ -2,71 +2,141 @@ set positional-arguments := true alias help := default -[default] +# List available recipes default: @just --list +# Run all quality checks (lint, format, typecheck, spellcheck, mdformat, lock) [group('quality')] -check: lint typecheck spellcheck mdformat +check: lint format-check typecheck spellcheck mdformat lock-check +# Lint with ruff (no auto-fix) [group('quality')] lint *args: uv run --group lint ruff check --no-fix --show-fixes "$@" +# Format code with ruff [group('quality')] format *args: uv run --group lint ruff format "$@" +# Verify formatting with ruff (no changes) +[group('quality')] +format-check *args: + uv run --group lint ruff format --check "$@" + +# Auto-fix lint, formatting, and markdown issues [group('quality')] fix: uv run --group lint ruff check --fix uv run --group lint ruff format uv run --group docs mdformat docs/ +# Type check with ty [group('quality')] typecheck *args: uv run --group lint ty check "$@" +# Spell check source, tests, packages, and docs [group('quality')] spellcheck *args: uv run --group lint codespell src tests packages docs README.md CLAUDE.md --skip="*.lock,*.svg,.git,__pycache__,.pytest_cache,tests/lean_spec/snappy/testdata" --ignore-words=.codespell-ignore-words.txt "$@" +# Verify markdown formatting in docs/ [group('quality')] mdformat *args: uv run --group docs mdformat --check docs/ "$@" +# Verify uv.lock is up to date +[group('quality')] +lock-check: + #!/usr/bin/env bash + if ! uv lock --check; then + echo "" + echo "uv.lock is out of date. To sync:" + echo " uv lock" + echo "" + echo "Then commit the updated uv.lock." + exit 1 + fi + +# Run unit tests in parallel [group('tests')] test *args: uv run --group test pytest tests -n auto --maxprocesses=10 --durations=10 --dist=worksteal "$@" +# Run unit tests with coverage report (HTML + terminal) [group('tests')] test-cov *args: uv run --group test pytest --cov --cov-report=html --cov-report=term "$@" +# Run unit tests with coverage gate (fails below 80%) [group('tests')] test-cov-gate *args: uv run --group test pytest --cov --cov-report=term-missing --cov-fail-under=80 "$@" +# Run consensus-only unit tests (containers, forkchoice, networking) [group('tests')] test-consensus *args: uv run --group test pytest -n auto --maxprocesses=10 --durations=10 --dist=worksteal tests/lean_spec/subspecs/containers tests/lean_spec/subspecs/forkchoice tests/lean_spec/subspecs/networking "$@" -[group('tests')] -fill *args: +# Canonical CI fixture run; contributors should use `uv run fill` directly +[group('tests'), private] +fill-ci *args: uv run --group test fill --fork=Lstar --clean -n auto "$@" +# Run API conformance tests against an external client [group('tests')] apitest server_url *args: uv run --group test apitest "{{server_url}}" "$@" +# Run multi-node interop tests [group('tests')] interop *args: uv run --group test pytest tests/interop/ -v --no-cov --timeout=120 -x --tb=short --log-cli-level=INFO "$@" +# Build documentation site with mkdocs [group('docs')] docs *args: uv run --group docs mkdocs build "$@" +# Serve documentation locally with mkdocs (live reload) [group('docs')] docs-serve *args: uv run --group docs mkdocs serve "$@" + +# Print the command to install shell completions for just recipes +[group('housekeeping')] +shell-completions: + #!/usr/bin/env bash + case "$(basename "$SHELL")" in + bash) + echo "Run the following commands to install just completions for bash:" + echo "" + echo " mkdir -p ~/.local/share/bash-completion/completions" + echo " just --completions bash > ~/.local/share/bash-completion/completions/just" + ;; + zsh) + echo "Run the following commands to install just completions for zsh:" + echo "" + echo " mkdir -p ~/.zsh/completions" + echo " just --completions zsh > ~/.zsh/completions/_just" + echo "" + echo "Then add to your .zshrc:" + echo "" + echo " fpath=(~/.zsh/completions \$fpath)" + echo " autoload -U compinit" + echo " compinit" + ;; + fish) + echo "Run the following commands to install just completions for fish:" + echo "" + echo " mkdir -p ~/.config/fish/completions" + echo " just --completions fish > ~/.config/fish/completions/just.fish" + ;; + *) + echo "See the link below for instructions for your shell." + ;; + esac + echo "" + echo "For more details, see https://just.systems/man/en/shell-completion-scripts.html" diff --git a/README.md b/README.md index 2e9db996..9e7a9e53 100644 --- a/README.md +++ b/README.md @@ -130,13 +130,13 @@ uv run pytest -n 4 uv run pytest -m "not slow" # Fill test vectors from pytest specs. -# Usage: uv run fill --clean --fork=devnet [--scheme=] [--output=] +# Usage: uv run fill --clean --fork=Lstar [--scheme=] [--output=] # --clean Overwrite existing fixtures -# --fork Target fork (default: devnet) +# --fork Target fork (e.g., Lstar) # --scheme XMSS signature scheme: "test" (default, fast) or "prod" (prod config, slower) # --output Optional directory for filled fixtures -uv run fill --clean --fork=devnet -uv run fill --clean --fork=devnet --scheme=prod +uv run fill --clean --fork=Lstar +uv run fill --clean --fork=Lstar --scheme=prod # Run API conformance tests against an external client implementation # Usage: uv run apitest [pytest-args] @@ -185,7 +185,7 @@ just test just docs # Generate consensus fixtures -just fill +uv run fill --fork=Lstar --clean -n auto ``` ### Documentation @@ -260,7 +260,7 @@ def test_withdrawal_amount_above_uint64_max(): | Type check | `just typecheck` | | Build docs | `just docs` | | Serve docs | `just docs-serve` | -| Generate consensus fixtures | `just fill` | +| Generate consensus fixtures | `uv run fill --fork=Lstar --clean -n auto` | | Test external client API conformance | `just apitest http://localhost:5052` | | Run consensus node | `uv run python -m lean_spec --genesis config.yaml` | | Build Docker test image | `docker build -t lean-spec:test .` | @@ -300,7 +300,7 @@ docker run --rm lean-spec:test docker run --rm lean-spec:test uv run pytest -n auto # Run the fill command directly -docker run --rm lean-spec:test uv run fill --clean --fork=devnet +docker run --rm lean-spec:test uv run fill --clean --fork=Lstar ``` ### Running a Consensus Node with Docker diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 71e8d1f5..00000000 --- a/tox.ini +++ /dev/null @@ -1,76 +0,0 @@ -[tox] -min_version = 4.0 -env_list = all-checks - -[testenv] -description = leanSpec now uses just for task orchestration -skip_install = true -allowlist_externals = printf, false -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Install just with:\n uv tool install just-bin\n\n Run \033[1mjust\033[0m to see available recipes.\n\n' - false - -[testenv:all-checks] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust check\033[0m\n\n' - false - -[testenv:lint] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust lint\033[0m\n\n' - false - -[testenv:fix] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust fix\033[0m\n\n' - false - -[testenv:typecheck] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust typecheck\033[0m\n\n' - false - -[testenv:spellcheck] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust spellcheck\033[0m\n\n' - false - -[testenv:mdformat] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust mdformat\033[0m\n\n' - false - -[testenv:fill] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust fill\033[0m\n\n' - false - -[testenv:pytest] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust test\033[0m\n\n' - false - -[testenv:pytest-cov] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust test-cov\033[0m\n\n' - false - -[testenv:pytest-cov-gate] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust test-cov-gate\033[0m\n\n' - false - -[testenv:pytest-consensus] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust test-consensus\033[0m\n\n' - false - -[testenv:docs-build] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust docs\033[0m\n\n' - false - -[testenv:docs-serve] -commands = - printf '\n\033[1m leanSpec has migrated from tox to just.\033[0m\n\n Use:\n \033[1mjust docs-serve\033[0m\n\n' - false