npins: init at 0.5.1 - #212
Conversation
Both argument lines were unexplained in the local delta against nixpkgs. Note each one's direct call site, and that only half of nix's justification disappears once corepkgs#211 is fixed.
npins-completions was built unconditionally while only its use was guarded, so on a cross build it still landed in $out/bin and forced an unguarded rm to remove it. Gate the build itself and collapse generation and removal into one guarded postInstall fragment, restoring the phase ordering the upstream expression relied on. nixpkgs keeps the rm inside the guard, which ships the helper on cross builds.
The openssh rationale explains why runtimePath omits a dependency, but sat above postFixup where that binding is merely consumed. Move it to the binding it describes and align the formal argument order with runtimePath so the two lists read identically.
Hickey/Lowy Analysis
Three findings were fixed; one is an accepted residual risk. A cross-validation round then ran once per lens, and both returned nothing new — the applied fixes strictly reduce interleaving relative to the initial commit. Hickey rationaleTwo real structural defects, both rooted in the same mistake: guarding use while building unconditionally. F1 (temporal coupling). Generation and removal lived in two concatenated fragments whose only ordering guarantee was left-to-right F2 (root cause).
The remaining seven were dismissed with evidence rather than dropped — notably #3, which is unavoidable because Lowy rationaleF10 (the finding worth fixing). Adding F13 is the same failure mode in miniature: the two added dependencies were the only unexplained lines in the local delta, because the sync normaliser strips bare F11 (accepted residual risk). The openssh omission and the F12 found the boundary question already answered by the repo: the sync tooling pairs the whole |
| # npins-completions is a build-time helper, not a shipped binary: it is only | ||
| # useful on a host that can execute the npins it just built, so it is neither | ||
| # built nor invoked when cross-compiling. |
There was a problem hiding this comment.
A lot of this can be inferred, do you mind having the comments shrunk down to a line or less?
Review feedback on #212: most of the prose can be inferred from the code. Collapse five multi-line comment blocks to one line each: - the runtime-dep preamble and per-dep notes move onto the formals themselves, keeping both reasons `nix` is required (npins' own direct calls, and nix-prefetch-git's nix-hash path from #211) so the surviving half stays identifiable if #211 closes - the openssh note keeps the mechanism (GIT_SSH_COMMAND is shell-resolved, so ssh comes from the caller's PATH) and drops the closure arithmetic - the completions guard and its build/removal pairing each fit one line No change to the derivation: same formals, runtimePath, build flags, postInstall and postFixup. Rebuilt and re-checked: `npins --version` returns 0.5.1, `$out/bin` holds only `npins`, all three completions install, and the wrapper PATH still carries git.
Why
ekala-orgpins nixpkgs for exactly two packages corepkgs does not carry —npinsandlefthook— and describes it as a gap-filler (ekala-org/README.md:7,ekala-org/nix/nixpkgs.nix:3). Lefthook landed in #209. This closes the second gap, so the nixpkgs input can be dropped entirely and the dependency graph collapses to a single npins-pinned corepkgs.npinsis the pinning tool the project already runs (nix/npins/sources.json,nix run nixpkgs#npins -- -d nix/npins update), so carrying it here also removes the bootstrapping oddity of fetching the pinning tool from the thing it pins.What it does
Ports
pkgs/by-name/np/npins/package.nixfrom nixpkgs master intopkgs/npins/default.nix. Registered automatically from the directory name — notop-level.nixentry.The package wraps npins with the external tools it shells out to, because npins is a process orchestrator: every pin type it supports is delegated to a separate binary. Miss one and that pin type fails at runtime with
command not found, not at build time.Divergence from nixpkgs
Five deliberate departures. A reviewer reading the diff against upstream should see each as a decision, not drift:
nixnix-prefetch-url(libnpins/src/nix.rs:20) andnix-instantiate(:264) directly, sonixis needed on every invocation. It also supplies thenix-hash/nix-storethatnix-prefetch-git's own wrapper omits when--hashis passed without--builder(#211). nixpkgs dropped this inb8a35d1d, reasoning that other packages assumenixis in PATH; that assumption does not hold in a bare dev shellskopeolibnpins/src/nix.rs:204). nixpkgs omits it, leavingnpins add containerlatently brokenopensshnpins-completionsunconditionally while guarding only its use, so on a cross build the build-time helper still lands in$out/binand has to be removed by a second, unguardedrm. This gates the build instead, which collapses generation and removal into one guardedpostInstallfragment# (Almost) all tests require internetcommentdoCheck = false, which this repo's rust builder already defaults (pkgs/rust/build-rust-package/default.nix:172)On
opensshnpins sets
GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=yes"(libnpins/src/nix.rs:76,pins/git.rs:695). That is a shell-resolved command, so git findssshvia PATH:get_ssh_command()returns the env value before consultingGIT_SSHorcore.sshcommand.So
ssh://pins work wherever the caller's environment provides openssh — any standard system — and fail loudly withssh: command not foundwhere it does not. Measured cost to add it: +77.5 MiB on a 635.9 MiB closure (~12%).Omitted because no
ssh://pin exists in this project, the failure names its own fix, and nixpkgs omits it too. The rationale is recorded at theruntimePathbinding so a future reader sees a decision rather than an oversight.Departure 1 is verified functionally, not argued: with
nixoff PATHnix-prefetch-git --hash sha256 …dies withnix-hash: command not foundat line 522; withnixon PATH the identical invocation returns the full JSON result. Relates to #211, which this does not block on — npins needsnixfor its own direct calls regardless of how #211 is resolved.Verification
The wrapper PATH resolves
nix,nix-prefetch-git,nix-prefetch-docker,skopeo, andgit, and contains no openssh. Beyond building, npins was exercised end-to-end in a scratch dir:npins initfetched a real nixpkgs revision, andnpins add git … --at 0.5.1resolvedsha256-PRdGQlxpv8qXdQ6KwlP2Ky2HBHDY83lGTSiD6yljUxE=— independently reproducing thesrchash pinned above.Try it locally
Intent source
npins: init at 0.5.1implementation handoff that specified the target file, the five departures, and the PR-body requirements. The upstream reference ispkgs/by-name/np/npins/package.nixon nixpkgs master./verify prshould confirm the delivered package realizes the handoff — a workingnpinswith all six runtime tools wrapped, the documented divergences present, and the omissions annotated in-file.