Skip to content

Commit 8ab084b

Browse files
mightyiamA-jay98
andcommitted
lib.evalModules: add graph attribute
Co-authored-by: Ali Jamadi <[email protected]>
1 parent bc94bc3 commit 8ab084b

File tree

7 files changed

+148
-5
lines changed

7 files changed

+148
-5
lines changed

doc/module-system/module-system.chapter.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ A nominal type marker, always `"configuration"`.
116116

117117
The [`class` argument](#module-system-lib-evalModules-param-class).
118118

119+
#### `graph` {#module-system-lib-evalModules-return-value-graph}
120+
121+
Represents all the modules that took part in the evaluation.
122+
It is a list of `ModuleGraph` where `ModuleGraph` is defined as an attribute set with the following attributes:
123+
124+
- `key`: `string` for the purpose of module deduplication and `disabledModules`
125+
- `file`: `string` for the purpose of error messages and warnings
126+
- `imports`: `[ ModuleGraph ]`
127+
- `disabled`: `bool`
128+
119129
## Module arguments {#module-system-module-arguments}
120130

121131
Module arguments are the attribute values passed to modules when they are evaluated.

doc/redirects.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@
409409
"module-system-lib-evalModules-return-value-_configurationClass": [
410410
"index.html#module-system-lib-evalModules-return-value-_configurationClass"
411411
],
412+
"module-system-lib-evalModules-return-value-graph": [
413+
"index.html#module-system-lib-evalModules-return-value-graph"
414+
],
412415
"part-stdenv": [
413416
"index.html#part-stdenv"
414417
],

lib/modules.nix

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ let
263263
// specialArgs
264264
);
265265
in
266-
mergeModules prefix (reverseList collected);
266+
mergeModules prefix (reverseList collected.modules);
267267

268268
options = merged.matchedOptions;
269269

@@ -359,12 +359,30 @@ let
359359
options = checked options;
360360
config = checked (removeAttrs config [ "_module" ]);
361361
_module = checked (config._module);
362+
graph =
363+
let
364+
collected =
365+
collectModules class (specialArgs.modulesPath or "") (regularModules ++ [ internalModule ])
366+
(
367+
{
368+
inherit
369+
lib
370+
options
371+
config
372+
specialArgs
373+
;
374+
_class = class;
375+
}
376+
// specialArgs
377+
);
378+
in
379+
collected.graph;
362380
inherit extendModules type class;
363381
};
364382
in
365383
result;
366384

367-
# collectModules :: (class: String) -> (modulesPath: String) -> (modules: [ Module ]) -> (args: Attrs) -> [ Module ]
385+
# collectModules :: (class: String) -> (modulesPath: String) -> (modules: [ Module ]) -> (args: Attrs) -> ModulesTree
368386
#
369387
# Collects all modules recursively through `import` statements, filtering out
370388
# all modules in disabledModules.
@@ -529,9 +547,25 @@ let
529547
operator = attrs: keyFilter attrs.modules;
530548
});
531549

550+
toGraph =
551+
modulesPath:
552+
{ disabled, modules }:
553+
let
554+
isDisabledModule = isDisabled modulesPath disabled;
555+
556+
toModuleGraph = structuredModule: {
557+
disabled = isDisabledModule structuredModule;
558+
inherit (structuredModule) key;
559+
file = structuredModule.module._file;
560+
imports = map toModuleGraph structuredModule.modules;
561+
};
562+
in
563+
map toModuleGraph (filter (x: x.key != "lib/modules.nix") modules);
532564
in
533-
modulesPath: initialModules: args:
534-
filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args);
565+
modulesPath: initialModules: args: {
566+
modules = filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args);
567+
graph = toGraph modulesPath (collectStructuredModules unknownModule "" initialModules args);
568+
};
535569

