Preserve source paths for Nix modules

In order for the module system to track the source location of modules,
they must not be imported and instead just passed to imports as paths.
This commit adds the ability to mark config values such that if those
values are are loaded from `nixDir` and loaded as an attrset, then the
values are just set as paths to the nix files instead of importing them.
This commit is contained in:
Archit Gupta
2025-08-10 19:13:57 -07:00
parent 5286275afd
commit fb0b426862
6 changed files with 36 additions and 10 deletions

View File

@@ -213,6 +213,12 @@ All options except for `nixDir` and `_module` can be configured this way.
To apply transformations on the output of an autoloaded directory, you can use
`option/default.nix` and load the directory with `flakelight.importDir`.
If you add a new config type that should be loaded as paths instead of imported,
such as configs for Nix modules, add them to the `nixDirPathAttrs` option. This
is already set for built-in module options. When options whose names are in
`nixDirPathAttrs` are loaded as a directory, `flakelight.importDirPaths` is used
instead of `flakelight.importDir`.
### outputs
```

View File

@@ -29,5 +29,7 @@ in
(mkIf (config.flakelightModules != { }) {
outputs = { inherit (config) flakelightModules; };
})
{ nixDirPathAttrs = [ "flakelightModules" ]; }
];
}

View File

@@ -29,5 +29,7 @@ in
(mkIf (config.homeModules != { }) {
outputs = { inherit (config) homeModules; };
})
{ nixDirPathAttrs = [ "homeModules" ]; }
];
}

View File

@@ -4,25 +4,30 @@
{ config, options, src, lib, flakelight, ... }:
let
inherit (builtins) attrNames;
inherit (builtins) attrNames elem;
inherit (lib) findFirst genAttrs mkIf mkOption pathExists subtractLists;
inherit (lib.types) attrsOf listOf str;
inherit (flakelight) importDir;
inherit (flakelight) importDir importDirPaths;
inherit (flakelight.types) path;
inherit (config) nixDir;
importName = name:
importName = asPaths: name:
if pathExists (nixDir + "/${name}.nix")
then { success = true; value = import (nixDir + "/${name}.nix"); }
else if pathExists (nixDir + "/${name}/default.nix")
then { success = true; value = import (nixDir + "/${name}"); }
else if pathExists (nixDir + "/${name}")
then { success = true; value = importDir (nixDir + "/${name}"); }
then {
success = true;
value = (if asPaths then importDirPaths else importDir)
(nixDir + "/${name}");
}
else { success = false; };
importNames = names:
findFirst (x: x.success) { success = false; } (map importName names);
importNames = asPaths: names:
findFirst (x: x.success) { success = false; }
(map (importName asPaths) names);
in
{
options = {
@@ -35,6 +40,11 @@ in
type = attrsOf (listOf str);
default = { };
};
nixDirPathAttrs = mkOption {
type = listOf str;
default = [ ];
};
};
config = genAttrs (subtractLists [ "_module" "nixDir" ] (attrNames options))
@@ -42,6 +52,8 @@ in
let
internal = options.${name}.internal or false;
val = importNames
(!(elem name [ "nixDirPathAttrs" "nixDirAliases" ])
&& (elem name config.nixDirPathAttrs))
(if name == "nixDirAliases" then [ name ] else
([ name ] ++ config.nixDirAliases.${name} or [ ]));
cond = !internal && val.success;

View File

@@ -29,5 +29,7 @@ in
(mkIf (config.nixosModules != { }) {
outputs = { inherit (config) nixosModules; };
})
{ nixDirPathAttrs = [ "nixosModules" ]; }
];
}

View File

@@ -38,7 +38,7 @@ let
};
flakelight = {
inherit importDir mkFlake selectAttr types;
inherit importDir importDirPaths mkFlake selectAttr types;
};
types = rec {
@@ -154,7 +154,9 @@ let
};
};
importDir = path: genAttrs
importDir = path: mapAttrs (_: import) (importDirPaths path);
importDirPaths = path: genAttrs
(pipe (readDir path) [
attrNames
(filter (s: s != "default.nix"))
@@ -163,10 +165,10 @@ let
(map (removeSuffix ".nix"))
(map (removePrefix "_"))
])
(p: import (path +
(p: path +
(if pathExists (path + "/_${p}.nix") then "/_${p}.nix"
else if pathExists (path + "/${p}.nix") then "/${p}.nix"
else "/${p}")));
else "/${p}"));
selectAttr = attr: mapAttrs (_: v: v.${attr} or { });
in