29ffb42898
---ci--- project: atelier phase: 0 milestone: v0.4 status: complete requirements: covered: [ATELIER-92, ATELIER-93, ATELIER-94, ATELIER-95, ATELIER-96, ATELIER-97, ATELIER-98, ATELIER-99, ATELIER-100, ATELIER-101, ATELIER-102, ATELIER-103, ATELIER-104, ATELIER-105, ATELIER-106, ATELIER-107, ATELIER-108, ATELIER-109, ATELIER-110, ATELIER-111, ATELIER-112, ATELIER-113, ATELIER-114, ATELIER-115, ATELIER-116, ATELIER-117] partial: [] ---/ci---
95 lines
4.9 KiB
Markdown
95 lines
4.9 KiB
Markdown
# Rust Tooling — Derived Application
|
|
|
|
> Applies Atelier's domain principles to Rust tooling specifically.
|
|
> Derives from `domains/` docs; introduces no new P-rules (D-063).
|
|
> See `languages/rust.md` for the language first-principles stub.
|
|
|
|
## cargo and Build Discipline (DevOps P2 Automation, DevOps P1 Reproducibility)
|
|
|
|
- **`cargo build` for dev, `cargo build --release` for release:** release enables optimizations (LTO, codegen-units=1). The default profile is for fast iteration, not perf.
|
|
- **`Cargo.lock` committed for applications and CI:** for libraries, commit the lock for CI reproducibility even though consumers resolve their own tree. A drifted lock breaks reproducibility (DevOps P1).
|
|
- **`cargo update` periodically, with a CI check:** `cargo update` bumps patch versions in the lock; a CI job that fails on lock drift catches a forgotten `cargo update`.
|
|
- **`cargo vendor` for hermetic CI:** vendors `vendor/` into the repo; CI builds without network. The trade-off is repo size; the win is reproducibility.
|
|
|
|
```toml
|
|
# Cargo.toml — profile discipline
|
|
[profile.release]
|
|
lto = true
|
|
codegen-units = 1
|
|
panic = "abort" # smaller binary, no unwinding
|
|
```
|
|
|
|
## clippy (DevOps P2 Automation, C2 Clarity)
|
|
|
|
- **`cargo clippy` is the lint layer over `rustc`:** it catches `clone()` where a borrow would do, `unwrap()` in library code, and needless `Box`. Run on every build.
|
|
- **`cargo clippy -- -D warnings` in CI:** warnings are errors. A clippy warning is a smell; accumulating them erodes the signal (Clarity C2).
|
|
- **Per-lint allow only with a tracked reason:** `#[allow(clippy::needless_collect)] // reason: GH-123 — collect needed for len` — each allow links to a ticket. Untracked allows accumulate into a permanently lint-bypassed core.
|
|
- **`cargo clippy --fix` for safe auto-fixes:** applies the linter's suggested change. Review the diff; do not run blindly on a large commit.
|
|
|
|
```bash
|
|
# CI gate
|
|
cargo clippy --all-targets --all-features -- -D warnings
|
|
```
|
|
|
|
## cargo fmt (DevOps P2 Automation, C2 Clarity)
|
|
|
|
- **`cargo fmt` is the formatter; format is not debated in review:** run in CI as a check (`cargo fmt --check`), not a fix. A failing check blocks the PR.
|
|
- **`rustfmt.toml` for repo-wide settings:** if the defaults are wrong for the repo, override once and stop. Do not relitigate per-PR.
|
|
- **Applies `devops/P2`:** the format gate is automated; a reviewer never comments on style.
|
|
|
|
```bash
|
|
# CI gate — fail if unformatted
|
|
cargo fmt --check
|
|
```
|
|
|
|
## Edition Discipline (DevOps P1 Reproducibility, C5 Reversibility)
|
|
|
|
- **`edition` in `Cargo.toml` pins the language edition:** 2015, 2018, 2021, 2024. An edition is a coherent set of language changes; bumping it is a deliberate migration.
|
|
- **Edition is not the compiler version:** `rustc 1.75` supports edition 2021; edition 2024 needs a newer `rustc`. Pin the toolchain with `rust-toolchain.toml`.
|
|
- **Bump editions deliberately, not opportunistically:** `cargo fix --edition` applies the migration lint; review the diff. A bump mid-feature conflates two changes.
|
|
- **Applies `devops/P1` and `C5` (reversibility):** pinning the edition and toolchain makes the build reproducible; bumping is a controlled, reversible change.
|
|
|
|
```toml
|
|
# Cargo.toml
|
|
[package]
|
|
edition = "2021"
|
|
rust-version = "1.75"
|
|
```
|
|
|
|
```toml
|
|
# rust-toolchain.toml
|
|
[toolchain]
|
|
channel = "1.75"
|
|
components = ["clippy", "rustfmt"]
|
|
```
|
|
|
|
## Documentation in the Pipeline (Documentation P1 Documentation is Code, DevOps P9 Documentation in the Pipeline)
|
|
|
|
- **`cargo doc` from doc comments:** `///` on items generates API docs; `cargo doc --open` previews. The build fails on broken intra-doc links (`#![warn(rustdoc::broken_intra_doc_links)]`).
|
|
- **Doc tests are run by `cargo test`:** a `///` fenced block with `#`-hidden setup is a tested artifact; a stale example fails `cargo test --doc` (Documentation P1).
|
|
- **`#![warn(missing_docs)]` for libraries:** public items without doc comments fail the build. Documentation is a build gate, not an afterthought.
|
|
- **`cargo readme` or `cargo docs-rs` for landing pages:** the crate's `README.md` is rendered on docs.rs; keep it in sync with `lib.rs`'s top-level doc.
|
|
|
|
```rust
|
|
#![warn(missing_docs, rustdoc::broken_intra_doc_links)]
|
|
|
|
/// Fetch a user by id.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use mycrate::get_user;
|
|
/// let u = get_user("abc").unwrap();
|
|
/// println!("{}", u.name);
|
|
/// ```
|
|
pub fn get_user(id: &str) -> Result<User, Error> { /* ... */ }
|
|
```
|
|
|
|
## Cross-References
|
|
|
|
- `domains/devops/ci-cd.md` — the pipeline gates that host clippy/fmt/test.
|
|
- `domains/devops/first-principles.md` — DevOps P1 Reproducibility, P2 Automation.
|
|
- `domains/documentation/first-principles.md` — Documentation P1 Documentation is Code.
|
|
- `languages/rs-ownership.md` — `Send`/`Sync` clippy lints reference this doc.
|
|
- `languages/rs-async.md` — async-runtime tooling (`tokio` features) detailed here.
|
|
- `languages/rs-testing.md` — `cargo test` flags (`--doc`, `--no-run`) detailed here. |