-
Notifications
You must be signed in to change notification settings - Fork 1
/
lib.nix
106 lines (94 loc) · 2.5 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
99
100
101
102
103
104
105
106
let
inherit
(builtins)
attrNames
concatMap
elemAt
fetchClosure
foldl'
hasAttr
head
isAttrs
length
listToAttrs
replaceStrings
zipAttrsWith
;
# x86-64-linux
busybox = fetchClosure {
fromPath = "/nix/store/62z5dklpfq7n0wi5fdasf4y0ymy12nxg-busybox-1.36.1";
toPath = "/nix/store/r4nhqzdi024kqw6riwpghidhyp2kdvfw-busybox-1.36.1";
fromStore = "https://cache.nixos.org";
};
# This way we avoid depending on nixpkgs just to turn our store paths from
# `fetchClosure` back into derivations
symlinkPath = args:
(derivation {
inherit (args) name system;
builder = "${busybox}/bin/ln";
args = ["-s" args.path (placeholder "out")];
pathToLink = args.path;
})
// args;
aggregate = {
name,
constituents,
meta ? {},
}: let
script = ''
mkdir -p $out/nix-support
touch $out/nix-support/hydra-build-products
echo $constituents > $out/nix-support/hydra-aggregate-constituents
for i in $constituents; do
if [ -e $i/nix-support/failed ]; then
touch $out/nix-support/failed
fi
done
'';
in
(derivation {
inherit name constituents;
system = "x86_64-linux";
preferLocalBuild = true;
_hydraAggregate = true;
PATH = "${busybox}/bin";
builder = "${busybox}/bin/sh";
args = ["-c" script];
})
// {inherit meta;};
sane = replaceStrings ["."] ["-"];
filterAttrs = pred: set:
listToAttrs (concatMap (name: let
value = set.${name};
in
if pred name value
then [{inherit name value;}]
else []) (attrNames set));
mapAttrsToList = f: attrs:
map (name: f name attrs.${name}) (attrNames attrs);
recursiveUpdateUntil = pred: lhs: rhs: let
f = attrPath:
zipAttrsWith (
n: values: let
here = attrPath ++ [n];
in
if
length values
== 1
|| pred here (elemAt values 1) (head values)
then head values
else f here values
);
in
f [] [rhs lhs];
recursiveUpdate = lhs: rhs:
recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs)) lhs rhs;
mapAndMergeAttrs = f: attrs: foldl' recursiveUpdate {} (mapAttrsToList f attrs);
optionalAttr = attrs: name:
if hasAttr name attrs
then {${name} = attrs.${name};}
else {};
last = list: elemAt list ((length list) - 1);
in {
inherit filterAttrs mapAndMergeAttrs sane symlinkPath aggregate optionalAttr last;
}