Is it possible to override cargoSha256 in buildRustPackage?

overrideAttrs works on the attributes passed to stdenv.mkDerivation, not on the attributes passed to buildRustPackage, so at that point you already get the attributes that buildRustPackage is passing to stdenv.mkDerivation.

In order to get around this you need to look at the source of buildRustPackage and figure out how the mkDerivation attributes came to be.

For buildRustPackage the important part here is cargoDeps, which is the only location where cargoSha256 is used. So let’s say if you have a package foo and you’d like to change src and cargoSha256 you could override it like this:

foo.overrideAttrs (drv: rec {
  src = ...;
  cargoDeps = drv.cargoDeps.overrideAttrs (_: {
    inherit src; # You need to pass "src" here again,
                 # otherwise the old "src" will be used.
    outputHash = "... new cargoSha256 ...";
  });
})

The nested overrideAttrs is for the fetchcargo function (source), which again overrides mkDerivation attributes, so instead of passing sha256, you need to pass outputHash.

To illustrate this with a more concrete (but probably stupid) example, here is how to downgrade loc to version 0.4.0:

{ pkgs ? import <nixpkgs> {}, lib ? pkgs.lib }:

pkgs.loc.overrideAttrs (drv: rec {
  name = "loc-${version}";
  version = "0.4.0";

  src = pkgs.fetchFromGitHub {
    owner = "cgag";
    repo = "loc";
    rev = "v${version}";
    sha256 = "0cdcalfb0njvlswwvzbp0s7lwfqx4acxcmlsjw2bkanszbdz10s8";
  };

  cargoDeps = drv.cargoDeps.overrideAttrs (lib.const {
    name = "${name}-vendor";
    inherit src;
    outputHash = "1qiib37qlm1z239mfr5020m4a1ig2abhlnwava7il8dqvrxzsxpl";
  });
})

Here I also passed name along with the src attribute to make sure that the store path actually reflects the version change, so it’s less confusing than having a store path that says something like 0.4.1 but the actual version is 0.4.0.

29 Likes