nix.dev icon indicating copy to clipboard operation
nix.dev copied to clipboard

Using fakeSha256 when updating derivations

Open jkachmar opened this issue 4 years ago • 1 comments

I'm not entirely sure what the precise underlying cause is of this behavior, but I've noticed the following non-obvious gotcha when updating Nix derivations in the past:

  1. Modify a derivation somehow
    • e.g. bump a package version, either fetching a binary to patchelf, updating some Haskell dependency, etc.
  2. Forget to modify the sha256 field
    • That is to say, the valid sha256 associated with the previously working derivation remains
  3. Build the derivation
    • The derivation actually does build, leading developer to believe that their change was effective
  4. Attempt to use the derivation, observing that the result from the previously successful derivation is the one being pulled from the store

A behavioral reproduction:

  1. Clone nixpkgs and cd into the directory
    • The patches below specifically refer to the nixpkgs-unstable branch as of 13 June 2020
    • Relevant commit hash is dcb64ea42e64aaecd8e6fef65cc86245c9666818
  2. Apply the following (incorrect) patch
incorrect patch

diff --git a/pkgs/applications/misc/hello/default.nix b/pkgs/applications/misc/hello/default.nix
index 32c8c696..e3555418 100644
--- a/pkgs/applications/misc/hello/default.nix
+++ b/pkgs/applications/misc/hello/default.nix
@@ -2,7 +2,7 @@
 
 stdenv.mkDerivation rec {
   pname = "hello";
-  version = "2.10";
+  version = "2.9";
 
   src = fetchurl {
     url = "mirror://gnu/hello/${pname}-${version}.tar.gz";
  1. Run the following command and observe that the version is still 2.10
nix-shell -E '{pkgs ? import ./. {}}: pkgs.mkShell { buildInputs = [ pkgs.hello ]; }' --command 'hello --version'
  1. Drop the previous patch and apply the following (correct) patch
correct patch

diff --git a/pkgs/applications/misc/hello/default.nix b/pkgs/applications/misc/hello/default.nix
index 32c8c696..c0f60198 100644
--- a/pkgs/applications/misc/hello/default.nix
+++ b/pkgs/applications/misc/hello/default.nix
@@ -2,11 +2,11 @@
 
 stdenv.mkDerivation rec {
   pname = "hello";
-  version = "2.10";
+  version = "2.9";
 
   src = fetchurl {
     url = "mirror://gnu/hello/${pname}-${version}.tar.gz";
-    sha256 = "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i";
+    sha256 = "19qy37gkasc4csb1d3bdiz9snn8mir2p3aj0jgzmfv0r2hi7mfzc";
   };
 
   doCheck = true;
  1. Run the following command and observe that the version is now (correctly) 2.9
nix-shell -E '{pkgs ? import ./. {}}: pkgs.mkShell { buildInputs = [ pkgs.hello ]; }' --command 'hello --version'

I think having a worked out example (like the one above) would help, but an explanation of Nix's underlying behavior here would be very nice as well.

jkachmar avatar Jun 13 '20 17:06 jkachmar

I might try to make an actual PR updating the documentation later, but for now I wanted to write that down while it was still fresh in my mind since it had just come up in one of the ZuriHac chats.

jkachmar avatar Jun 13 '20 17:06 jkachmar