on stack-cache-native help sign in
haskell.nix/modules/hackage.nix
89 lines 3.6 kB history raw
1{ lib, config, pkgs, ... }:
3let
4 # hackage looks like the following:
5 # { "package-name" =
6 # { "a.b.c.d" =
7 # rec { sha256 = $pkgVersionSha256;
8 # revisions =
9 # { r0 = { outPath = ./hackage/...; revNum = 0; sha256 = $revisionSha256; };
10 # default = revisions.r0; };
11 # };
12 # };
13 # };
14 # }
17 # However it's more convenient to deal with the leaf nodes, and as such
18 # push the `sha256` of the package/version into the revision and keep the
19 # revision.sha256 as revisionSha256; as well as making the revision content
20 # addressable by it's revision hash.
21 #
22 # Thus we transform hackage into hackageConfigs, which will look like:
23 # { "package-name" =
24 # { "a.b.c.d" =
25 # rec { sha256 = $packageVersionSha256;
26 # revisions =
27 # { r0 = { outPath = ./hackage/...;
28 # sha256 = $packageVersionSha256;
29 # revision = $revNum;
30 # revisionSha256 = $revisionSha256; };
31 # default = revisions.r0;
32 # $revisionSha256 = revisions.r0; };
33 # };
34 # };
35 # };
36 # }
38 hackageConfigs =
39 lib.flip lib.mapAttrs config.hackage.db
40 (pname: lib.mapAttrs
41 (vnum: version: version // {
42 revisions =
43 let
44 rev2Config = rev: { system, compiler, flags, pkgs, hsPkgs, pkgconfPkgs, ... }@modArgs: {
45 inherit (version) sha256;
46 revision = rev.revNum;
47 revisionSha256 = rev.sha256;
48 } // import rev modArgs;
49 f = rev: acc: acc // {
50 # If there's a collision (e.g. a revision was
51 # reverted), pick the one with the smaller
52 # revNum. They're identical, but if the smaller one is
53 # r0 then we don't have to download a cabal file.
54 ${rev.sha256} = if lib.hasAttr rev.sha256 acc && acc.${rev.sha256}.revNum < rev.revNum
55 then acc.${rev.sha256}
56 else rev;
57 };
58 contentAddressedRevs = lib.foldr f {} (builtins.attrValues version.revisions);
59 in lib.mapAttrs (_: rev2Config) (version.revisions // contentAddressedRevs);
60 }));
62in {
63 options.ghc.package = lib.mkOption {
64 type = lib.types.package;
65 # obtain the compiler from the haskell packages.
66 # this should allow us to use `config` overrides
67 # in the nixpkgs setup, and properly override the
68 # complier as needed.
69 default = pkgs.buildPackages.haskell-nix.compiler.${config.compiler.nix-name} or (throw ''
70 This version of Nixpkgs does not contain GHC ${config.compiler.version}
71 (or it is not present at attribute '${config.compiler.nix-name})').
72 Either switch to a version of Nixpkgs which does have this version, or use a version
73 of GHC which the current version of Nixpkgs contains.
74 '');
75 defaultText = "pkgs.buildPackages.haskell-nix.compiler.\${config.compiler.nix-name}";
76 };
78 options.hackage.db = lib.mkOption {
79 type = lib.types.unspecified; # TODO: Worth type checking with modules? Or does that slow eval too much?
80 };
81 options.hackage.configs = lib.mkOption {
82 type = lib.types.unspecified;
83 };
84 # Note: we inject rts."1.0" as invalid here. This package can only
85 # be built by GHC's build system. However it may show up in stackage
86 # snapshots. As such we just null it out.
87 config.hackage.configs = hackageConfigs
88 // { rts."1.0".revisions.default = null; };