|
| 1 | +# AGENTS.md — xtask-wasm |
| 2 | + |
| 3 | +Guidelines for agentic coding tools working in this repository. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## Repository Overview |
| 8 | + |
| 9 | +`xtask-wasm` is a Rust library crate providing customizable xtask subcommands (`Dist`, |
| 10 | +`Watch`, `DevServer`) for building WebAssembly projects without external tools like |
| 11 | +`wasm-pack`. It is part of a Cargo workspace with one other member: |
| 12 | +`xtask-wasm-run-example` (a proc-macro crate). |
| 13 | + |
| 14 | +``` |
| 15 | +xtask-wasm/ |
| 16 | +├── src/ # Library source (lib.rs, dist.rs, dev_server.rs, sass.rs, wasm_opt.rs) |
| 17 | +├── xtask-wasm-run-example/ # Proc-macro workspace member |
| 18 | +├── examples/demo/ # Demo workspace (separate Cargo workspace) |
| 19 | +│ ├── webapp/ # Example wasm app |
| 20 | +│ └── xtask/ # Example xtask binary using xtask-wasm |
| 21 | +└── .github/workflows/ # CI definitions |
| 22 | +``` |
| 23 | + |
| 24 | +--- |
| 25 | + |
| 26 | +## Build, Lint, and Test Commands |
| 27 | + |
| 28 | +All commands are run from the repository root unless noted otherwise. |
| 29 | + |
| 30 | +### Standard check/build |
| 31 | +```bash |
| 32 | +cargo check --workspace --all-features |
| 33 | +cargo build --workspace --all-features |
| 34 | +``` |
| 35 | + |
| 36 | +### Run all tests |
| 37 | +```bash |
| 38 | +cargo test --workspace --all-features |
| 39 | +``` |
| 40 | + |
| 41 | +### Run a single test |
| 42 | +```bash |
| 43 | +# By test name (substring match) |
| 44 | +cargo test --workspace --all-features <test_name> |
| 45 | + |
| 46 | +# By test name in a specific crate |
| 47 | +cargo test -p xtask-wasm --all-features <test_name> |
| 48 | +``` |
| 49 | + |
| 50 | +### Formatting |
| 51 | +```bash |
| 52 | +# Check (CI uses this) |
| 53 | +cargo fmt --all -- --check |
| 54 | + |
| 55 | +# Apply |
| 56 | +cargo fmt --all |
| 57 | +``` |
| 58 | + |
| 59 | +### Linting (clippy) |
| 60 | +```bash |
| 61 | +# CI command — all warnings are errors |
| 62 | +cargo clippy --all --tests --all-features -- -D warnings |
| 63 | + |
| 64 | +# Local (softer, same flags) |
| 65 | +cargo clippy --all --tests --all-features |
| 66 | +``` |
| 67 | + |
| 68 | +### Check the demo workspace |
| 69 | +```bash |
| 70 | +# Must be run from the demo directory |
| 71 | +cargo check -p xtask # from examples/demo/ |
| 72 | +``` |
| 73 | + |
| 74 | +### CI matrix |
| 75 | +CI runs on ubuntu/windows/macos against both stable and the MSRV declared in |
| 76 | +`Cargo.toml` (`rust-version`). Always verify `cargo fmt` and `cargo clippy` pass before |
| 77 | +committing. |
| 78 | + |
| 79 | +--- |
| 80 | + |
| 81 | +## Code Style Guidelines |
| 82 | + |
| 83 | +### Formatting |
| 84 | + |
| 85 | +- Use `cargo fmt` (default `rustfmt` settings — no `rustfmt.toml` in this repo). |
| 86 | +- 4-space indentation; no tabs. |
| 87 | +- Trailing commas in multi-line struct literals and function call arguments. |
| 88 | +- Method chains are broken across lines with a leading `.`: |
| 89 | + ```rust |
| 90 | + dist |
| 91 | + .assets_dir("static") |
| 92 | + .app_name("my-app") |
| 93 | + .build("my-app")?; |
| 94 | + ``` |
| 95 | + |
| 96 | +### Imports |
| 97 | + |
| 98 | +- Group imports using nested paths where possible: |
| 99 | + ```rust |
| 100 | + use std::{fs, path::PathBuf, process}; |
| 101 | + ``` |
| 102 | +- Standard library imports first, then external crates, then `crate::` / `super::`. |
| 103 | +- Feature-gated imports use `#[cfg(...)]` attribute blocks, not inline `cfg!()` in use |
| 104 | + statements. |
| 105 | +- Re-exports from `xtask_watch` (`anyhow`, `camino`, `clap`, etc.) are accessed via |
| 106 | + `crate::` — do not add duplicate direct dependencies when the re-export is sufficient. |
| 107 | + |
| 108 | +### Naming Conventions |
| 109 | + |
| 110 | +| Item | Convention | Example | |
| 111 | +|------|-----------|---------| |
| 112 | +| Types / traits | `PascalCase` | `Dist`, `DevServer`, `Transformer` | |
| 113 | +| Functions / methods | `snake_case` | `build_command`, `copy_assets` | |
| 114 | +| Fields / variables | `snake_case` | `dist_dir`, `app_name` | |
| 115 | +| Constants / statics | `SCREAMING_SNAKE_CASE` | `WASM_OPT_URL` | |
| 116 | +| Modules | `snake_case`, match filename | `dev_server`, `wasm_opt` | |
| 117 | + |
| 118 | +### Error Handling |
| 119 | + |
| 120 | +- All fallible functions return `anyhow::Result<T>` (re-exported as `crate::Result`). |
| 121 | +- Prefer `context("…")` / `with_context(|| format!("…"))` from `anyhow` to annotate |
| 122 | + errors with actionable messages. |
| 123 | +- Use `ensure!(condition, "message")` for precondition checks. |
| 124 | +- Use `bail!("message")` for early exit with an error. |
| 125 | +- `unwrap()` is acceptable only when the invariant is guaranteed by surrounding logic |
| 126 | + (e.g. `strip_prefix(…).unwrap()` inside a `WalkDir` iterator where prefix is known). |
| 127 | +- `expect("message")` is acceptable where a panic would indicate a programmer bug; write |
| 128 | + a clear message describing what was expected. |
| 129 | +- Do **not** introduce custom error types — stay with `anyhow` throughout. |
| 130 | + |
| 131 | +### Types and Traits |
| 132 | + |
| 133 | +- All public API structs (`Dist`, `DevServer`, `Request`) are marked `#[non_exhaustive]` |
| 134 | + to preserve semver compatibility. |
| 135 | +- All public API structs derive `clap::Parser`; fields not from the CLI use |
| 136 | + `#[clap(skip)]`. |
| 137 | +- Use `derive_more::Debug` (not `std::fmt::Debug`) so `#[debug(skip)]` can be applied |
| 138 | + to fields containing non-`Debug` types (e.g. `Box<dyn Transformer>`, |
| 139 | + `Arc<dyn Fn(…)>`). |
| 140 | +- `impl Default` is written manually for structs that cannot derive it (e.g. anything |
| 141 | + containing `process::Command`). |
| 142 | +- Builder pattern: methods take `mut self` and return `Self` for chaining. |
| 143 | +- Use `Vec<Box<dyn Trait>>` for heterogeneous collections of hooks/transformers. |
| 144 | +- Use `Arc<dyn Fn(…) + Send + Sync + 'static>` for shared callable fields. |
| 145 | +- Use `lazy_static!` for lazily initialized statics. |
| 146 | + |
| 147 | +### Documentation |
| 148 | + |
| 149 | +- `#![deny(missing_docs)]` is active in `lib.rs` — **every public item must have a doc |
| 150 | + comment**. |
| 151 | +- Use `///` for item-level docs; `//!` for module/crate-level docs. |
| 152 | +- Include `# Examples` sections (with ` ```rust,no_run ``` `) for all significant public |
| 153 | + API items. |
| 154 | +- Document `# Panics` sections when `expect(…)` can be triggered by incorrect user |
| 155 | + input. |
| 156 | +- Feature-gated public items carry `#[cfg_attr(docsrs, doc(cfg(feature = "…")))]`. |
| 157 | + |
| 158 | +### Conditional Compilation |
| 159 | + |
| 160 | +- Feature flags: `run-example`, `sass`, `wasm-opt`. Add new opt-in functionality as |
| 161 | + optional features. |
| 162 | +- Target-gated deps use `[target.'cfg(…)'.dependencies]` in `Cargo.toml`. |
| 163 | +- Host-only (non-wasm) code is gated behind `#[cfg(not(target_arch = "wasm32"))]`. |
| 164 | + |
| 165 | +### Logging |
| 166 | + |
| 167 | +- Use the `log` crate macros: `log::trace!`, `log::debug!`, `log::info!`, `log::warn!`, |
| 168 | + `log::error!`. |
| 169 | +- Do not use `println!` / `eprintln!` for diagnostic output; use `log::` macros. |
| 170 | + |
| 171 | +--- |
| 172 | + |
| 173 | +## Dependency Philosophy |
| 174 | + |
| 175 | +- Keep dependencies minimal; prefer what is already pulled in transitively (e.g. via |
| 176 | + `xtask-watch`). |
| 177 | +- Avoid duplicating dependencies that are already re-exported from `xtask-watch`. |
| 178 | +- `wasm-bindgen-cli-support` is used as a library instead of shelling out to |
| 179 | + `wasm-bindgen` — preserve this property. |
| 180 | + |
| 181 | +--- |
| 182 | + |
| 183 | +## MSRV Policy |
| 184 | + |
| 185 | +The minimum supported Rust version is declared in the root `Cargo.toml` under |
| 186 | +`rust-version`. CI verifies both stable and MSRV. Do not use language or library |
| 187 | +features introduced after that version without updating `rust-version` and the changelog. |
| 188 | + |
| 189 | +--- |
| 190 | + |
| 191 | +## Changelog |
| 192 | + |
| 193 | +All user-visible changes must be recorded in `CHANGELOG.md` under the `[Unreleased]` |
| 194 | +section. Follow the Keep a Changelog format already in use. |
0 commit comments