collin/anvil · d60232e6
Turn on clippy::multiple_crate_versions across the workspace
Collin Richards · 2026-08-25 05:36 UTC · d60232e675b92bbd35bdc08ff14ae69d6afe87f1 · parent 562268fb · browse files
modifiedCLAUDE.md+7 −0
| ⋯ 17 unchanged lines | |||
| 18 | 18 | rustfmt.toml), `cargo sort-derives` (`cargo install cargo-sort-derives`), and | |
| 19 | 19 | `cargo clippy --workspace --all-targets -- -D warnings`. | |
| 20 | 20 | ||
| 21 | + | Every crate opts into `[workspace.lints]`, which turns on | |
| 22 | + | `clippy::multiple_crate_versions` — so adding a dependency that drags in a | |
| 23 | + | second copy of something already in the tree fails the hook. The duplicates | |
| 24 | + | that exist today are listed in `clippy.toml` with a note on who is holding | |
| 25 | + | each back; delete an entry when a bump makes it unnecessary rather than | |
| 26 | + | letting the list rot. | |
| 27 | + | ||
| 21 | 28 | **The Rust version is set in exactly one place: `rust-toolchain.toml`.** It | |
| 22 | 29 | pins the toolchain and the musl cross target for every `cargo` invocation here, | |
| 23 | 30 | and `docker/runner/build.sh` parses `[toolchain] channel` out of it to bake the | |
| ⋯ 113 unchanged lines | |||
modifiedCargo.toml+9 −0
| ⋯ 11 unchanged lines | |||
| 12 | 12 | repository = "https://github.com/richardscollin/anvil" | |
| 13 | 13 | rust-version = "1.98.0" | |
| 14 | 14 | ||
| 15 | + | [workspace.lints.clippy] | |
| 16 | + | # One version of a crate per tree, or say why not. Duplicates are usually a | |
| 17 | + | # dependency mid-upgrade (two `digest` generations, two `base64`s) — each one | |
| 18 | + | # is dead weight in the static musl binary and a type that does not unify | |
| 19 | + | # across the seam. Unavoidable ones go in `allowed-duplicate-crates` in | |
| 20 | + | # clippy.toml, with a reason, so the list is the record of what we are waiting | |
| 21 | + | # on rather than an ambient warning everyone learns to scroll past. | |
| 22 | + | multiple_crate_versions = "warn" | |
| 23 | + | ||
| 15 | 24 | [workspace.dependencies] | |
| 16 | 25 | # Internal crates | |
| 17 | 26 | anvil-core = { path = "crates/anvil-core" } | |
| ⋯ 99 unchanged lines | |||
addedclippy.toml+49 −0
| 1 | + | # Duplicates `clippy::multiple_crate_versions` is allowed to ignore. | |
| 2 | + | # | |
| 3 | + | # The lint is on (see `[workspace.lints.clippy]` in Cargo.toml) so that a *new* | |
| 4 | + | # duplicate has to be argued for. Everything below is a duplicate we cannot | |
| 5 | + | # remove from here: some other crate in the tree pins the older copy, and the | |
| 6 | + | # only fix is that crate moving. Each entry says who is holding it, so this | |
| 7 | + | # list doubles as the "what are we waiting on" record — when a bump makes an | |
| 8 | + | # entry unnecessary, delete it rather than leaving it to rot. | |
| 9 | + | # | |
| 10 | + | # Nothing here is ours to collapse today, with one exception noted below. | |
| 11 | + | ||
| 12 | + | allowed-duplicate-crates = [ | |
| 13 | + | # --- The RustCrypto `digest` 0.10 -> 0.11 seam ------------------------ | |
| 14 | + | # Half the tree has moved to digest 0.11 (aes-gcm, ssh-key, russh, our own | |
| 15 | + | # sha2/hmac) and half has not (gix's sha1, `rsa` 0.9 in anvil-web's tests, | |
| 16 | + | # argon2 0.5). Every crate below is simply the same crate on both sides of | |
| 17 | + | # that line, and they collapse when the stragglers move — mostly gix. | |
| 18 | + | "block-buffer", | |
| 19 | + | "const-oid", | |
| 20 | + | "cpufeatures", | |
| 21 | + | "crypto-common", | |
| 22 | + | "digest", | |
| 23 | + | "generic-array", | |
| 24 | + | "sha1", | |
| 25 | + | "sha3", | |
| 26 | + | ||
| 27 | + | # `argon2` is the one duplicate we could remove ourselves: we pin 0.5 and | |
| 28 | + | # ssh-key pulls 0.6.0-rc.8. Deliberately not taken — 0.6 is a pre-release | |
| 29 | + | # and argon2 is what verifies account passwords. Moving it would also | |
| 30 | + | # collapse `blake2` and `password-hash`, which are here only because | |
| 31 | + | # argon2 0.5 holds the old copy. | |
| 32 | + | "argon2", | |
| 33 | + | "blake2", | |
| 34 | + | "password-hash", | |
| 35 | + | ||
| 36 | + | # --- Held by direct dependencies of ours ------------------------------ | |
| 37 | + | "base64", # axum 0.8 is on 0.22; we are on 0.23. | |
| 38 | + | "tower-http", # reqwest 0.13 uses 0.6 internally; we are on 0.7. | |
| 39 | + | "hashlink", # rusqlite 0.40 moved to 0.12; something older wants 0.11. | |
| 40 | + | ||
| 41 | + | # --- Entirely inside other crates' trees ------------------------------ | |
| 42 | + | "bitflags", # 1.x lingers under a few transitive crates. | |
| 43 | + | "foldhash", # gix-pack's clru vs jaq-json. | |
| 44 | + | "getrandom", # 0.2/0.3/0.4 across rand, ring and gix. | |
| 45 | + | "hashbrown", # three copies, all within gix's own sub-crates. | |
| 46 | + | "r-efi", # a getrandom UEFI backend, one per getrandom major. | |
| 47 | + | "rand_core", # tracks the getrandom split above. | |
| 48 | + | "syn", # proc-macro crates mid-migration from 2.x to 3.x. | |
| 49 | + | ] |
modifiedcrates/anvil-agent/Cargo.toml+3 −0
| ⋯ 6 unchanged lines | |||
| 7 | 7 | rust-version.workspace = true | |
| 8 | 8 | description = "Agent sessions for anvil: a tmux-hosted agent CLI per repository, in a container, attachable from the browser." | |
| 9 | 9 | ||
| 10 | + | [lints] | |
| 11 | + | workspace = true | |
| 12 | + | ||
| 10 | 13 | [dependencies] | |
| 11 | 14 | # The Docker connect/pull plumbing is shared with the job runner rather than | |
| 12 | 15 | # duplicated — both start containers from the same runner image. | |
| ⋯ 9 unchanged lines | |||
modifiedcrates/anvil-ci/Cargo.toml+3 −0
| ⋯ 6 unchanged lines | |||
| 7 | 7 | rust-version.workspace = true | |
| 8 | 8 | description = "CI runner for anvil: executes .anvil/ci.yml pipelines in Docker containers via the socket." | |
| 9 | 9 | ||
| 10 | + | [lints] | |
| 11 | + | workspace = true | |
| 12 | + | ||
| 10 | 13 | [dependencies] | |
| 11 | 14 | anvil-core.workspace = true | |
| 12 | 15 | anvil-docker.workspace = true | |
| ⋯ 11 unchanged lines | |||
modifiedcrates/anvil-cli/Cargo.toml+3 −0
| ⋯ 11 unchanged lines | |||
| 12 | 12 | name = "anvild" | |
| 13 | 13 | path = "src/main.rs" | |
| 14 | 14 | ||
| 15 | + | [lints] | |
| 16 | + | workspace = true | |
| 17 | + | ||
| 15 | 18 | [dependencies] | |
| 16 | 19 | anvil-core.workspace = true | |
| 17 | 20 | anvil-web.workspace = true | |
| ⋯ 17 unchanged lines | |||
modifiedcrates/anvil-core/Cargo.toml+3 −0
| ⋯ 6 unchanged lines | |||
| 7 | 7 | rust-version.workspace = true | |
| 8 | 8 | description = "Domain model, persistence, and on-disk repository storage for the anvil git forge." | |
| 9 | 9 | ||
| 10 | + | [lints] | |
| 11 | + | workspace = true | |
| 12 | + | ||
| 10 | 13 | [dependencies] | |
| 11 | 14 | anvil-job.workspace = true | |
| 12 | 15 | async-trait.workspace = true | |
| ⋯ 29 unchanged lines | |||
modifiedcrates/anvil-docker/Cargo.toml+3 −0
| ⋯ 6 unchanged lines | |||
| 7 | 7 | rust-version.workspace = true | |
| 8 | 8 | description = "Docker connect/pull plumbing shared by anvil's job runner and agent-session supervisor." | |
| 9 | 9 | ||
| 10 | + | [lints] | |
| 11 | + | workspace = true | |
| 12 | + | ||
| 10 | 13 | [dependencies] | |
| 11 | 14 | bollard.workspace = true | |
| 12 | 15 | futures-util.workspace = true | |
| ⋯ 1 unchanged line | |||
modifiedcrates/anvil-git/Cargo.toml+3 −0
| ⋯ 6 unchanged lines | |||
| 7 | 7 | rust-version.workspace = true | |
| 8 | 8 | description = "Server-side git wire protocol (smart-HTTP / SSH) on top of gix. Transport-agnostic; upstream-candidate." | |
| 9 | 9 | ||
| 10 | + | [lints] | |
| 11 | + | workspace = true | |
| 12 | + | ||
| 10 | 13 | [dependencies] | |
| 11 | 14 | anvil-core.workspace = true | |
| 12 | 15 | gix.workspace = true | |
| ⋯ 10 unchanged lines | |||
modifiedcrates/anvil-job/Cargo.toml+3 −0
| ⋯ 6 unchanged lines | |||
| 7 | 7 | rust-version.workspace = true | |
| 8 | 8 | description = "The wire format between anvil and a job runner: what a claimed job is, and what its result looks like." | |
| 9 | 9 | ||
| 10 | + | [lints] | |
| 11 | + | workspace = true | |
| 12 | + | ||
| 10 | 13 | [dependencies] | |
| 11 | 14 | serde.workspace = true | |
modifiedcrates/anvil-ssh/Cargo.toml+3 −0
| ⋯ 6 unchanged lines | |||
| 7 | 7 | rust-version.workspace = true | |
| 8 | 8 | description = "git-over-SSH transport for anvil (russh), delegating to anvil-git. Added in milestone 6." | |
| 9 | 9 | ||
| 10 | + | [lints] | |
| 11 | + | workspace = true | |
| 12 | + | ||
| 10 | 13 | [dependencies] | |
| 11 | 14 | anvil-core.workspace = true | |
| 12 | 15 | anvil-git.workspace = true | |
| ⋯ 4 unchanged lines | |||
modifiedcrates/anvil-web/Cargo.toml+3 −0
| ⋯ 6 unchanged lines | |||
| 7 | 7 | rust-version.workspace = true | |
| 8 | 8 | description = "HTTP server for anvil: web UI and smart-HTTP git endpoints (axum)." | |
| 9 | 9 | ||
| 10 | + | [lints] | |
| 11 | + | workspace = true | |
| 12 | + | ||
| 10 | 13 | [dependencies] | |
| 11 | 14 | anvil-agent.workspace = true | |
| 12 | 15 | anvil-ci.workspace = true | |
| ⋯ 38 unchanged lines | |||
modifiedcrates/anvil-worker/Cargo.toml+3 −0
| ⋯ 12 unchanged lines | |||
| 13 | 13 | name = "anvil-worker" | |
| 14 | 14 | path = "src/main.rs" | |
| 15 | 15 | ||
| 16 | + | [lints] | |
| 17 | + | workspace = true | |
| 18 | + | ||
| 16 | 19 | [dependencies] | |
| 17 | 20 | anvil-docker.workspace = true | |
| 18 | 21 | anvil-job.workspace = true | |
| ⋯ 11 unchanged lines | |||
modifiedvendor/gitserver-core/Cargo.toml+3 −0
| ⋯ 5 unchanged lines | |||
| 6 | 6 | license = "MPL-2.0" | |
| 7 | 7 | repository = "https://github.com/WJQSERVER/gitserver" | |
| 8 | 8 | ||
| 9 | + | [lints] | |
| 10 | + | workspace = true | |
| 11 | + | ||
| 9 | 12 | [dependencies] | |
| 10 | 13 | # gix / gix-pack come from the anvil workspace (bumped to 0.87 / 0.74 here). | |
| 11 | 14 | gix = { workspace = true } | |
| ⋯ 14 unchanged lines | |||
modifiedvendor/gitserver-core/VENDOR.md+2 −0
| ⋯ 29 unchanged lines | |||
| 30 | 30 | ||
| 31 | 31 | - `Cargo.toml`: standalone manifest using the anvil workspace's `gix` (0.87) and | |
| 32 | 32 | `gix-pack` (0.74) instead of upstream's pinned 0.80 / 0.67. | |
| 33 | + | - `Cargo.toml`: `[lints] workspace = true`, so the vendored crate is held to | |
| 34 | + | anvil's lint configuration like any other member. | |
| 33 | 35 | - Source changes required by the gix version bump are recorded in git history. | |