+1
-1
.github/workflows/test.yml
+1
-1
.github/workflows/test.yml
···
8
8
runs-on: ubuntu-latest
9
9
steps:
10
10
- uses: cachix/install-nix-action@v30
11
-
- run: nix flake check -L github:vic/checkmate --override-input target github:$GITHUB_REPOSITORY/$GITHUB_SHA
11
+
- run: nix flake check -L github:$GITHUB_REPOSITORY/$GITHUB_SHA?dir=checkmate --override-input target github:$GITHUB_REPOSITORY/$GITHUB_SHA
+184
checkmate/flake.lock
+184
checkmate/flake.lock
···
1
+
{
2
+
"nodes": {
3
+
"flake-parts": {
4
+
"inputs": {
5
+
"nixpkgs-lib": [
6
+
"nixpkgs-lib"
7
+
]
8
+
},
9
+
"locked": {
10
+
"lastModified": 1763759067,
11
+
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
12
+
"owner": "hercules-ci",
13
+
"repo": "flake-parts",
14
+
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
15
+
"type": "github"
16
+
},
17
+
"original": {
18
+
"owner": "hercules-ci",
19
+
"repo": "flake-parts",
20
+
"type": "github"
21
+
}
22
+
},
23
+
"import-tree": {
24
+
"locked": {
25
+
"lastModified": 1763762820,
26
+
"narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=",
27
+
"owner": "vic",
28
+
"repo": "import-tree",
29
+
"rev": "3c23749d8013ec6daa1d7255057590e9ca726646",
30
+
"type": "github"
31
+
},
32
+
"original": {
33
+
"owner": "vic",
34
+
"repo": "import-tree",
35
+
"type": "github"
36
+
}
37
+
},
38
+
"nix-github-actions": {
39
+
"inputs": {
40
+
"nixpkgs": [
41
+
"nix-unit",
42
+
"nixpkgs"
43
+
]
44
+
},
45
+
"locked": {
46
+
"lastModified": 1737420293,
47
+
"narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=",
48
+
"owner": "nix-community",
49
+
"repo": "nix-github-actions",
50
+
"rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9",
51
+
"type": "github"
52
+
},
53
+
"original": {
54
+
"owner": "nix-community",
55
+
"repo": "nix-github-actions",
56
+
"type": "github"
57
+
}
58
+
},
59
+
"nix-unit": {
60
+
"inputs": {
61
+
"flake-parts": [
62
+
"flake-parts"
63
+
],
64
+
"nix-github-actions": "nix-github-actions",
65
+
"nixpkgs": [
66
+
"nixpkgs"
67
+
],
68
+
"treefmt-nix": "treefmt-nix"
69
+
},
70
+
"locked": {
71
+
"lastModified": 1762774186,
72
+
"narHash": "sha256-hRADkHjNt41+JUHw2EiSkMaL4owL83g5ZppjYUdF/Dc=",
73
+
"owner": "nix-community",
74
+
"repo": "nix-unit",
75
+
"rev": "1c9ab50554eed0b768f9e5b6f646d63c9673f0f7",
76
+
"type": "github"
77
+
},
78
+
"original": {
79
+
"owner": "nix-community",
80
+
"repo": "nix-unit",
81
+
"type": "github"
82
+
}
83
+
},
84
+
"nixpkgs": {
85
+
"locked": {
86
+
"lastModified": 1764587062,
87
+
"narHash": "sha256-hdFa0TAVQAQLDF31cEW3enWmBP+b592OvHs6WVe3D8k=",
88
+
"owner": "nixos",
89
+
"repo": "nixpkgs",
90
+
"rev": "c1cb7d097cb250f6e1904aacd5f2ba5ffd8a49ce",
91
+
"type": "github"
92
+
},
93
+
"original": {
94
+
"owner": "nixos",
95
+
"ref": "nixpkgs-unstable",
96
+
"repo": "nixpkgs",
97
+
"type": "github"
98
+
}
99
+
},
100
+
"root": {
101
+
"inputs": {
102
+
"flake-parts": "flake-parts",
103
+
"import-tree": "import-tree",
104
+
"nix-unit": "nix-unit",
105
+
"nixpkgs": "nixpkgs",
106
+
"nixpkgs-lib": [
107
+
"nixpkgs"
108
+
],
109
+
"systems": "systems",
110
+
"target": "target",
111
+
"treefmt-nix": "treefmt-nix_2"
112
+
}
113
+
},
114
+
"systems": {
115
+
"locked": {
116
+
"lastModified": 1681028828,
117
+
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
118
+
"owner": "nix-systems",
119
+
"repo": "default",
120
+
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
121
+
"type": "github"
122
+
},
123
+
"original": {
124
+
"owner": "nix-systems",
125
+
"repo": "default",
126
+
"type": "github"
127
+
}
128
+
},
129
+
"target": {
130
+
"locked": {
131
+
"path": "..",
132
+
"type": "path"
133
+
},
134
+
"original": {
135
+
"path": "..",
136
+
"type": "path"
137
+
},
138
+
"parent": []
139
+
},
140
+
"treefmt-nix": {
141
+
"inputs": {
142
+
"nixpkgs": [
143
+
"nix-unit",
144
+
"nixpkgs"
145
+
]
146
+
},
147
+
"locked": {
148
+
"lastModified": 1762410071,
149
+
"narHash": "sha256-aF5fvoZeoXNPxT0bejFUBXeUjXfHLSL7g+mjR/p5TEg=",
150
+
"owner": "numtide",
151
+
"repo": "treefmt-nix",
152
+
"rev": "97a30861b13c3731a84e09405414398fbf3e109f",
153
+
"type": "github"
154
+
},
155
+
"original": {
156
+
"owner": "numtide",
157
+
"repo": "treefmt-nix",
158
+
"type": "github"
159
+
}
160
+
},
161
+
"treefmt-nix_2": {
162
+
"inputs": {
163
+
"nixpkgs": [
164
+
"nixpkgs"
165
+
]
166
+
},
167
+
"locked": {
168
+
"lastModified": 1762938485,
169
+
"narHash": "sha256-AlEObg0syDl+Spi4LsZIBrjw+snSVU4T8MOeuZJUJjM=",
170
+
"owner": "numtide",
171
+
"repo": "treefmt-nix",
172
+
"rev": "5b4ee75aeefd1e2d5a1cc43cf6ba65eba75e83e4",
173
+
"type": "github"
174
+
},
175
+
"original": {
176
+
"owner": "numtide",
177
+
"repo": "treefmt-nix",
178
+
"type": "github"
179
+
}
180
+
}
181
+
},
182
+
"root": "root",
183
+
"version": 7
184
+
}
+28
checkmate/flake.nix
+28
checkmate/flake.nix
···
1
+
{
2
+
3
+
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules);
4
+
5
+
inputs = {
6
+
target.url = "path:..";
7
+
flake-parts = {
8
+
inputs.nixpkgs-lib.follows = "nixpkgs-lib";
9
+
url = "github:hercules-ci/flake-parts";
10
+
};
11
+
import-tree.url = "github:vic/import-tree";
12
+
nix-unit = {
13
+
inputs = {
14
+
flake-parts.follows = "flake-parts";
15
+
nixpkgs.follows = "nixpkgs";
16
+
};
17
+
url = "github:nix-community/nix-unit";
18
+
};
19
+
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
20
+
nixpkgs-lib.follows = "nixpkgs";
21
+
systems.url = "github:nix-systems/default";
22
+
treefmt-nix = {
23
+
inputs.nixpkgs.follows = "nixpkgs";
24
+
url = "github:numtide/treefmt-nix";
25
+
};
26
+
};
27
+
28
+
}
+25
checkmate/modules/checkmate.nix
+25
checkmate/modules/checkmate.nix
···
1
+
{ inputs, lib, ... }:
2
+
{
3
+
imports = [
4
+
inputs.nix-unit.modules.flake.default
5
+
inputs.treefmt-nix.flakeModule
6
+
];
7
+
systems = import inputs.systems;
8
+
9
+
perSystem =
10
+
{ self', ... }:
11
+
{
12
+
packages.fmt = self'.formatter;
13
+
treefmt.projectRoot = inputs.target;
14
+
nix-unit = {
15
+
allowNetwork = true;
16
+
inputs = inputs;
17
+
};
18
+
treefmt.programs = {
19
+
nixfmt.enable = true;
20
+
};
21
+
treefmt.settings.global.excludes = [
22
+
"LICENSE"
23
+
];
24
+
};
25
+
}
+61
-512
checkmate/modules/tests.nix
+61
-512
checkmate/modules/tests.nix
···
1
-
{ inputs, ... }:
2
-
{
3
-
perSystem =
4
-
{ lib, ... }:
5
-
let
6
-
transpose = import ../../nix { inherit lib; };
7
-
8
-
mkFlake =
9
-
mod:
10
-
inputs.flake-parts.lib.mkFlake
11
-
{
12
-
inputs.self = [ ];
13
-
}
14
-
{
15
-
systems = [ ];
16
-
imports = [
17
-
../../nix/flakeModule.nix
18
-
inputs.flake-parts.flakeModules.modules
19
-
mod
20
-
(fooMod "aspectOne")
21
-
(fooMod "aspectTwo")
22
-
(fooMod "aspectThree")
23
-
];
24
-
};
25
-
26
-
fooMod = aspect: {
1
+
{ inputs, lib, ... }:
2
+
let
3
+
targetNix = "${inputs.target}/nix";
4
+
targetLib = "${inputs.target}/nix/lib.nix";
5
+
targetMod = "${inputs.target}/nix/flakeModule.nix";
6
+
7
+
transpose = import targetNix { inherit lib; };
8
+
9
+
mkFlake =
10
+
mod:
11
+
inputs.flake-parts.lib.mkFlake
12
+
{
13
+
inputs.self = [ ];
14
+
}
15
+
{
16
+
systems = [ ];
27
17
imports = [
28
-
{ flake.modules.classOne.${aspect}.imports = [ fooOpt ]; }
29
-
{ flake.modules.classTwo.${aspect}.imports = [ fooOpt ]; }
30
-
{ flake.modules.classThree.${aspect}.imports = [ fooOpt ]; }
18
+
targetMod
19
+
inputs.flake-parts.flakeModules.modules
20
+
mod
21
+
(fooMod "aspectOne")
22
+
(fooMod "aspectTwo")
23
+
(fooMod "aspectThree")
31
24
];
32
25
};
33
26
34
-
fooOpt = {
35
-
options.foo = lib.mkOption {
36
-
type = lib.types.str;
37
-
default = "<unset>";
38
-
};
39
-
options.bar = lib.mkOption {
40
-
type = lib.types.listOf lib.types.str;
41
-
default = [ ];
42
-
};
43
-
options.baz = lib.mkOption {
44
-
type = lib.types.lazyAttrsOf lib.types.str;
45
-
default = { };
46
-
};
47
-
};
48
-
49
-
evalMod =
50
-
class: mod:
51
-
(lib.evalModules {
52
-
inherit class;
53
-
modules = [ mod ];
54
-
}).config;
55
-
in
56
-
{
57
-
nix-unit.tests = {
58
-
transpose."test swaps parent and child attrNames" = {
59
-
expr = transpose { a.b.c = 1; };
60
-
expected = {
61
-
b.a.c = 1;
62
-
};
63
-
};
64
-
65
-
transpose."test common childs become one parent" = {
66
-
expr = transpose {
67
-
a.b = 1;
68
-
c.b = 2;
69
-
};
70
-
expected.b = {
71
-
a = 1;
72
-
c = 2;
73
-
};
74
-
};
75
-
76
-
new-scope."test usage without flakes" =
77
-
let
78
-
flake-aspects-lib = import ../../nix/lib.nix lib;
79
-
# first eval is like evaling the flake.
80
-
first = lib.evalModules {
81
-
modules = [
82
-
(flake-aspects-lib.new-scope "hello")
83
-
{
84
-
hello.aspects =
85
-
{ aspects, ... }:
86
-
{
87
-
a.b.c = [ "world" ];
88
-
a.includes = [ aspects.x ];
89
-
x.b =
90
-
{ lib, ... }:
91
-
{
92
-
c = lib.splitString " " "mundo cruel";
93
-
};
94
-
};
95
-
}
96
-
];
97
-
};
98
-
# second eval is like evaling its nixosConfiguration
99
-
second = lib.evalModules {
100
-
modules = [
101
-
{ options.c = lib.mkOption { type = lib.types.listOf lib.types.str; }; }
102
-
first.config.hello.modules.b.a
103
-
];
104
-
};
105
-
expr = lib.sort (a: b: a < b) second.config.c;
106
-
expected = [
107
-
"cruel"
108
-
"mundo"
109
-
"world"
110
-
];
111
-
in
112
-
{
113
-
inherit expr expected;
114
-
};
115
-
116
-
aspects."test provides default" =
117
-
let
118
-
flake =
119
-
inputs.flake-parts.lib.mkFlake
120
-
{
121
-
inputs.self = [ ];
122
-
moduleLocation = builtins.toString ./.;
123
-
}
124
-
{
125
-
systems = [ ];
126
-
imports = [
127
-
../../nix/flakeModule.nix
128
-
inputs.flake-parts.flakeModules.modules
129
-
];
130
-
};
131
-
expr = flake.modules;
132
-
expected = { };
133
-
in
134
-
{
135
-
inherit expr expected;
136
-
};
137
-
138
-
aspects."test transposes to flake.modules" =
139
-
let
140
-
flake = mkFlake {
141
-
flake.aspects.aspectOne = {
142
-
classOne.foo = "niri";
143
-
classTwo.foo = "paper.spoon";
144
-
};
145
-
};
146
-
expr = {
147
-
classOne = (evalMod "classOne" flake.modules.classOne.aspectOne).foo;
148
-
classTwo = (evalMod "classTwo" flake.modules.classTwo.aspectOne).foo;
149
-
};
150
-
expected = {
151
-
classOne = "niri";
152
-
classTwo = "paper.spoon";
153
-
};
154
-
in
155
-
{
156
-
inherit expr expected;
157
-
};
158
-
159
-
aspects."test dependencies on aspects" =
160
-
let
161
-
flake = mkFlake {
162
-
flake.aspects =
163
-
{ aspects, ... }:
164
-
{
165
-
aspectOne = {
166
-
description = "os config";
167
-
includes = with aspects; [ aspectTwo ];
168
-
classOne.bar = [ "os" ];
169
-
};
170
-
171
-
aspectTwo = {
172
-
description = "user config at os level";
173
-
classOne.bar = [ "user" ];
174
-
};
175
-
};
176
-
};
177
-
expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
178
-
expected = [
179
-
"os"
180
-
"user"
181
-
];
182
-
in
183
-
{
184
-
inherit expr expected;
185
-
};
186
-
187
-
aspects."test resolve aspect-chain" =
188
-
let
189
-
flake = mkFlake {
190
-
flake.aspects =
191
-
{ aspects, ... }:
192
-
{
193
-
aspectOne = {
194
-
name = "one";
195
-
includes = [ aspects.aspectOne.provides.dos ];
196
-
classOne.bar = [ "zzz" ];
197
-
provides.dos =
198
-
{ aspect-chain, ... }:
199
-
{
200
-
name = "dos";
201
-
includes = [ aspects.aspectOne.provides.tres ];
202
-
classOne.bar = map (x: x.name) aspect-chain;
203
-
};
204
-
205
-
provides.tres =
206
-
{ aspect-chain, ... }:
207
-
{
208
-
name = "tres";
209
-
classOne.bar = [ (lib.last aspect-chain).name ];
210
-
};
211
-
};
212
-
};
213
-
};
214
-
mod = {
215
-
imports = [
216
-
fooOpt
217
-
(flake.aspects.aspectOne.resolve { class = "classOne"; })
218
-
];
219
-
};
220
-
expr = lib.sort (a: b: a < b) (evalMod "classOne" mod).bar;
221
-
expected = [
222
-
"dos"
223
-
"one"
224
-
"zzz"
225
-
];
226
-
in
227
-
{
228
-
inherit expr expected;
229
-
};
230
-
231
-
aspects."test modules resolved" =
232
-
let
233
-
flake = mkFlake {
234
-
flake.aspects =
235
-
{ aspects, ... }:
236
-
{
237
-
aspectOne = {
238
-
name = "one";
239
-
includes = [ aspects.aspectOne.provides.dos ];
240
-
classOne.bar = [ "zzz" ];
241
-
provides.dos =
242
-
{ aspect-chain, ... }:
243
-
{
244
-
name = "dos";
245
-
includes = [ aspects.aspectOne.provides.tres ];
246
-
classOne.bar = map (x: x.name) aspect-chain;
247
-
};
248
-
249
-
provides.tres =
250
-
{ aspect-chain, ... }:
251
-
{
252
-
name = "tres";
253
-
classOne.bar = [ (lib.last aspect-chain).name ];
254
-
};
255
-
};
256
-
};
257
-
};
258
-
mod = {
259
-
imports = [
260
-
fooOpt
261
-
(flake.aspects.aspectOne.modules.classOne)
262
-
];
263
-
};
264
-
expr = lib.sort (a: b: a < b) (evalMod "classOne" mod).bar;
265
-
expected = [
266
-
"dos"
267
-
"one"
268
-
"zzz"
269
-
];
270
-
in
271
-
{
272
-
inherit expr expected;
273
-
};
274
-
275
-
aspects."test provides" =
276
-
let
277
-
flake = mkFlake {
278
-
flake.aspects =
279
-
{ aspects, ... }:
280
-
{
281
-
aspectOne.includes = with aspects.aspectTwo.provides; [
282
-
foo
283
-
bar
284
-
];
285
-
aspectOne.classOne = { }; # must be present for mixing dependencies.
286
-
aspectTwo = {
287
-
classOne.bar = [ "class one not included" ];
288
-
classTwo.bar = [ "class two not included" ];
289
-
provides.foo =
290
-
{ class, aspect-chain }:
291
-
{
292
-
name = "aspectTwo.foo";
293
-
description = "aspectTwo foo provided";
294
-
includes = [
295
-
aspects.aspectThree.provides.moo
296
-
aspects.aspectTwo.provides.baz
297
-
];
298
-
classOne.bar = [ "two:${class}:${lib.concatStringsSep "/" (lib.map (x: x.name) aspect-chain)}" ];
299
-
classTwo.bar = [ "foo class two not included" ];
300
-
};
301
-
# a provider can be immediately an aspect object.
302
-
provides.bar = {
303
-
# classOne is missing on bar
304
-
classTwo.bar = [ "bar class two not included" ];
305
-
};
306
-
# _ is an shortcut alias of provides.
307
-
_.baz = {
308
-
# classOne is missing on bar
309
-
classTwo.bar = [ "baz" ];
310
-
};
311
-
};
312
-
aspectThree.provides.moo =
313
-
{ aspect-chain, class }:
314
-
{
315
-
classOne.bar = [ "three:${class}:${lib.concatStringsSep "/" (lib.map (x: x.name) aspect-chain)}" ];
316
-
};
317
-
};
318
-
};
319
-
expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
320
-
expected = [
321
-
"three:classOne:aspectOne/aspectTwo.foo"
322
-
"two:classOne:aspectOne"
323
-
];
324
-
in
325
-
{
326
-
inherit expr expected;
327
-
};
328
-
329
-
aspects."test provides using fixpoints" =
330
-
let
331
-
flake = mkFlake {
332
-
flake.aspects =
333
-
{ aspects, ... }:
334
-
{
335
-
aspectOne = {
336
-
classOne.bar = [ "1" ];
337
-
includes = [
338
-
aspects.aspectTwo
339
-
];
340
-
};
341
-
342
-
aspectTwo = {
343
-
classOne.bar = [ "2" ];
344
-
includes = [ aspects.aspectTwo.provides.three-and-four-and-five ];
345
-
provides =
346
-
{ provides, ... }:
347
-
{
348
-
three-and-four-and-five = {
349
-
classOne.bar = [ "3" ];
350
-
includes = [
351
-
provides.four
352
-
aspects.five
353
-
];
354
-
};
355
-
four = {
356
-
classOne.bar = [ "4" ];
357
-
};
358
-
};
359
-
};
360
-
361
-
five.classOne.bar = [ "5" ];
362
-
};
363
-
};
364
-
365
-
expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
366
-
expected = [
367
-
"1"
368
-
"2"
369
-
"3"
370
-
"4"
371
-
"5"
372
-
];
373
-
in
374
-
{
375
-
inherit expr expected;
376
-
};
377
-
378
-
aspects."test provides parametrized modules" =
379
-
let
380
-
flake = mkFlake {
381
-
flake.aspects =
382
-
{ aspects, ... }:
383
-
{
384
-
aspectOne.includes = [ (aspects.aspectTwo.provides.hello "mundo") ];
385
-
aspectOne.classOne.bar = [ "1" ];
386
-
387
-
aspectTwo.provides.hello = world: {
388
-
classOne.bar = [ world ];
389
-
};
390
-
};
391
-
};
392
-
393
-
expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
394
-
expected = [
395
-
"1"
396
-
"mundo"
397
-
];
398
-
in
399
-
{
400
-
inherit expr expected;
401
-
};
402
-
403
-
aspects."test override default provider" =
404
-
let
405
-
flake = mkFlake {
406
-
flake.aspects =
407
-
{ aspects, ... }:
408
-
{
409
-
aspectOne =
410
-
{ aspect, ... }:
411
-
{
412
-
includes = [ (aspects.aspectTwo { message = "hello ${aspect.name}"; }) ];
413
-
classOne = { }; # required for propagation
414
-
};
415
-
416
-
aspectTwo.__functor =
417
-
_:
418
-
{ message }: # args must be always named
419
-
{ class, aspect-chain }:
420
-
{ aspect, ... }:
421
-
{
422
-
classOne.bar = [
423
-
"foo"
424
-
aspect.name
425
-
message
426
-
class
427
-
]
428
-
++ (lib.map (x: x.name) aspect-chain);
429
-
};
430
-
aspectTwo.classOne.bar = [ "itself not included" ];
431
-
};
432
-
};
433
-
434
-
expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
435
-
expected = [
436
-
"foo"
437
-
"<function body>"
438
-
"hello aspectOne"
439
-
"classOne"
440
-
"aspectOne"
441
-
];
442
-
in
443
-
{
444
-
inherit expr expected;
445
-
};
446
-
447
-
aspects."test override default provider includes" =
448
-
let
449
-
flake = mkFlake {
450
-
flake.aspects =
451
-
{ aspects, ... }:
452
-
{
453
-
aspectOne = {
454
-
classOne.bar = [ "should-not-be-present" ];
455
-
includes = [ aspects.aspectTwo ];
456
-
__functor = aspect: {
457
-
includes = [
458
-
{ classOne.bar = [ "from-functor" ]; }
459
-
]
460
-
++ map (f: f { message = "hello"; }) aspect.includes;
461
-
};
462
-
};
463
-
aspectTwo.__functor =
464
-
_aspect:
465
-
{ message }:
466
-
{
467
-
classOne.bar = [ message ];
468
-
};
469
-
};
470
-
};
471
-
472
-
expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
473
-
expected = [
474
-
"hello"
475
-
"from-functor"
476
-
];
477
-
in
478
-
{
479
-
inherit expr expected;
480
-
};
481
-
482
-
aspects."test define top-level context-aware aspect" =
483
-
let
484
-
flake = mkFlake {
485
-
flake.aspects =
486
-
{ aspects, ... }:
487
-
{
488
-
aspectOne = {
489
-
classOne.bar = [ "should-not-be-present" ];
490
-
includes = [ aspects.aspectTwo ];
491
-
__functor = aspect: {
492
-
includes = [
493
-
{ classOne.bar = [ "from-functor" ]; }
494
-
]
495
-
++ map (f: f { message = "hello"; }) aspect.includes;
496
-
};
497
-
};
498
-
aspectTwo =
499
-
{ message }:
500
-
{
501
-
classOne.bar = [ message ];
502
-
};
503
-
};
504
-
};
505
-
506
-
expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
507
-
expected = [
508
-
"hello"
509
-
"from-functor"
510
-
];
511
-
in
512
-
{
513
-
inherit expr expected;
514
-
};
515
-
};
516
-
27
+
fooMod = aspect: {
28
+
imports = [
29
+
{ flake.modules.classOne.${aspect}.imports = [ fooOpt ]; }
30
+
{ flake.modules.classTwo.${aspect}.imports = [ fooOpt ]; }
31
+
{ flake.modules.classThree.${aspect}.imports = [ fooOpt ]; }
32
+
];
33
+
};
34
+
35
+
fooOpt = {
36
+
options.foo = lib.mkOption {
37
+
type = lib.types.str;
38
+
default = "<unset>";
39
+
};
40
+
options.bar = lib.mkOption {
41
+
type = lib.types.listOf lib.types.str;
42
+
default = [ ];
517
43
};
44
+
options.baz = lib.mkOption {
45
+
type = lib.types.lazyAttrsOf lib.types.str;
46
+
default = { };
47
+
};
48
+
};
49
+
50
+
evalMod =
51
+
class: mod:
52
+
(lib.evalModules {
53
+
inherit class;
54
+
modules = [ mod ];
55
+
}).config;
56
+
in
57
+
{
58
+
_module.args = {
59
+
inherit
60
+
transpose
61
+
targetLib
62
+
targetMod
63
+
targetNix
64
+
;
65
+
inherit mkFlake evalMod fooOpt;
66
+
};
518
67
}
+53
checkmate/modules/tests/aspect_chain.nix
+53
checkmate/modules/tests/aspect_chain.nix
···
1
+
{
2
+
lib,
3
+
mkFlake,
4
+
evalMod,
5
+
fooOpt,
6
+
...
7
+
}:
8
+
{
9
+
10
+
flake.tests."test resolve aspect-chain" =
11
+
let
12
+
flake = mkFlake {
13
+
flake.aspects =
14
+
{ aspects, ... }:
15
+
{
16
+
aspectOne = {
17
+
name = "one";
18
+
includes = [ aspects.aspectOne.provides.dos ];
19
+
classOne.bar = [ "zzz" ];
20
+
provides.dos =
21
+
{ aspect-chain, ... }:
22
+
{
23
+
name = "dos";
24
+
includes = [ aspects.aspectOne.provides.tres ];
25
+
classOne.bar = map (x: x.name) aspect-chain;
26
+
};
27
+
28
+
provides.tres =
29
+
{ aspect-chain, ... }:
30
+
{
31
+
name = "tres";
32
+
classOne.bar = [ (lib.last aspect-chain).name ];
33
+
};
34
+
};
35
+
};
36
+
};
37
+
mod = {
38
+
imports = [
39
+
fooOpt
40
+
(flake.aspects.aspectOne.resolve { class = "classOne"; })
41
+
];
42
+
};
43
+
expr = lib.sort (a: b: a < b) (evalMod "classOne" mod).bar;
44
+
expected = [
45
+
"dos"
46
+
"one"
47
+
"zzz"
48
+
];
49
+
in
50
+
{
51
+
inherit expr expected;
52
+
};
53
+
}
+53
checkmate/modules/tests/aspect_default_provider_functor.nix
+53
checkmate/modules/tests/aspect_default_provider_functor.nix
···
1
+
{
2
+
mkFlake,
3
+
evalMod,
4
+
lib,
5
+
...
6
+
}:
7
+
{
8
+
9
+
flake.tests."test override default provider" =
10
+
let
11
+
flake = mkFlake {
12
+
flake.aspects =
13
+
{ aspects, ... }:
14
+
{
15
+
aspectOne =
16
+
{ aspect, ... }:
17
+
{
18
+
includes = [ (aspects.aspectTwo { message = "hello ${aspect.name}"; }) ];
19
+
classOne = { }; # required for propagation
20
+
};
21
+
22
+
aspectTwo.__functor =
23
+
_:
24
+
{ message }: # args must be always named
25
+
{ class, aspect-chain }:
26
+
{ aspect, ... }:
27
+
{
28
+
classOne.bar = [
29
+
"foo"
30
+
aspect.name
31
+
message
32
+
class
33
+
]
34
+
++ (lib.map (x: x.name) aspect-chain);
35
+
};
36
+
aspectTwo.classOne.bar = [ "itself not included" ];
37
+
};
38
+
};
39
+
40
+
expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
41
+
expected = [
42
+
"foo"
43
+
"<function body>"
44
+
"hello aspectOne"
45
+
"classOne"
46
+
"aspectOne"
47
+
];
48
+
in
49
+
{
50
+
inherit expr expected;
51
+
};
52
+
53
+
}
+43
checkmate/modules/tests/aspect_default_provider_override.nix
+43
checkmate/modules/tests/aspect_default_provider_override.nix
···
1
+
{
2
+
mkFlake,
3
+
evalMod,
4
+
lib,
5
+
...
6
+
}:
7
+
{
8
+
9
+
flake.tests."test override default provider includes" =
10
+
let
11
+
flake = mkFlake {
12
+
flake.aspects =
13
+
{ aspects, ... }:
14
+
{
15
+
aspectOne = {
16
+
classOne.bar = [ "should-not-be-present" ];
17
+
includes = [ aspects.aspectTwo ];
18
+
__functor = aspect: {
19
+
includes = [
20
+
{ classOne.bar = [ "from-functor" ]; }
21
+
]
22
+
++ map (f: f { message = "hello"; }) aspect.includes;
23
+
};
24
+
};
25
+
aspectTwo.__functor =
26
+
_aspect:
27
+
{ message }:
28
+
{
29
+
classOne.bar = [ message ];
30
+
};
31
+
};
32
+
};
33
+
34
+
expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
35
+
expected = [
36
+
"hello"
37
+
"from-functor"
38
+
];
39
+
in
40
+
{
41
+
inherit expr expected;
42
+
};
43
+
}
+37
checkmate/modules/tests/aspect_dependencies.nix
+37
checkmate/modules/tests/aspect_dependencies.nix
···
1
+
{
2
+
mkFlake,
3
+
evalMod,
4
+
lib,
5
+
...
6
+
}:
7
+
{
8
+
9
+
flake.tests."test dependencies on aspects" =
10
+
let
11
+
flake = mkFlake {
12
+
flake.aspects =
13
+
{ aspects, ... }:
14
+
{
15
+
aspectOne = {
16
+
description = "os config";
17
+
includes = with aspects; [ aspectTwo ];
18
+
classOne.bar = [ "os" ];
19
+
};
20
+
21
+
aspectTwo = {
22
+
description = "user config at os level";
23
+
classOne.bar = [ "user" ];
24
+
};
25
+
};
26
+
};
27
+
expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
28
+
expected = [
29
+
"os"
30
+
"user"
31
+
];
32
+
in
33
+
{
34
+
inherit expr expected;
35
+
};
36
+
37
+
}
+59
checkmate/modules/tests/aspect_fixpoint.nix
+59
checkmate/modules/tests/aspect_fixpoint.nix
···
1
+
{
2
+
lib,
3
+
mkFlake,
4
+
evalMod,
5
+
fooOpt,
6
+
...
7
+
}:
8
+
{
9
+
10
+
flake.tests."test provides using fixpoints" =
11
+
let
12
+
flake = mkFlake {
13
+
flake.aspects =
14
+
{ aspects, ... }@top:
15
+
{
16
+
aspectOne = {
17
+
classOne.bar = [ "1" ];
18
+
includes = [
19
+
aspects.aspectTwo
20
+
];
21
+
};
22
+
23
+
aspectTwo = {
24
+
classOne.bar = [ "2" ];
25
+
includes = [ aspects.aspectTwo.provides.three-and-four-and-five ];
26
+
provides =
27
+
{ aspects, ... }:
28
+
{
29
+
three-and-four-and-five = {
30
+
classOne.bar = [ "3" ];
31
+
includes = [
32
+
aspects.four
33
+
top.aspects.five
34
+
];
35
+
};
36
+
four = {
37
+
classOne.bar = [ "4" ];
38
+
};
39
+
};
40
+
};
41
+
42
+
five.classOne.bar = [ "5" ];
43
+
};
44
+
};
45
+
46
+
expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
47
+
expected = [
48
+
"1"
49
+
"2"
50
+
"3"
51
+
"4"
52
+
"5"
53
+
];
54
+
in
55
+
{
56
+
inherit expr expected;
57
+
};
58
+
59
+
}
+54
checkmate/modules/tests/aspect_modules_resolved.nix
+54
checkmate/modules/tests/aspect_modules_resolved.nix
···
1
+
{
2
+
lib,
3
+
mkFlake,
4
+
evalMod,
5
+
fooOpt,
6
+
...
7
+
}:
8
+
{
9
+
10
+
flake.tests."test modules resolved" =
11
+
let
12
+
flake = mkFlake {
13
+
flake.aspects =
14
+
{ aspects, ... }:
15
+
{
16
+
aspectOne = {
17
+
name = "one";
18
+
includes = [ aspects.aspectOne.provides.dos ];
19
+
classOne.bar = [ "zzz" ];
20
+
provides.dos =
21
+
{ aspect-chain, ... }:
22
+
{
23
+
name = "dos";
24
+
includes = [ aspects.aspectOne.provides.tres ];
25
+
classOne.bar = map (x: x.name) aspect-chain;
26
+
};
27
+
28
+
provides.tres =
29
+
{ aspect-chain, ... }:
30
+
{
31
+
name = "tres";
32
+
classOne.bar = [ (lib.last aspect-chain).name ];
33
+
};
34
+
};
35
+
};
36
+
};
37
+
mod = {
38
+
imports = [
39
+
fooOpt
40
+
(flake.aspects.aspectOne.modules.classOne)
41
+
];
42
+
};
43
+
expr = lib.sort (a: b: a < b) (evalMod "classOne" mod).bar;
44
+
expected = [
45
+
"dos"
46
+
"one"
47
+
"zzz"
48
+
];
49
+
in
50
+
{
51
+
inherit expr expected;
52
+
};
53
+
54
+
}
+34
checkmate/modules/tests/aspect_parametric.nix
+34
checkmate/modules/tests/aspect_parametric.nix
···
1
+
{
2
+
mkFlake,
3
+
evalMod,
4
+
lib,
5
+
...
6
+
}:
7
+
{
8
+
9
+
flake.tests."test provides parametrized modules" =
10
+
let
11
+
flake = mkFlake {
12
+
flake.aspects =
13
+
{ aspects, ... }:
14
+
{
15
+
aspectOne.includes = [ (aspects.aspectTwo.provides.hello "mundo") ];
16
+
aspectOne.classOne.bar = [ "1" ];
17
+
18
+
aspectTwo.provides.hello = world: {
19
+
classOne.bar = [ world ];
20
+
};
21
+
};
22
+
};
23
+
24
+
expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
25
+
expected = [
26
+
"1"
27
+
"mundo"
28
+
];
29
+
in
30
+
{
31
+
inherit expr expected;
32
+
};
33
+
34
+
}
+64
checkmate/modules/tests/aspect_provides.nix
+64
checkmate/modules/tests/aspect_provides.nix
···
1
+
{
2
+
lib,
3
+
mkFlake,
4
+
evalMod,
5
+
fooOpt,
6
+
...
7
+
}:
8
+
{
9
+
10
+
flake.tests."test provides" =
11
+
let
12
+
flake = mkFlake {
13
+
flake.aspects =
14
+
{ aspects, ... }:
15
+
{
16
+
aspectOne.includes = with aspects.aspectTwo.provides; [
17
+
foo
18
+
bar
19
+
];
20
+
aspectOne.classOne = { }; # must be present for mixing dependencies.
21
+
aspectTwo = {
22
+
classOne.bar = [ "class one not included" ];
23
+
classTwo.bar = [ "class two not included" ];
24
+
provides.foo =
25
+
{ class, aspect-chain }:
26
+
{
27
+
name = "aspectTwo.foo";
28
+
description = "aspectTwo foo provided";
29
+
includes = [
30
+
aspects.aspectThree.provides.moo
31
+
aspects.aspectTwo.provides.baz
32
+
];
33
+
classOne.bar = [ "two:${class}:${lib.concatStringsSep "/" (lib.map (x: x.name) aspect-chain)}" ];
34
+
classTwo.bar = [ "foo class two not included" ];
35
+
};
36
+
# a provider can be immediately an aspect object.
37
+
provides.bar = {
38
+
# classOne is missing on bar
39
+
classTwo.bar = [ "bar class two not included" ];
40
+
};
41
+
# _ is an shortcut alias of provides.
42
+
_.baz = {
43
+
# classOne is missing on bar
44
+
classTwo.bar = [ "baz" ];
45
+
};
46
+
};
47
+
aspectThree.provides.moo =
48
+
{ aspect-chain, class }:
49
+
{
50
+
classOne.bar = [ "three:${class}:${lib.concatStringsSep "/" (lib.map (x: x.name) aspect-chain)}" ];
51
+
};
52
+
};
53
+
};
54
+
expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
55
+
expected = [
56
+
"three:classOne:aspectOne/aspectTwo.foo"
57
+
"two:classOne:aspectOne"
58
+
];
59
+
in
60
+
{
61
+
inherit expr expected;
62
+
};
63
+
64
+
}
+42
checkmate/modules/tests/aspect_toplevel_parametric.nix
+42
checkmate/modules/tests/aspect_toplevel_parametric.nix
···
1
+
{
2
+
mkFlake,
3
+
evalMod,
4
+
lib,
5
+
...
6
+
}:
7
+
{
8
+
9
+
flake.tests."test define top-level context-aware aspect" =
10
+
let
11
+
flake = mkFlake {
12
+
flake.aspects =
13
+
{ aspects, ... }:
14
+
{
15
+
aspectOne = {
16
+
classOne.bar = [ "should-not-be-present" ];
17
+
includes = [ aspects.aspectTwo ];
18
+
__functor = aspect: {
19
+
includes = [
20
+
{ classOne.bar = [ "from-functor" ]; }
21
+
]
22
+
++ map (f: f { message = "hello"; }) aspect.includes;
23
+
};
24
+
};
25
+
aspectTwo =
26
+
{ message }:
27
+
{
28
+
classOne.bar = [ message ];
29
+
};
30
+
};
31
+
};
32
+
33
+
expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar;
34
+
expected = [
35
+
"hello"
36
+
"from-functor"
37
+
];
38
+
in
39
+
{
40
+
inherit expr expected;
41
+
};
42
+
}
+30
checkmate/modules/tests/default_empty.nix
+30
checkmate/modules/tests/default_empty.nix
···
1
+
{
2
+
lib,
3
+
inputs,
4
+
targetMod,
5
+
...
6
+
}:
7
+
{
8
+
9
+
flake.tests."test provides default" =
10
+
let
11
+
flake =
12
+
inputs.flake-parts.lib.mkFlake
13
+
{
14
+
inputs.self = [ ];
15
+
moduleLocation = builtins.toString ./.;
16
+
}
17
+
{
18
+
systems = [ ];
19
+
imports = [
20
+
targetMod
21
+
inputs.flake-parts.flakeModules.modules
22
+
];
23
+
};
24
+
expr = flake.modules;
25
+
expected = { };
26
+
in
27
+
{
28
+
inherit expr expected;
29
+
};
30
+
}
+29
checkmate/modules/tests/tranpose_flake_modules.nix
+29
checkmate/modules/tests/tranpose_flake_modules.nix
···
1
+
{
2
+
mkFlake,
3
+
lib,
4
+
evalMod,
5
+
...
6
+
}:
7
+
{
8
+
9
+
flake.tests."test transposes to flake.modules" =
10
+
let
11
+
flake = mkFlake {
12
+
flake.aspects.aspectOne = {
13
+
classOne.foo = "niri";
14
+
classTwo.foo = "paper.spoon";
15
+
};
16
+
};
17
+
expr = {
18
+
classOne = (evalMod "classOne" flake.modules.classOne.aspectOne).foo;
19
+
classTwo = (evalMod "classTwo" flake.modules.classTwo.aspectOne).foo;
20
+
};
21
+
expected = {
22
+
classOne = "niri";
23
+
classTwo = "paper.spoon";
24
+
};
25
+
in
26
+
{
27
+
inherit expr expected;
28
+
};
29
+
}
+15
checkmate/modules/tests/transpose_common.nix
+15
checkmate/modules/tests/transpose_common.nix
+10
checkmate/modules/tests/transpose_swap.nix
+10
checkmate/modules/tests/transpose_swap.nix
+44
checkmate/modules/tests/without_flakes.nix
+44
checkmate/modules/tests/without_flakes.nix
···
1
+
{ lib, targetLib, ... }:
2
+
{
3
+
4
+
flake.tests."test usage without flakes" =
5
+
let
6
+
flake-aspects-lib = import targetLib lib;
7
+
# first eval is like evaling the flake.
8
+
first = lib.evalModules {
9
+
modules = [
10
+
(flake-aspects-lib.new-scope "hello")
11
+
{
12
+
hello.aspects =
13
+
{ aspects, ... }:
14
+
{
15
+
a.b.c = [ "world" ];
16
+
a.includes = [ aspects.x ];
17
+
x.b =
18
+
{ lib, ... }:
19
+
{
20
+
c = lib.splitString " " "mundo cruel";
21
+
};
22
+
};
23
+
}
24
+
];
25
+
};
26
+
# second eval is like evaling its nixosConfiguration
27
+
second = lib.evalModules {
28
+
modules = [
29
+
{ options.c = lib.mkOption { type = lib.types.listOf lib.types.str; }; }
30
+
first.config.hello.modules.b.a
31
+
];
32
+
};
33
+
expr = lib.sort (a: b: a < b) second.config.c;
34
+
expected = [
35
+
"cruel"
36
+
"mundo"
37
+
"world"
38
+
];
39
+
in
40
+
{
41
+
inherit expr expected;
42
+
};
43
+
44
+
}