Skip to content

Commit 3b2cf74

Browse files
feat(tools): add cargo-stow for Cargo.toml validation and enforcement (#2961)
## Summary Introduces `cargo stow`, a workspace linting tool that validates and fixes Cargo.toml files to enforce project conventions. ### Features - **Validation Rules:** - Flat crate structure (no nested crates under `crates/`) - Crate naming conventions (`baml_<word>` or `baml_<prefix>_<word>`) - Test crate pairing (e.g., `baml_ide_tests` requires `baml_ide`) - Workspace dependency format (`{ workspace = true }`) - Dependency restriction rules (e.g., `anyhow` only in CLI/test crates) - Dependency sorting (internal deps first, then external) - **Auto-fix capability:** Run `cargo stow --fix` to automatically fix sortable/formattable issues - **Runtime configuration:** Configure via `stow.toml` or `[workspace.metadata.stow]` in Cargo.toml - no recompilation needed to change rules ### Integration - Added `cargo-stow` CI job that runs on every PR - Integrated into pre-commit hooks via `setup-hooks.sh` ### Usage ```bash # Check for validation errors cargo stow --check # Automatically fix issues cargo stow --fix # Verbose output cargo stow --check --verbose ``` ## Test plan - [x] `cargo stow --check` passes on the current workspace - [x] Pre-commit hook runs stow check - [x] CI workflow includes cargo-stow job --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
1 parent 221c79e commit 3b2cf74

35 files changed

Lines changed: 5256 additions & 3368 deletions

File tree

.github/workflows/cargo-tests.reusable.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ jobs:
7070
working-directory: baml_language
7171

7272
- name: "Clippy (wasm)"
73-
run: cargo clippy --workspace --exclude baml_tools_onionskin --exclude baml_lsp --exclude baml_cli --target wasm32-unknown-unknown --all-features --locked -- -D warnings
73+
run: cargo clippy --workspace --exclude baml_tools_onionskin --exclude baml_lsp --exclude baml_cli --exclude baml_tools_stow --target wasm32-unknown-unknown --all-features --locked -- -D warnings
7474
working-directory: baml_language
7575

7676
cargo-test-linux:
@@ -204,8 +204,8 @@ jobs:
204204

205205
- name: "Build for WASM"
206206
run: |
207-
cargo build --workspace --target wasm32-unknown-unknown --exclude baml_tools_onionskin --exclude baml_lsp --exclude baml_cli --no-default-features
208-
cargo build --workspace --target wasm32-unknown-unknown --exclude baml_tools_onionskin --exclude baml_lsp --exclude baml_cli --no-default-features --release
207+
cargo build --workspace --target wasm32-unknown-unknown --exclude baml_tools_onionskin --exclude baml_lsp --exclude baml_cli --exclude baml_tools_stow --no-default-features
208+
cargo build --workspace --target wasm32-unknown-unknown --exclude baml_tools_onionskin --exclude baml_lsp --exclude baml_cli --exclude baml_tools_stow --no-default-features --release
209209
working-directory: baml_language
210210

211211
- name: "Check WASM size"

.github/workflows/ci.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,31 @@ jobs:
200200
echo "changed=true" >> "$GITHUB_OUTPUT"
201201
fi
202202
203+
# Lint checks
204+
cargo-stow:
205+
name: "Cargo Stow"
206+
runs-on: ubuntu-latest
207+
needs: determine_changes
208+
if: needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/canary'
209+
timeout-minutes: 10
210+
steps:
211+
- name: "Checkout Branch"
212+
uses: actions/checkout@v4
213+
with:
214+
persist-credentials: false
215+
216+
- uses: Swatinem/rust-cache@v2
217+
with:
218+
workspaces: "baml_language -> target"
219+
220+
- name: "Install Rust toolchain"
221+
run: rustup show
222+
working-directory: baml_language
223+
224+
- name: "Run cargo stow --check"
225+
run: cargo run -p baml_tools_stow --release -- stow --check
226+
working-directory: baml_language
227+
203228
# Call reusable workflows
204229
cargo-tests:
205230
name: "Cargo Tests"
@@ -300,6 +325,7 @@ jobs:
300325
runs-on: ubuntu-latest
301326
if: always()
302327
needs:
328+
- cargo-stow
303329
- cargo-tests
304330
- wasm-pack-tests
305331
- beps
@@ -309,6 +335,11 @@ jobs:
309335
steps:
310336
- name: "Check test results"
311337
run: |
338+
if [[ "${{ needs.cargo-stow.result }}" != "success" && "${{ needs.cargo-stow.result }}" != "skipped" ]]; then
339+
echo "::error::Cargo stow check failed"
340+
exit 1
341+
fi
342+
312343
if [[ "${{ needs.cargo-tests.result }}" != "success" && "${{ needs.cargo-tests.result }}" != "skipped" ]]; then
313344
echo "::error::Cargo tests failed"
314345
exit 1

baml_language/.claude/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
"Bash(cargo clippy:*)",
2121
"WebSearch",
2222
"Bash(cargo run:*)",
23-
"Bash(cargo check:*)"
23+
"Bash(cargo check:*)",
24+
"Bash(git add:*)",
25+
"Bash(git commit -m \"$\\(cat <<''EOF''\nfeat\\(tools\\): add cargo-stow for Cargo.toml validation and enforcement\n\nIntroduces `cargo stow`, a workspace linting tool that validates and fixes\nCargo.toml files to enforce project conventions:\n\n- Flat crate structure \\(no nested crates\\)\n- Crate naming conventions \\(baml_* with approved prefixes\\)\n- Test crate pairing requirements\n- Workspace dependency format enforcement\n- Dependency restriction rules \\(e.g., anyhow only in CLI crates\\)\n- Dependency sorting \\(internal deps first, then external\\)\n\nConfiguration via stow.toml or [workspace.metadata.stow] in Cargo.toml\nallows changing rules without recompilation.\n\nIntegrated into:\n- CI workflow \\(cargo-stow job\\)\n- Pre-commit hooks \\(via setup-hooks.sh\\)\nEOF\n\\)\")"
2426
]
2527
}
2628
}

0 commit comments

Comments
 (0)