This repository has been archived by the owner on Sep 10, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
lib.nix
138 lines (122 loc) · 3.35 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
An action is a function of the form:
```nix
{ name, id }: {
io = ''
inputs: {
# require last fact with `count` of at least 1
tick: match: count: >0
# stop at 10 (no `over_nine` input will be created)
over_nine: {
not: true
match: count: >9
}
# has no influence on runnability
double: {
optional: true
match: double: true
}
}
output: {
# this is the default
success: null
failure: count: inputs.tick.value.count
}
'';
job = { tick, double ? false }:
# `tick` is the latest fact that matches
# `double` is provided if found
…; # nomad HCL job spec in JSON format
}
```
*/
{lib, ...}: {
flake.lib = let
inherit (builtins) mapAttrs;
in rec {
# Calls an action or a file containing one.
callAction = name: action: {
id,
inputs ? throw "no inputs given",
ociRegistry ? null,
}: let
inherit
(builtins)
isFunction
typeOf
deepSeq
;
validateAction = {io, ...} @ action:
lib.pipe action (map deepSeq [
(
let
t = typeOf io;
in
if t != "string"
then throw "`io` must be string but is ${t}"
else null
)
]);
hydrateNomadJob = mapAttrs (k: job:
assert !job ? ID; # author must not set an ID
lib.recursiveUpdate job ({
type = "batch";
}
// lib.optionalAttrs (job ? group) {
group =
mapAttrs
(k: group:
lib.recursiveUpdate group (lib.optionalAttrs (group ? task) {
task =
mapAttrs (k: lib.recursiveUpdate {driver = "nix";})
group.task;
}))
job.group;
}));
mkActionState = action:
action
// {
inherit (action) io;
}
// lib.optionalAttrs (action ? job) {
job = hydrateNomadJob (action.job inputs);
};
in
lib.pipe action [
(action:
if isFunction action
then action
else import action)
(action: action {inherit name id ociRegistry;})
validateAction
mkActionState
];
# Recurses through a directory, considering every file an action.
# The path of the file from the starting directory is used as name.
listActions = dir:
lib.listToAttrs (map
(file:
lib.nameValuePair
(lib.pipe file [
toString
(lib.removePrefix "${toString dir}/")
(lib.removeSuffix ".nix")
])
file)
(lib.filesystem.listFilesRecursive dir));
# Like `listActions` but calls every action.
callActions = dir:
mapAttrs callAction (listActions dir);
callActionsWithDefaults = defaults: dir:
mapAttrs (k: actionWithDefaults defaults) (callActions dir);
callActionsWithExtraArgs = extras: dir:
mapAttrs (k: v: callAction k (actionWithExtraArgs extras (import v))) (listActions dir);
actionWithDefaults = defaults: innerAction: args:
defaults
// mapAttrs (k: v:
if v == null
then defaults.${k} or null
else v) (innerAction args);
actionWithExtraArgs = extras: innerAction: args: innerAction (args // extras);
};
}