From fb0b426862b52f1ce1888a5957070194838a89ac Mon Sep 17 00:00:00 2001 From: Archit Gupta Date: Sun, 10 Aug 2025 19:13:57 -0700 Subject: [PATCH] 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. --- API_GUIDE.md | 6 ++++++ builtinModules/flakelightModules.nix | 2 ++ builtinModules/homeModules.nix | 2 ++ builtinModules/nixDir.nix | 24 ++++++++++++++++++------ builtinModules/nixosModules.nix | 2 ++ default.nix | 10 ++++++---- 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/API_GUIDE.md b/API_GUIDE.md index 466389a..d8238fd 100644 --- a/API_GUIDE.md +++ b/API_GUIDE.md @@ -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 ``` diff --git a/builtinModules/flakelightModules.nix b/builtinModules/flakelightModules.nix index 922c2d0..609f3db 100644 --- a/builtinModules/flakelightModules.nix +++ b/builtinModules/flakelightModules.nix @@ -29,5 +29,7 @@ in (mkIf (config.flakelightModules != { }) { outputs = { inherit (config) flakelightModules; }; }) + + { nixDirPathAttrs = [ "flakelightModules" ]; } ]; } diff --git a/builtinModules/homeModules.nix b/builtinModules/homeModules.nix index c382e85..82eeb60 100644 --- a/builtinModules/homeModules.nix +++ b/builtinModules/homeModules.nix @@ -29,5 +29,7 @@ in (mkIf (config.homeModules != { }) { outputs = { inherit (config) homeModules; }; }) + + { nixDirPathAttrs = [ "homeModules" ]; } ]; } diff --git a/builtinModules/nixDir.nix b/builtinModules/nixDir.nix index 247385a..06fa739 100644 --- a/builtinModules/nixDir.nix +++ b/builtinModules/nixDir.nix @@ -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; diff --git a/builtinModules/nixosModules.nix b/builtinModules/nixosModules.nix index 15f1078..71c3809 100644 --- a/builtinModules/nixosModules.nix +++ b/builtinModules/nixosModules.nix @@ -29,5 +29,7 @@ in (mkIf (config.nixosModules != { }) { outputs = { inherit (config) nixosModules; }; }) + + { nixDirPathAttrs = [ "nixosModules" ]; } ]; } diff --git a/default.nix b/default.nix index 830abde..a80dad6 100644 --- a/default.nix +++ b/default.nix @@ -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