Hiding an upstream Haskell package - Nix

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Magnus Therning

(I posted this on the Nix discourse too: https://discourse.nixos.org/t/hiding-a-haskell-package)

I'm the developer of two related Haskell packages, _sandi_ and _omnicodec_.

My rather naïve first attempt to use Nix to build them both is this

with (import <nixpkgs> {});

let
  t = lib.trivial;
  hl = haskell.lib;

  addBuildTools = (t.flip hl.addBuildTools) [haskellPackages.cabal-install];

  sandiPkg = haskellPackages.developPackage {
    root = ./sandi;

    modifier = (t.flip t.pipe)
      [addBuildTools];
  };

  omnicodecPkg = haskellPackages.developPackage {
    root = ./omnicodec;

    modifier = (t.flip t.pipe)
      [addBuildTools];
  };

in {
  sandi = sandiPkg;
  omnicodec = omnicodecPkg;
}

It does work, but one thing I noticed is that since _sandi_ is packaged in nixpkgs it's the upstream package that's used rather than the local development version.

How do I go about forcing the build of _omnicodec_ to use the local _sandi_ instead of the one in nixpkgs?

I’m the developer of two related Haskell packages, sandi and omnicodec. My rather naïve first attempt to use Nix to build them both is this with (import <nixpkgs> {}); let t = lib.trivial; hl = haskell.lib; addBuildTools = (t.flip hl.addBuildTools) [haskellPackages.cabal-install]; sandiPkg = haskellPackages.developPackage { root = ./sandi; modifier = (t.flip t.pipe) [addBuildTools]; }; omnicodecPkg = haskellPackages.developPackage { root = ./omnicodec; m...
Ben Kolera

One big note: the import <nixpkgs> is a big red flag. You don't get any reproducibility that way because the build is then dependent on the nix-channel of the machine.

Ben Kolera

You could override sandi in the haskell packages that you use to build omnicodec.

Ben Kolera

But this kind of hierarchy of nix doesn't scale too well, I find. Especially once you start needing overrides around the place wrt nixpkgs.

Ben Kolera

See https://stackoverflow.com/questions/56414329/how-do-i-override-a-haskell-package-with-a-git-local-package-with-nix-when-usi for an example that should help! :slight_smile:

Essentially I'm using this: default.nix { nixpkgs ? import <nixpkgs> {}, compiler ? "ghc864" }: nixpkgs.pkgs.haskell.packages.${compiler}.callPackage ./gitchapter.nix { } gitchapter.nix {
Magnus Therning

Thanks, that SO question unlocked it for me. I ended up with the following setup:

  sandiPkg = haskellPackages.developPackage {
    root = ./sandi;

    modifier = (t.flip t.pipe)
      [addBuildTools];
  };

  myHaskellPackages = pkgs.haskell.packages.ghc865.override {
    overrides = self: super: rec {
      sandi = sandiPkg;
    };
  };

  omnicodecPkg = myHaskellPackages.developPackage {
    root = ./omnicodec;

    modifier = (t.flip t.pipe)
      [addBuildTools];
  };

Which seems to work the way I want.

Any suggestions for improvements? (Now it's time to worry about things like re-producability :grinning: )

Ben Kolera

Nah, no other feedback. I just see too many people go to all the trouble of nix and not pin nixpkgs and actually don't get reproducablity. I want to save everyone from this sadness because nix is rad. :slight_smile: