Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Fetching crates.io dependencies

zut builds are hermetic: the build phase has no network access. So fetching third-party crates is a separate, explicit step — zut fetch — that runs once, downloads everything into the content-addressed store, and generates a BUILD file the hermetic build then consumes offline.

The workflow

Point zut fetch at a Cargo lockfile:

$ zut fetch Cargo.lock
zut fetch Cargo.lock
  fetch  serde 1.0.210
  fetch  serde_derive 1.0.210
  ...
  42 crate(s): 42 fetched, 0 reused → .zut/crates.lock + //crates/BUILD

This does four things:

  1. Downloads each registry crate’s .crate archive over HTTPS (the only networked step — zut ships its own TLS via std.http.Client).
  2. Checksum-verifies each archive against the lockfile’s SHA-256, then unpacks it into a CAS Tree (a content-addressed directory).
  3. Records a manifest at .zut/crates.lock mapping each name version to its Tree digest.
  4. Generates //crates/BUILD — crate_library / crate_proc_macro targets wired with the right editions, features, and dependency edges.

When cargo and the host triple are available, zut runs cargo metadata for a faithful model (real editions, resolved features, lib/proc-macro kinds). Without them it falls back to a lockfile-only model (edition 2021, no features).

Idempotent & incremental

zut fetch is safe to re-run. A crate whose Tree is already in the CAS (per the prior .zut/crates.lock) is reused, not re-downloaded:

$ zut fetch Cargo.lock
  reuse  serde 1.0.210
  ...
  42 crate(s): 1 fetched, 41 reused → .zut/crates.lock + //crates/BUILD

Downloads run in parallel across worker threads (--jobs=N to bound them).

Using the fetched crates

Depend on a generated target from your own BUILD:

load("@builtin//:rust.bzl", "rust_binary")

rust_binary(
    name = "app",
    crate_root = "src/main.rs",
    srcs = ["src/main.rs"],
    edition = "2021",
    out = "app",
    deps = ["//crates:serde"],
)

Then zut build //:app runs entirely offline — the sources are grafted from the CAS Trees recorded earlier.

For the full design — URL construction, the manifest format, the generated model, and the cargo-as-toolchain decision — see docs/design/crates-io.md.