Skip to content

fix(nix): point fetchCrate at static.crates.io too - #12

Merged
dlipicar merged 1 commit into
masterfrom
fix/fetch-crate-static-crates-io
Sep 8, 2026
Merged

fix(nix): point fetchCrate at static.crates.io too#12
dlipicar merged 1 commit into
masterfrom
fix/fetch-crate-static-crates-io

Conversation

@dlipicar

@dlipicar dlipicar commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Third and last fetcher on the 403 endpoint, closing out #9 / #10 / #11 and the consumer
wiring in logos-co/logos-module-builder#233 and logos-co/logos-rust-sdk#56.

Why this one was missed

fetchCrate pulls a crate's own source tarball, not a vendored dependency, so
neither sibling overlay touches it — one adds a User-Agent to fetchCargoVendor, the
other rewrites importCargoLock's URLs.

#9 left it alone on the grounds that "nothing here fetches through it". True of this
repo; false of a module closure, which reaches rav1e and cargo-c via
qtdeclarative → qtsvg → jasper → libheif. Measured live with substituters disabled, on
the rav1e source derivation:

URL result
crates.io/api/v1/... curl (22) 403cannot download rav1e-0.8.1.tar.gz from any mirror
static.crates.io/... builds, and lands on the same store path 0s8jm042…-rav1e-0.8.1.tar.gz

The change

Swaps registryDlfetchCrate's own documented argument — rather than
re-instantiating the file. A caller naming a registry still wins, and the value is the
one upstream itself moved to: NixOS/nixpkgs#524979 spells
registryDl ? "https://static.crates.io/crates" at b5aa0fbd. Identity on a pin that
already points at the CDN; evaluation-time failure if the pin references neither prefix.

#9's stated objection, measured

#9 skipped this because overriding fetchCrate "moved the devShell drvPaths on every
system"
. That reproduces and is real — but it is cosmetic:

drvPath outPath
devShell aarch64-darwin ki8lzz89pjar0vgb l9hpbrxa… unchanged
devShell x86_64-linux f9yh59srx2nb5rjz lsjg4sw0… unchanged

Same for the packages that actually fetch this way: rav1e, its source FOD and
cargo-c all keep their exact outPaths. Nothing rebuilds; only .drv files differ.

Gate

checks.<sys>.fetch-crate-overlay asserts the rewrite for real, in the style of the
sibling gate — it calls fetchCrate with unpack = false so the probe is a plain
fetchurl exposing urls, and fails if the CDN prefix is absent or an API URL survives.
Verified non-vacuous by neutering the overlay to args: prev.fetchCrate args:

