on fd39d56 help sign in
haskell.nix/modules/hackage.nix
81 lines 2.9 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: {
45 inherit (version) sha256;
46 inherit (rev) outPath;
47 revision = rev.revNum;
48 revisionSha256 = rev.sha256;
49 };
50 f = rev: acc: acc // {
51 # If there's a collision (e.g. a revision was
52 # reverted), pick the one with the smaller
53 # revNum. They're identical, but if the smaller one is
54 # r0 then we don't have to download a cabal file.
55 ${rev.sha256} = if lib.hasAttr rev.sha256 acc && acc.${rev.sha256}.revNum < rev.revNum
56 then acc.${rev.sha256}
57 else rev;
58 };
59 contentAddressedRevs = lib.foldr f {} (builtins.attrValues version.revisions);
60 in lib.mapAttrs (_: rev2Config) (version.revisions // contentAddressedRevs);
61 }));
63in {
64 options.ghc.package = lib.mkOption {
65 type = lib.types.package;
66 # obtain the compiler from the haskell packages.
67 # this should allow us to use `config` overrides
68 # in the nixpkgs setup, and properly override the
69 # complier as needed.
70 default = pkgs.haskell.compiler.${config.compiler.nix-name};
71 defaultText = "pkgs.haskell.compiler.\${config.compiler.nix-name}";
72 };
74 options.hackage.db = lib.mkOption {
75 type = lib.types.unspecified; # TODO: Worth type checking with modules? Or does that slow eval too much?
76 };
77 options.hackage.configs = lib.mkOption {
78 type = lib.types.unspecified;
79 };
80 config.hackage.configs = hackageConfigs;