536570
/**
537571
Wrap a module with a default location for reporting errors.

lib/tests/modules.sh

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ cd "$DIR"/modules
2020
pass=0
2121
fail=0
2222

23+
local-nix-instantiate() {
24+
nix-instantiate --timeout 1 --eval-only --show-trace --read-write-mode --json "$@"
25+
}
26+
2327
# loc
2428
# prints the location of the call of to the function that calls it
2529
# loc n
@@ -55,7 +59,7 @@ evalConfig() {
5559
local attr=$1
5660
shift
5761
local script="import ./default.nix { modules = [ $* ];}"
58-
nix-instantiate --timeout 1 -E "$script" -A "$attr" --eval-only --show-trace --read-write-mode --json
62+
local-nix-instantiate -E "$script" -A "$attr"
5963
}
6064

6165
reportFailure() {
@@ -82,6 +86,20 @@ checkConfigOutput() {
8286
fi
8387
}
8488

89+
checkExpression() {
90+
local path=$1
91+
local output
92+
{
93+
output="$(local-nix-instantiate --strict "$path" 2>&1)" && ((++pass))
94+
} || {
95+
logStartFailure
96+
echo "$output"
97+
((++fail))
98+
logFailure
99+
logEndFailure
100+
}
101+
}
102+
85103
checkConfigError() {
86104
local errorContains=$1
87105
local err=""
@@ -305,6 +323,9 @@ checkConfigOutput '^12$' config.value ./declare-coerced-value-unsound.nix
305323
checkConfigError 'A definition for option .* is not of type .*. Definition values:\n\s*- In .*: "1000"' config.value ./declare-coerced-value-unsound.nix ./define-value-string-bigint.nix
306324
checkConfigError 'toInt: Could not convert .* to int' config.value ./declare-coerced-value-unsound.nix ./define-value-string-arbitrary.nix
307325

326+
# Check `graph` attribute
327+
checkExpression './graph/test.nix'
328+
308329
# Check mkAliasOptionModule.
309330
checkConfigOutput '^true$' config.enable ./alias-with-priority.nix
310331
checkConfigOutput '^true$' config.enableAlias ./alias-with-priority.nix

lib/tests/modules/graph/a.nix

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
imports = [
3+
{
4+
imports = [ { } ];
5+
}
6+
];
7+
disabledModules = [ ./b.nix ];
8+
}

lib/tests/modules/graph/b.nix

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
args: {
2+
imports = [ { key = "explicit-key"; } ];
3+
}

lib/tests/modules/graph/test.nix

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
let
2+
lib = import ../../..;
3+
4+
evaluation = lib.evalModules {
5+
modules = [
6+
{ }
7+
(args: { })
8+
./a.nix
9+
./b.nix
10+
];
11+
};
12+
13+
actual = evaluation.graph;
14+
15+
expected = [
16+
{
17+
key = ":anon-1";
18+
file = "<unknown-file>";
19+
imports = [ ];
20+
disabled = false;
21+
}
22+
{
23+
key = ":anon-2";
24+
file = "<unknown-file>";
25+
imports = [ ];
26+
disabled = false;
27+
}
28+
{
29+
key = toString ./a.nix;
30+
file = toString ./a.nix;
31+
imports = [
32+
{
33+
key = "${toString ./a.nix}:anon-1";
34+
file = toString ./a.nix;
35+
imports = [
36+
{
37+
key = "${toString ./a.nix}:anon-1:anon-1";
38+
file = toString ./a.nix;
39+
imports = [ ];
40+
disabled = false;
41+
}
42+
];
43+
disabled = false;
44+
}
45+
];
46+
disabled = false;
47+
}
48+
{
49+
key = toString ./b.nix;
50+
file = toString ./b.nix;
51+
imports = [
52+
{
53+
key = "explicit-key";
54+
file = toString ./b.nix;
55+
imports = [ ];
56+
disabled = false;
57+
}
58+
];
59+
disabled = true;
60+
}
61+
];
62+
in
63+
assert actual == expected;
64+
null

0 commit comments

Comments
 (0)