Overlays for packages using let-in

When I need to overlay a package for something simple, like setting a specific version I often end up having to do a “whole bunch” more than just changing a version and hash. It frustrates me even more when the package I’m replacing has done a good job extracting variables with let ... in syntax. Take fluxcd for example; nixpkgs/pkgs/by-name/fl/fluxcd/package.nix at 6313551cd05425cd5b3e63fe47dbc324eabb15e4 · NixOS/nixpkgs · GitHub - everything I need to edit is nicely extracted using let ... in, but I can’t use it, can I? That leaves me duplicating a bunch of the source again in my overlay.

# part of a larger nix file, `pkgs` is the only thing not shown here, but it's obvious what that is
flux_overlay = final: prev: {
  fluxcd = prev.fluxcd.overrideAttrs (oldAttrs: let
    version = "2.5.1";
    vendorHash = "sha256-2fThvz/5A1/EyS6VTUQQa5Unx1BzYfsVRE18xOHtLHE=";
    src = pkgs.fetchFromGitHub {
      owner = "fluxcd";
      repo = "flux2";
      rev = "v${version}";
      hash = "sha256-BuFylOWR30aK7d1eN+9getR5amtAtkkhHNAPfdfASHs=";
    };
    manifests = pkgs.fetchzip {
      url = "https://github.com/fluxcd/flux2/releases/download/v${version}/manifests.tar.gz";
      hash = "sha256-bIIK8igtx0gUcn3hlBohE0MG9PMhyThz4a71pkonBpE=";
      stripRoot = false;
    };
  in {
    inherit version vendorHash src;
    
    # copied verbatim since manifests has changed, and
    # had I left this alone, my overlay of manifests wouldn't have any affect!
    postUnpack = ''
      cp -r ${manifests} source/cmd/flux/manifests

      # disable tests that require network access
      rm source/cmd/flux/create_secret_git_test.go
    '';
    
    # I want the cli tool to report the overlay's version
    ldflags = ["-s" "-w" "-X main.VERSION=${version}"];

    # sure there's `doInstallCheck = false` instead, but I'm making a point
    installCheckPhase = ''
      $out/bin/flux --version | grep ${version} > /dev/null
    '';
  });
};

I don’t mind it, but in an effort to always learn and improve my understanding of Nix - is there a better way to write overlays than by duplicating all this stuff? I have a feeling it’s due to the prev’s usage of let ... in, but is there no better way?

Correct. rec also suffers from the same problem.

Ideally, all the build helpers would support the fixed-point finalAttrs argument, but most (like buildGoModule in this case) currently don’t. (And even if they did, the package expression still needs to properly use it.)

So currently, you’re overall stuck with this ugly style of override for fluxcd.

1 Like