summary refs log tree commit diff
path: root/maintainers/scripts/haskell/test-configurations.nix
blob: 05f26f86147321ba840b323afd77d58f03f4d58c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* Nix expression to test for regressions in the Haskell configuration overlays.

   test-configurations.nix determines all attributes touched by given Haskell
   configuration overlays (i. e. pkgs/development/haskell-modules/configuration-*.nix)
   and builds all derivations (or at least a reasonable subset) affected by
   these overrides.

   By default, it checks `configuration-{common,nix,ghc-8.10.x}.nix`. You can
   invoke it like this:

     nix-build maintainers/scripts/haskell/test-configurations.nix --keep-going

   It is possible to specify other configurations:

     nix-build maintainers/scripts/haskell/test-configurations.nix \
       --arg files '[ "configuration-ghc-9.0.x.nix" "configuration-ghc-9.2.x.nix" ]' \
       --keep-going

   You can also just supply a single string:

     nix-build maintainers/scripts/haskell/test-configurations.nix \
       --argstr files "configuration-arm.nix" --keep-going

   You can even supply full paths which is handy, as it allows for tab-completing
   the configurations:

     nix-build maintainers/scripts/haskell/test-configurations.nix \
       --argstr files pkgs/development/haskell-modules/configuration-arm.nix \
       --keep-going

   By default, derivation that fail to evaluate are skipped, unless they are
   “just” marked as broken. You can check for other eval errors like this:

     nix-build maintainers/scripts/haskell/test-configurations.nix \
       --arg skipEvalErrors false --keep-going

   You can also disable checking broken packages by passing a nixpkgs config:

     nix-build maintainers/scripts/haskell/test-configurations.nix \
       --arg config '{ allowBroken = false; }' --keep-going

   By default the haskell.packages.ghc*Binary sets used for bootstrapping GHC
   are _not_ tested. You can change this using:

     nix-build maintainers/scripts/haskell/test-configurations.nix \
       --arg skipBinaryGHCs false --keep-going

*/
{ files ? [
    "configuration-common.nix"
    "configuration-nix.nix"
    "configuration-ghc-8.10.x.nix"
  ]
, nixpkgsPath ? ../../..
, config ? { allowBroken = true; }
, skipEvalErrors ? true
, skipBinaryGHCs ? true
}:

let
  pkgs = import nixpkgsPath { inherit config; };
  inherit (pkgs) lib;

  # see usage explanation for the input format `files` allows
  files' = builtins.map builtins.baseNameOf (
    if !builtins.isList files then [ files ] else files
  );

  setsForFile = fileName:
    let
      # extract the unique part of the config's file name
      configName = builtins.head (
        builtins.match "configuration-(.+).nix" fileName
      );
      # match the major and minor version of the GHC the config is intended for, if any
      configVersion = lib.concatStrings (
        builtins.match "ghc-([0-9]+).([0-9]+).x" configName
      );
      # return all package sets under haskell.packages matching the version components
      setsForVersion =  builtins.map (name: pkgs.haskell.packages.${name}) (
        builtins.filter (setName:
          lib.hasPrefix "ghc${configVersion}" setName
          && (skipBinaryGHCs -> !(lib.hasInfix "Binary" setName))
        ) (
          builtins.attrNames pkgs.haskell.packages
        )
      );

      defaultSets = [ pkgs.haskellPackages ];
    in {
      # use plain haskellPackages for the version-agnostic files
      # TODO(@sternenseemann): also consider currently selected versioned sets
      "common" = defaultSets;
      "nix" = defaultSets;
      "arm" = defaultSets;
      "darwin" = defaultSets;
    }.${configName} or setsForVersion;

  # evaluate a configuration and only return the attributes changed by it
  overriddenAttrs = fileName: builtins.attrNames (
    import (nixpkgsPath + "/pkgs/development/haskell-modules/${fileName}") {
      haskellLib = pkgs.haskell.lib.compose;
      inherit pkgs;
    } {} {}
  );

  # list of derivations that are affected by overrides in the given configuration
  # overlays. For common, nix, darwin etc. only the derivation from the default
  # package set will be emitted.
  packages = builtins.filter (v:
    lib.warnIf (v.meta.broken or false) "${v.pname} is marked as broken" (
      v != null
      && (skipEvalErrors -> (builtins.tryEval (v.outPath or v)).success)
    )
  ) (
    lib.concatMap (fileName:
      let
        sets = setsForFile fileName;
        attrs = overriddenAttrs fileName;
      in
        lib.concatMap (set: builtins.map (attr: set.${attr}) attrs) sets
    ) files'
  );
in

packages