Is it possible to override cargoSha256 in buildRustPackage?

Thankfully such hacks may be a thing of the past pretty soon lib.extendMkDerivation: init by ShamrockLee · Pull Request #234651 · NixOS/nixpkgs · GitHub

To clarify, https://github.com/NixOS/nixpkgs/pull/234651 alone doesn’t solve the “arguments not overridable via the <pkg>.overrideAttrs” issue.

To make cargoHash overridable in buildRustPackage-constructed packages, we need to utilize the fixed-point arguments support of the base build helper and refer to cargoHash as finalAttrs.cargoHash or finalAttrs.passthru.cargoHash to use the overridden version.

For rustPlatform.buildRustPackage, the base build helper is stdenv.mkDerivation, which already supports fixed-point arguments. While for build helpers that are not directly based on stdenv.mkDerivation, it would be helpful to refactor the base build helper with lib.extendMkDerivation.

We underwent a similar transition to make vendorHash overridable for buildGoModule-constructed packages:

A more complex transition for Python packages to use overrideAttrs instead of overridePythonAttrs is underway. Reviews and feedbacks are welcome:

I’m trying the solution here (overriding cargoDeps) but encountering a very strange error during build:

error: output path '/nix/store/xfjsxcnlw6qzrshafkj5988h5img3lyv-lazyjj-0.5.0-vendor.drv.chroot/root/nix/store/r57fwwdbf62hfrwlpvhjz9bp4f3hmzfb-lazyjj-0.5.0-vendor' should be a non-executable regular file since recursive hashing is not enabled (one of outputHashMode={flat,text} is true)

This is my code right now:

  lazyjj.overrideAttrs (old: rec {
    src = pkgs.fetchFromGitHub {
      owner = "Cretezy";
      repo = "lazyjj";
      rev = "push-rymqkytxnusu";
      hash = "sha256-UN2eTSgHUQQEaALZ51H4r6nKnGcm6klnbSkUrEBBoNw=";
    };

    cargoDeps = old.cargoDeps.overrideAttrs (
      lib.const {
        inherit src;
        # Deliberately invalid hash -- I'm not sure how to effectively
        # pre-determine it.
        outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
      }
    );
  })

What’s going on here? :<

Edit: Manually setting outputHashMode = "recursive" fixed the issue, but upon updating outputHash to match what the proceeding hash mismatch error was expecting, I received the original ERROR: cargoHash or cargoSha256 is out of date error!

The result derivation of fetchCargoVendor is not currently overridable.

BTW, <pkg>.overrideAttrs (provided by stdenv.mkDerivation) supports { foo = ""; }, previousAttrs: { foo = ""; }, and finalAttrs: previousAttrs; { foo = ""; }.

Let me take back what I said above.

Even though the fetchCargoVendor-constructed derivation is not fully overridable in current implementation, the hash can be overridden by overriding the vendorStaging;

  lazyjj.overrideAttrs (finalAttrs: previousAttrs: {
    src = pkgs.fetchFromGitHub {
      owner = "Cretezy";
      repo = "lazyjj";
      rev = "push-rymqkytxnusu";
      hash = "sha256-UN2eTSgHUQQEaALZ51H4r6nKnGcm6klnbSkUrEBBoNw=";
    };

    cargoDeps = previousAttrs.cargoDeps.overrideAttrs (previousAttrs: {
        vendorStaging = previousAttrs.vendorStaging.overrideAttrs {
          inherit (finalAttrs) src;
          # Deliberately invalid hash -- I'm not sure how to effectively
          # pre-determine it.
          outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
        };
      }
    );
  })

This seems to work but it still ultimately fails to provide me the hash I should be using like I’d expect it to…

Could you elaborate this? After replacing the fake hash with the hash got from the error message, the overridden lazyjj package builds on my machine.

Now I know why my previous suggestion doesn’t work. The src taken by cargoDeps doesn’t update when the main src is overridden. Thank you for testing and pointing out the issue.

I’m authoring a fix in Nixpkgs PR 435239. Please take a look!

Just faced this issue. From the rustPlatform docs: nixpkgs/doc/languages-frameworks/rust.section.md at 6bc0621ff46a81a7fa9063788127bad9906ad1a9 · NixOS/nixpkgs · GitHub
Example:

final: prev:
let
  name = "cargo-nextest";
  version = "0.9.124";
  src = final.fetchFromGitHub {
    owner = "nextest-rs";
    repo = "nextest";
    rev = "cargo-nextest-${version}";
    hash = "sha256-qvJ/dqbls2fVSPY++kYBIeiu14eDD8ORuvcD8dEtMZ8=";
  };
in
{
  ${name} = prev.${name}.overrideAttrs (oldAttrs: rec {
    inherit version src;

    cargoDeps = prev.rustPlatform.fetchCargoVendor {
      inherit src;
      name = "${name}-${version}-vendor";
      hash = "sha256-3fZSXBP6vMh7GN2eY2upsvV/mTuDOcSovdsbcZBQA4U=";
    };
  });
}

Here’s an example if you want minimal cargoDeps override. Of course, it’s coupled with fetchCargoVendor implementation, which is very likely to be break in the future.

codex = prev.codex.overrideAttrs (oldAttrs: rec {
  version = "0.153.4";
  src =
    assert lib.assertMsg (lib.versionOlder oldAttrs.version "0.153.4")
      "codex is updated in the upstream";
    final.fetchFromGitHub {
      owner = "openai";
      repo = "codex";
      tag = "rust-v${version}";
      hash = "sha256-lHiDj5SodaM3mh8goMm6esfejeAT+Y3JJWrRnyj6sJo=";
    };
  cargoHash = "sha256-GG6kOXmCdq+bZLU2ul0DIVL8lDuweayvZvXn6+bcUZw=";
  cargoDeps = oldAttrs.cargoDeps.overrideAttrs (oldAttrs: {
    vendorStaging = oldAttrs.vendorStaging.overrideAttrs {
      outputHash = cargoHash;
    };
  });
});