From 48244e8390f56294d977fbcc311b9a380b96f189 Mon Sep 17 00:00:00 2001 From: Andrew Bryant Date: Sun, 25 Oct 2026 09:29:11 -0400 Subject: [PATCH] Add a flake package output for the library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `nix build` now works, using `rustPlatform.buildRustPackage` built with the pinned dev toolchain rather than whatever rustc nixpkgs happens to carry, so it compiles with the same compiler `nix develop` and CI do. `cargoLock` points at the repo's own `Cargo.lock` rather than a separately maintained hash. The crate has no `[[bin]]` target — see the "No CLI, and no binary at all" non-goal just added to `GOALS.md` — so the resulting store path comes out empty: `cargoInstallHook` only copies files matching a `[[bin]]` target out of `target/release`, and there is nothing to copy. Verified rather than assumed; the first version of this comment claimed the output held "an rlib and docs", which is not what actually lands in the store path. What `nix build` is good for regardless: it compiles with the pinned toolchain and runs the full suite, doctests included, inside the Nix sandbox with no network — matching the "no credentials needed" property `CLAUDE.md` already claims for `cargo test`, now exercised a second way. Treat it as a build-and-test gate, not a source of an installable artifact. Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 8 ++++++++ flake.nix | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 833f749..f8b1694 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,6 +22,14 @@ This project uses Nix for toolchain management (Rust via `rust-overlay`): nix develop ``` +`flake.nix` also has `packages.default`: `nix build` compiles with the +pinned dev toolchain and runs the full test suite, including doctests, +inside the Nix sandbox. The crate has no `[[bin]]` target (see the "No +CLI" non-goal in `GOALS.md`), so the resulting store path is empty — +`cargoInstallHook` has no binary to copy out of `target/release`. Treat +`nix build` as a build-and-test gate, not a source of an installable +artifact. + ### Rust version Two versions are pinned, and **three places must agree** when either moves: diff --git a/flake.nix b/flake.nix index d160afc..e2fd783 100644 --- a/flake.nix +++ b/flake.nix @@ -43,6 +43,14 @@ packages = [ toolchain pkgs.pkg-config pkgs.openssl pkgs.jq ]; RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library"; }; + + # Built with the pinned dev toolchain, not nixpkgs' own rustc, so a + # `nix build` matches what `nix develop` and CI compile with rather + # than whatever stable nixpkgs happens to carry. + rustPlatform = pkgs.makeRustPlatform { + cargo = rustToolchain; + rustc = rustToolchain; + }; in { devShells.default = shellFor rustToolchain; @@ -50,5 +58,25 @@ # Verifies the declared MSRV still builds: # nix develop .#msrv --command cargo test devShells.msrv = shellFor msrvToolchain; + + # This is a library with no `[[bin]]` target (see the "No CLI, and + # no binary at all" non-goal in GOALS.md), so the output directory + # ends up empty: `cargoInstallHook` only copies binaries matching a + # `[[bin]]` target out of `target/release`, and there are none to + # copy. `nix build` is still meaningful as a build-and-test gate — + # it compiles with the pinned toolchain and runs the full suite, + # including doctests, inside the Nix sandbox (no network, matching + # the "no credentials needed" property in CLAUDE.md) — just not as + # a source of an installable artifact. + packages.default = rustPlatform.buildRustPackage { + pname = "invoiceninjars"; + version = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).package.version; + src = self; + cargoLock.lockFile = ./Cargo.lock; + nativeBuildInputs = [ pkgs.pkg-config ]; + buildInputs = [ pkgs.openssl ]; + # The test suite needs no network (see CLAUDE.md), so the default + # `cargo test` checkPhase runs unmodified in the sandboxed build. + }; }); }