Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: haskell: allow overriding all package sets at once #39309

Merged
merged 1 commit into from Apr 23, 2018

Conversation

basvandijk
Copy link
Member

CC @peti

Motivation for this change

I often have a bunch of overrides for local Haskell packages that I want to apply to all, or at least a bunch of, package sets at once. For example today I worked on inline-c and had to write the following default.nix in the inline-c repo:

{ nixpkgs ? import <nixpkgs> }:
let
  overlay = final : previous :
    let
      haskellOverrides = {
        overrides = self : super : with final.haskell.lib;
          let
            localHsPkg = name :
              let
                src = ./. + "/${name}";
                spec = super.haskellSrc2nix {
                  inherit name;
                  src = src + "/${name}.cabal";
                };
                drv = super.callPackage spec {};
              in overrideCabal drv (_drv: { inherit src; });
          in {
            inline-c     = localHsPkg "inline-c";
            inline-c-cpp = localHsPkg "inline-c-cpp";
          };
      };
    in {
      haskellPackages = previous.haskellPackages.override haskellOverrides;
      haskell = previous.haskell // {
        packages = previous.haskell.packages // {
          ghc822 = previous.haskell.packages.ghc822.override haskellOverrides;
          ghc841 = previous.haskell.packages.ghc841.override haskellOverrides;
          ghc842 = previous.haskell.packages.ghc842.override haskellOverrides;
        };
      };
    };
in nixpkgs { overlays = [ overlay ]; }

With the proposed change the last part can be simplified to:

{
  haskell = previous.haskell // {
    overrides = haskellOverrides;
  };
}

which will override all compiler-specific package sets using haskellOverrides.

An alternative design could be to make overrides an argument of <nixpkgs/pkgs/top-level/haskell-packages.nix> so that we can override haskell as follows:

{
  haskell = previous.haskell.override {
    overrides = haskellOverrides;
  };
}

I choose the former because it looks a bit simpler.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option build-use-sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Fits CONTRIBUTING.md.

Copy link
Member

@peti peti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool, I like it!

The only minor nitpick I have is that haskell.overrides sounds like it would be applied to all attribute sets inside of haskell, which includes haskell.compiler in particular, but the overrides are not applied there. And they shouldn't be! I'm just wondering whether people will be confused by name of the function.

packageOverrides, maybe?

Anyhow, I don't feel strongly about this issue.

Setting haskell.packageOverrides like so:

  haskell = super.haskell // {
    packageOverrides = self: super: {
      my-package = ...;
      my-other-package = ...;
    };
  };

causes all compiler-specific package sets to be overridden with those
overrides.
@basvandijk
Copy link
Member Author

Good point. I switched to packageOverrides.

In the first version I wrote I used haskell.packages.overrides which looks the most consistent. However setting that is a bit more involved than setting packageOverrides:

{  
  haskell = previous.haskell // {
    packages = previous.haskell.packages // {
      overrides = self: super: {};
    };
  };
}

versus:

{  
  haskell = previous.haskell // {
    packageOverrides = self: super: {};
  };
}

Although when I look at it again it's not that much more involved. Which one do you like better?

@peti peti merged commit 21d688f into NixOS:master Apr 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants