-
Notifications
You must be signed in to change notification settings - Fork 0
/
lib.nix
98 lines (98 loc) · 5.45 KB
/
lib.nix
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
pkgs:
with pkgs.haskell.lib; with pkgs.lib; with builtins;
let
# traceAttrsN :: Map a b -> Map a b -- Given an attrset, instrument it so its elements self-trace on use.
traceAttrsN = depth: attrs: mapAttrs (k: v: traceSeqN depth { "${k}" = v; } v) attrs;
# maybeTraceAttrs :: Bool -> Map a b -> Map a b
maybeTraceAttrs = bool: xs: if bool then traceAttrsN 5 xs else xs;
# mergeAttrsWithFunc :: (a -> a -> a) -> Map k a -> Map k a -> Map k a
mergeAttrsWithFunc = f: set1: set2:
fold (n: set: if set1 ? ${n}
then setAttr set n (f set1.${n} set2.${n})
else set )
(set2 // set1) (attrNames set2);
# mergeNestedAttrs2 :: Map k a -> Map k a -> Map k a
mergeNestedAttrs2 = xs: ys: mergeAttrsWithFunc (x: y: x // y) xs ys;
# valPath :: FilePath -> Key -> OverrideKey -> FilePath
valPath = path: key: type: (path + "/${key}.${type}");
# interpSrcJson :: FilePath -> Repo -> Src
interpSrcJson = path: repo: pkgs.fetchgit (removeAttrs (fromJSON (readFile (valPath path repo "src-json"))) ["date"]);
# interpChdir :: Bool -> FilePath -> String
interpChdir = flag: chdir: if flag then "cd ${chdir}; " else "";
# listfiles :: FilePath -> [FilePath]
listFiles = path: mapAttrsToList (k: _: k) (filterAttrs (k: v: v == "regular") (readDir path));
# fileMapAdd :: Map Attr [OverrideKey] -> FilePath -> Map Attr [OverrideKey]
fileMapAdd = bag: x: let destr = splitString "." x; in bag // { "${elemAt destr 0}" = (bag."${elemAt destr 0}" or []) ++ [(elemAt destr 1)]; };
# allPins :: FilePath -> Bool -> Map Attr [OverrideKey]
allPins = path: tracep: maybeTraceAttrs false (foldl' fileMapAdd {} (listFiles path));
# interSinglePin :: FilePath -> Attr -> Map Override OverrideVal -> OverrideKey -> Map Override OverrideVal
interpSinglePin = path: attr: acc: overkey: acc //
(if overkey == "src-json"
then { pin = true; }
else { "${overkey}" = import (valPath path attr overkey); });
# readPackagePinSpecs :: FilePath -> Attr -> [OverrideKey] -> Map Attr (Map Override OverrideVal)
readPackagePinSpecs = path: attr: pins: { "${attr}" = (foldl' (interpSinglePin path attr) {} pins); };
# readPinSpecsFromDir :: FilePath -> Map Attr (Map Override OverrideVal)
readPinSpecsFromDir = result: path: tracep: foldl' (acc: x: acc // x) {} (mapAttrsToList (readPackagePinSpecs path) (removeAttrs (allPins path tracep) ["nixpkgs"]));
# printPinSpecs :: Map Attr (Map Override OverrideVal) -> IO [Bool]
printPinSpecs = pinSpecs: mapAttrsToList (attr: over: traceSeqN 5 { "${attr}" = over; } true) pinSpecs;
# ppBool :: Bool -> String
ppBool = x: if x then "yes" else "no";
# over :: Attr -> Map Override OverrideVal -> Map DrvKey DrvVal -> Map DrvKey DrvVal
over = super:
attr:
{ pin ? false
, just ? null
, repo ? attr, chdir ? null
, dontRevise ? pin
, patches ? [], patch ? null
, jailbreak ? false
, doHaddock ? true
, doCheck ? true
, scope ? null
, headPatch ? true
, headCabal ? true
, extAttrs ? {}
, extLists ? {}
, extStrs ? {}
}:
let result = overrideCabal (if just == null then super."${attr}" else just)
(drv: {}
// optionalAttrs pin {
src = interpSrcJson ./pins repo;
prePatch = interpChdir (chdir != null) chdir; }
// optionalAttrs dontRevise {
editedCabalFile = null;
revision = null; }
// optionalAttrs jailbreak { jailbreak = true; }
// optionalAttrs (!doHaddock) { doHaddock = false; }
// optionalAttrs (!doCheck) { doCheck = false; }
// optionalAttrs (patch != null) { patches = [(pkgs.fetchpatch patch)]; }
// (mapAttrs (k: v: (drv."${k}" or {}) // v) extAttrs)
// (mapAttrs (k: v: (drv."${k}" or []) ++ v) extLists)
// (mapAttrs (k: f: f (drv."${k}" or "")) (maybeTraceAttrs true extStrs))
);
in if scope == null then result
else result.overrideScope scope;
attrHasPin = result: attr: pin: result ? "${attr}" && result."${attr}" ? "${pin}";
patchAttrRepoPin = result: attr: pins: pins //
optionalAttrs ((pins.repo or attr) != attr
&& attrHasPin result pins.repo "pin")
{ pin = true; };
allPinSpecs = pinsDir: declPinsFile: tracep: self: super:
let result =
(mergeNestedAttrs2
(readPinSpecsFromDir result pinsDir tracep)
(mapAttrs (patchAttrRepoPin result) (import declPinsFile pkgs.haskell.lib self super)));
in result;
computeOverrides = pinsDir: declPinsFile: tracep: self: super: mapAttrs (over super) (maybeTraceAttrs tracep (allPinSpecs pinsDir declPinsFile tracep self super));
printAllPinSpecs = pinsDir: declPinsFile: self: super: printPinSpecs (allPinSpecs pinsDir declPinsFile self super);
suppressedPatches = specs: filterAttrs (_: v: v ? headPatch && !v.headPatch) specs;
suppressedCabals = specs: filterAttrs (_: v: v ? headCabal && !v.headCabal) specs;
in {}
// pkgs.lib
// pkgs.haskell.lib
// builtins
// {
inherit over readPinSpecsFromDir printPinSpecs computeOverrides printAllPinSpecs mergeNestedAttrs2 maybeTraceAttrs suppressedPatches suppressedCabals;
}