error: fetch-crate overlay drift: crate source not on the CDN
       (https://crates.io/api/v1/crates/logos-gate-probe/0.0.0/download)

The mutation suite gains M7 for the same property and is 8/8;
nix flake check --no-build --all-systems exits 0.

checks.<sys>.overlay-exports needed no change — registering the overlay in both
nativeOverlays and lib.overlays kept it at 3 == 3, which is exactly what that gate is
for.

After this

All three crate fetchers are on the CDN, and consumers pick this up through
lib.nativeOverlays with no change on their side. Remaining known item, unrelated to
this PR: logos-workspace/flake.nix:25 still pins logos-nix at 6e0f4a71, so bumping
logos-module-builder past #233 there without bumping logos-nix in the same commit makes
ws build throw a crates.io error on C++ repos.

🤖 Generated with Claude Code

Third and last fetcher on the 403 endpoint. fetchCrate pulls a crate's own
SOURCE tarball, not a vendored dependency, so neither sibling overlay touches
it: one adds a User-Agent to fetchCargoVendor, the other rewrites
importCargoLock's URLs.

#9 left it alone on the grounds that "nothing here fetches through it". True of
this repo; false of a module closure, which reaches rav1e and cargo-c via
qtdeclarative -> qtsvg -> jasper -> libheif. Measured live with substituters
disabled, on the rav1e source derivation:

  API URL  -> curl (22) 403, "cannot download rav1e-0.8.1.tar.gz from any mirror"
  CDN URL  -> builds, and lands on the SAME store path
              (0s8jm0421sg4hj6g57v9az8j0vas248i-rav1e-0.8.1.tar.gz)

Swaps `registryDl`, fetchCrate's own documented argument, rather than
re-instantiating the file — so a caller naming a registry still wins and the
default is the one upstream itself moved to (NixOS/nixpkgs#524979 spells
`registryDl ? "https://static.crates.io/crates"` at b5aa0fbd). Identity on a pin
that already points at the CDN, and an evaluation-time failure if the pin
references neither prefix.

#9's stated reason for skipping this was that overriding fetchCrate "moved the
devShell drvPaths on every system". That reproduces and is real, but it is
cosmetic: measured on aarch64-darwin and x86_64-linux, devShell drvPaths move
(ki8lzz89 -> pjar0vgb, f9yh59sr -> x2nb5rjz) while devShell OUTPATHS are
byte-identical (l9hpbrxa..., lsjg4sw0...). Same for the packages that actually
fetch this way: rav1e, its source FOD and cargo-c all keep their exact outPaths.
Nothing rebuilds; only .drv files differ.

checks.<sys>.fetch-crate-overlay asserts the rewrite for real, in the style of
the sibling gate: it calls fetchCrate with unpack=false so the probe is a plain
fetchurl exposing `urls`, and fails if the CDN prefix is absent or an API URL
survives. Verified non-vacuous by neutering the overlay to `args:
prev.fetchCrate args`:

  error: fetch-crate overlay drift: crate source not on the CDN
         (https://crates.io/api/v1/crates/logos-gate-probe/0.0.0/download)

Mutation suite gains M7 for the same property and is 8/8. The overlay-exports
gate needed no change -- registering in nativeOverlays and lib.overlays kept it
at 3 == 3, which is what it is for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dlipicar
dlipicar merged commit 30285b1 into master Sep 8, 2026
4 checks passed
dlipicar added a commit to logos-co/logos-qt-sdk that referenced this pull request Sep 8, 2026
This flake built its own package set with a bare `import nixpkgs`, twice, so
neither carried logos-nix's crates.io overlays. The consequence is worse than a
missing fix: because logos-module-builder now applies them, a module closure
ended up with TWO Qt stacks -- module-builder's overlaid one and this flake's
un-overlaid one -- and the crate sources behind the second still came from the
endpoint crates.io 403s.

Bumping locks does not close it. Measured with every SDK-repo logos-nix lock
already at #12, the closure still carried two qtdeclaratives and two
crates.io/api fetchers; this one-line change is what collapses it.

Measured on aarch64-darwin, reading `urls` off the fetchers in the realised
closure:

                        before          after
  logos-qt-sdk-lib      API=2  CDN=0    API=0  CDN=2
  logos-qt-generator                    API=0  CDN=2

The two are rav1e and cargo-c, crate SOURCE tarballs reached through
qtdeclarative -> qtsvg -> jasper -> libheif; logos-co/logos-nix#12 is the
overlay that moves them.

Both sites go through one `mkPkgs`, rather than being handed the same overlay
list twice: two independent `import nixpkgs` calls drifting apart is the shape
of this bug, and :68 (checks, devShells) had the same hole as :94 (packages).
Windows is untouched -- mkWindowsPkgs owns its own overlay list.

Nothing in nixpkgs rebuilds: qtdeclarative keeps its exact outPath
(fn7iqppsl6z7ikbspxnjirwdz345w8mj) either way. logos-qt-sdk-lib's own outPath
moves, but because this flake's source is its `src`, not because of the
overlays -- a no-op comment appended to flake.nix on master moves it the same
way (vqwwm0w6 -> z7prwdzy, against the wired ng8817a2).

The logos-nix input was still on 6e0f4a71, which predates lib.overlays
entirely; it moves to master. nixpkgs stays at e9f00bd8.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant