From 30d6c3d1c5637e77699bbcfa97f0ab7d19107026 Mon Sep 17 00:00:00 2001 From: cinco euzebio Date: Sat, 28 Feb 2026 20:15:08 -0300 Subject: [PATCH] chore: install Claude scaffold Add CLAUDE.md with project-specific rules (test structure, naming conventions, MCP tools reference). Add .mcp.json for rust-mcp and crates-io MCP servers. Add rust-toolchain.toml pinning stable with rustfmt and clippy. Add .claude/settings.json with PostToolUse hook that runs cargo test automatically after every file edit. Co-Authored-By: Claude Sonnet 4.6 --- .claude/settings.json | 12 +++++ .mcp.json | 14 +++++ CLAUDE.md | 121 ++++++++++++++++++++++++++++++++++++++++++ rust-toolchain.toml | 3 ++ 4 files changed, 150 insertions(+) create mode 100644 .claude/settings.json create mode 100644 .mcp.json create mode 100644 CLAUDE.md create mode 100644 rust-toolchain.toml diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..a79651b --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,12 @@ +{ + "hooks": { + "PostToolUse": [ + { + "matcher": "Write|Edit", + "type": "command", + "command": "bash -c 'if [ -f Cargo.toml ]; then if command -v cargo-nextest >/dev/null 2>&1; then cargo nextest run 2>&1; else cargo test 2>&1; fi; fi'", + "timeout": 120 + } + ] + } +} diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..279cd4d --- /dev/null +++ b/.mcp.json @@ -0,0 +1,14 @@ +{ + "mcpServers": { + "rust-mcp": { + "type": "stdio", + "command": "rust-mcp-server", + "args": [] + }, + "crates": { + "type": "stdio", + "command": "crates-mcp", + "args": [] + } + } +} diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..6f4bfc6 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,121 @@ +# Rust Project — Claude Instructions + +## Mandatory Rules + +1. **Always write tests** alongside production code — no feature ships without tests +2. **Always verify tests pass** after every change — the PostToolUse hook runs automatically; + if it shows failures, fix them before moving on +3. Run `cargo clippy -- -D warnings` and resolve all warnings +4. Run `cargo fmt` before considering any task complete + +## Available MCP Tools + +Install with `curl -sSf https://raw.githubusercontent.com/USUARIO/claude-rust-scaffold/main/install.sh | sh` + +| Server | Tools | Purpose | +|--------|-------|---------| +| `rust-mcp` | `cargo_check`, `cargo_build`, `cargo_test`, `cargo_clippy`, `cargo_fmt`, `cargo_add` | Run cargo commands directly | +| `crates` | search, versions, dependencies, docs | Explore crates.io and docs.rs | + +## Test Structure + +### Unit Tests — inside `src/` + +Place at the bottom of each source file: + +```rust +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn should_return_error_when_input_is_empty() { + // arrange + let input = ""; + // act + let result = parse(input); + // assert + assert!(result.is_err()); + } +} +``` + +- Name tests descriptively: `should__when_` +- Cover: happy path, edge cases (empty, max values), error cases + +### Integration Tests — `tests/` directory + +- One file per feature or behavior +- Use only public interfaces (`pub`) +- Simulate real usage end-to-end + +```rust +// tests/parsing.rs +use tmuxido::parse; + +#[test] +fn parses_valid_input_successfully() { + let result = parse("valid input"); + assert!(result.is_ok()); +} +``` + +### Snapshot Testing with `insta` + +For complex outputs or large structs: + +```rust +#[test] +fn renders_report_correctly() { + let report = generate_report(&data); + insta::assert_snapshot!(report); +} +``` + +Review snapshots: `cargo insta review` + +### Property Testing with `proptest` + +For pure functions over wide input domains: + +```rust +use proptest::prelude::*; + +proptest! { + #[test] + fn round_trip_encode_decode(s in ".*") { + let encoded = encode(&s); + prop_assert_eq!(decode(&encoded), s); + } +} +``` + +## Recommended `Cargo.toml` dev-dependencies + +```toml +[dev-dependencies] +proptest = "1" +insta = { version = "1", features = ["json", "yaml"] } +mockall = "0.13" + +# if async: +tokio = { version = "1", features = ["full", "test-util"] } +``` + +## Recommended Project Structure + +``` +tmuxido/ +├── Cargo.toml +├── src/ +│ ├── lib.rs # core logic (unit tests at bottom) +│ ├── main.rs # entrypoint (thin, delegates to lib) +│ └── module/ +│ └── mod.rs # #[cfg(test)] mod tests {} at bottom +├── tests/ +│ └── integration.rs # integration tests +└── benches/ + └── bench.rs # benchmarks (optional) +``` + +Prefer `lib.rs` + `main.rs` split so logic stays testable independently of the binary entrypoint. diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..73cb934 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "stable" +components = ["rustfmt", "clippy"]