at master 5.7 kB view raw
1/* 2 Nix expression to test for regressions in the Haskell configuration overlays. 3 4 test-configurations.nix determines all attributes touched by given Haskell 5 configuration overlays (i. e. pkgs/development/haskell-modules/configuration-*.nix) 6 and builds all derivations (or at least a reasonable subset) affected by 7 these overrides. 8 9 By default, it checks `configuration-{common,nix,ghc-9.8.x}.nix`. You can 10 invoke it like this: 11 12 nix-build maintainers/scripts/haskell/test-configurations.nix --keep-going 13 14 It is possible to specify other configurations: 15 16 nix-build maintainers/scripts/haskell/test-configurations.nix \ 17 --arg files '[ "configuration-ghc-9.0.x.nix" "configuration-ghc-9.2.x.nix" ]' \ 18 --keep-going 19 20 You can also just supply a single string: 21 22 nix-build maintainers/scripts/haskell/test-configurations.nix \ 23 --argstr files "configuration-arm.nix" --keep-going 24 25 You can even supply full paths which is handy, as it allows for tab-completing 26 the configurations: 27 28 nix-build maintainers/scripts/haskell/test-configurations.nix \ 29 --argstr files pkgs/development/haskell-modules/configuration-arm.nix \ 30 --keep-going 31 32 By default, derivation that fail to evaluate are skipped, unless they are 33 just marked as broken. You can check for other eval errors like this: 34 35 nix-build maintainers/scripts/haskell/test-configurations.nix \ 36 --arg skipEvalErrors false --keep-going 37 38 You can also disable checking broken packages by passing a nixpkgs config: 39 40 nix-build maintainers/scripts/haskell/test-configurations.nix \ 41 --arg config '{ allowBroken = false; }' --keep-going 42 43 By default the haskell.packages.ghc*Binary sets used for bootstrapping GHC 44 are _not_ tested. You can change this using: 45 46 nix-build maintainers/scripts/haskell/test-configurations.nix \ 47 --arg skipBinaryGHCs false --keep-going 48*/ 49{ 50 files ? [ 51 "configuration-common.nix" 52 "configuration-nix.nix" 53 "configuration-ghc-9.8.x.nix" 54 ], 55 nixpkgsPath ? ../../.., 56 config ? { 57 allowBroken = true; 58 }, 59 skipEvalErrors ? true, 60 skipBinaryGHCs ? true, 61}: 62 63let 64 pkgs = import nixpkgsPath { inherit config; }; 65 inherit (pkgs) lib; 66 67 # see usage explanation for the input format `files` allows 68 files' = builtins.map builtins.baseNameOf (if !builtins.isList files then [ files ] else files); 69 70 packageSetsWithVersionedHead = 71 pkgs.haskell.packages 72 // ( 73 let 74 headSet = pkgs.haskell.packages.ghcHEAD; 75 # Determine the next GHC release version following GHC HEAD. 76 # GHC HEAD always has an uneven, tentative version number, e.g. 9.7. 77 # GHC releases always have even numbers, i.e. GHC 9.8 is branched off from 78 # GHC HEAD 9.7. Since we use the to be release number for GHC HEAD's 79 # configuration file, we need to calculate this here. 80 headVersion = lib.pipe headSet.ghc.version [ 81 lib.versions.splitVersion 82 (lib.take 2) 83 lib.concatStrings 84 lib.strings.toInt 85 (builtins.add 1) 86 toString 87 ]; 88 in 89 { 90 "ghc${headVersion}" = headSet; 91 } 92 ); 93 94 setsForFile = 95 fileName: 96 let 97 # extract the unique part of the config's file name 98 configName = builtins.head (builtins.match "configuration-(.+).nix" fileName); 99 # match the major and minor version of the GHC the config is intended for, if any 100 configVersion = lib.concatStrings (builtins.match "ghc-([0-9]+).([0-9]+).x" configName); 101 # return all package sets under haskell.packages matching the version components 102 setsForVersion = builtins.map (name: packageSetsWithVersionedHead.${name}) ( 103 builtins.filter ( 104 setName: 105 lib.hasPrefix "ghc${configVersion}" setName && (skipBinaryGHCs -> !(lib.hasInfix "Binary" setName)) 106 ) (builtins.attrNames packageSetsWithVersionedHead) 107 ); 108 109 defaultSets = [ pkgs.haskellPackages ]; 110 in 111 { 112 # use plain haskellPackages for the version-agnostic files 113 # TODO(@sternenseemann): also consider currently selected versioned sets 114 "common" = defaultSets; 115 "nix" = defaultSets; 116 "arm" = defaultSets; 117 "darwin" = defaultSets; 118 } 119 .${configName} or setsForVersion; 120 121 # attribute set that has all the attributes of haskellPackages set to null 122 availableHaskellPackages = builtins.listToAttrs ( 123 builtins.map (attr: lib.nameValuePair attr null) (builtins.attrNames pkgs.haskellPackages) 124 ); 125 126 # evaluate a configuration and only return the attributes changed by it, 127 # pass availableHaskellPackages as super in case intersectAttrs is used 128 overriddenAttrs = 129 fileName: 130 builtins.attrNames ( 131 lib.fix ( 132 self: 133 import (nixpkgsPath + "/pkgs/development/haskell-modules/${fileName}") { 134 haskellLib = pkgs.haskell.lib.compose; 135 inherit pkgs; 136 } self availableHaskellPackages 137 ) 138 ); 139 140 # list of derivations that are affected by overrides in the given configuration 141 # overlays. For common, nix, darwin etc. only the derivation from the default 142 # package set will be emitted. 143 packages = 144 builtins.filter 145 ( 146 v: 147 lib.warnIf (v.meta.broken or false) "${v.pname} is marked as broken" ( 148 v != null && (skipEvalErrors -> (builtins.tryEval (v.outPath or v)).success) 149 ) 150 ) 151 ( 152 lib.concatMap ( 153 fileName: 154 let 155 sets = setsForFile fileName; 156 attrs = overriddenAttrs fileName; 157 in 158 lib.concatMap (set: builtins.map (attr: set.${attr}) attrs) sets 159 ) files' 160 ); 161in 162 163packages