anvilsign in

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
1818 rustfmt.toml), `cargo sort-derives` (`cargo install cargo-sort-derives`), and
1919 `cargo clippy --workspace --all-targets -- -D warnings`.
2020
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+
2128 **The Rust version is set in exactly one place: `rust-toolchain.toml`.** It
2229 pins the toolchain and the musl cross target for every `cargo` invocation here,
2330 and `docker/runner/build.sh` parses `[toolchain] channel` out of it to bake the
⋯ 113 unchanged lines
modifiedCargo.toml+9 −0
⋯ 11 unchanged lines
1212 repository = "https://github.com/richardscollin/anvil"
1313 rust-version = "1.98.0"
1414
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+
1524 [workspace.dependencies]
1625 # Internal crates
1726 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
77 rust-version.workspace = true
88 description = "Agent sessions for anvil: a tmux-hosted agent CLI per repository, in a container, attachable from the browser."
99
10+[lints]
11+workspace = true
12+
1013 [dependencies]
1114 # The Docker connect/pull plumbing is shared with the job runner rather than
1215 # duplicated — both start containers from the same runner image.
⋯ 9 unchanged lines
modifiedcrates/anvil-ci/Cargo.toml+3 −0
⋯ 6 unchanged lines
77 rust-version.workspace = true
88 description = "CI runner for anvil: executes .anvil/ci.yml pipelines in Docker containers via the socket."
99
10+[lints]
11+workspace = true
12+
1013 [dependencies]
1114 anvil-core.workspace = true
1215 anvil-docker.workspace = true
⋯ 11 unchanged lines
modifiedcrates/anvil-cli/Cargo.toml+3 −0
⋯ 11 unchanged lines
1212 name = "anvild"
1313 path = "src/main.rs"
1414
15+[lints]
16+workspace = true
17+
1518 [dependencies]
1619 anvil-core.workspace = true
1720 anvil-web.workspace = true
⋯ 17 unchanged lines
modifiedcrates/anvil-core/Cargo.toml+3 −0
⋯ 6 unchanged lines
77 rust-version.workspace = true
88 description = "Domain model, persistence, and on-disk repository storage for the anvil git forge."
99
10+[lints]
11+workspace = true
12+
1013 [dependencies]
1114 anvil-job.workspace = true
1215 async-trait.workspace = true
⋯ 29 unchanged lines
modifiedcrates/anvil-docker/Cargo.toml+3 −0
⋯ 6 unchanged lines
77 rust-version.workspace = true
88 description = "Docker connect/pull plumbing shared by anvil's job runner and agent-session supervisor."
99
10+[lints]
11+workspace = true
12+
1013 [dependencies]
1114 bollard.workspace = true
1215 futures-util.workspace = true
⋯ 1 unchanged line
modifiedcrates/anvil-git/Cargo.toml+3 −0
⋯ 6 unchanged lines
77 rust-version.workspace = true
88 description = "Server-side git wire protocol (smart-HTTP / SSH) on top of gix. Transport-agnostic; upstream-candidate."
99
10+[lints]
11+workspace = true
12+
1013 [dependencies]
1114 anvil-core.workspace = true
1215 gix.workspace = true
⋯ 10 unchanged lines
modifiedcrates/anvil-job/Cargo.toml+3 −0
⋯ 6 unchanged lines
77 rust-version.workspace = true
88 description = "The wire format between anvil and a job runner: what a claimed job is, and what its result looks like."
99
10+[lints]
11+workspace = true
12+
1013 [dependencies]
1114 serde.workspace = true
modifiedcrates/anvil-ssh/Cargo.toml+3 −0
⋯ 6 unchanged lines
77 rust-version.workspace = true
88 description = "git-over-SSH transport for anvil (russh), delegating to anvil-git. Added in milestone 6."
99
10+[lints]
11+workspace = true
12+
1013 [dependencies]
1114 anvil-core.workspace = true
1215 anvil-git.workspace = true
⋯ 4 unchanged lines
modifiedcrates/anvil-web/Cargo.toml+3 −0
⋯ 6 unchanged lines
77 rust-version.workspace = true
88 description = "HTTP server for anvil: web UI and smart-HTTP git endpoints (axum)."
99
10+[lints]
11+workspace = true
12+
1013 [dependencies]
1114 anvil-agent.workspace = true
1215 anvil-ci.workspace = true
⋯ 38 unchanged lines
modifiedcrates/anvil-worker/Cargo.toml+3 −0
⋯ 12 unchanged lines
1313 name = "anvil-worker"
1414 path = "src/main.rs"
1515
16+[lints]
17+workspace = true
18+
1619 [dependencies]
1720 anvil-docker.workspace = true
1821 anvil-job.workspace = true
⋯ 11 unchanged lines
modifiedvendor/gitserver-core/Cargo.toml+3 −0
⋯ 5 unchanged lines
66 license = "MPL-2.0"
77 repository = "https://github.com/WJQSERVER/gitserver"
88
9+[lints]
10+workspace = true
11+
912 [dependencies]
1013 # gix / gix-pack come from the anvil workspace (bumped to 0.87 / 0.74 here).
1114 gix = { workspace = true }
⋯ 14 unchanged lines
modifiedvendor/gitserver-core/VENDOR.md+2 −0
⋯ 29 unchanged lines
3030
3131 - `Cargo.toml`: standalone manifest using the anvil workspace's `gix` (0.87) and
3232 `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.
3335 - Source changes required by the gix version bump are recorded in git history.