diff --git a/default.nix b/default.nix index 0526e7d..b2c4820 100644 --- a/default.nix +++ b/default.nix @@ -23,16 +23,40 @@ let files = leaves path; in { - imports = if scoped == { } then files else map scoped-import files; + imports = if scoped == { } then files else map scoped-import-module files; }; - scoped-import = builtins.scopedImport ( - { - inherit builtins; - __nixPath = [ ]; - } - // scoped - ); + # Like builtins.scopedImport but: + # - include scope argument in builtins as `builtins.scoped`, for potential reuse in nested invocations + # - empty `__nixPath` and `builtins.nixPath` (unless explictely set in `scoped` argument) + scoped-import = + scoped: + builtins.scopedImport ( + { + __nixPath = [ ]; + } + // scoped + // { + builtins = + scoped.builtins or ( + builtins + // { + nixPath = [ ]; + } + ) + // { + inherit scoped; + }; + } + ); + + scoped-import-module = file: { + # Let's not lose track of the original file even if scope-imported: + _file = file; + imports = [ + (scoped-import scoped file) + ]; + }; leaves = let diff --git a/docs/src/content/docs/reference/api.mdx b/docs/src/content/docs/reference/api.mdx index d545957..b62a003 100644 --- a/docs/src/content/docs/reference/api.mdx +++ b/docs/src/content/docs/reference/api.mdx @@ -169,10 +169,21 @@ The provided attributes are merged into the scope used by `builtins.scopedImport Multiple `.addScoped` calls accumulate: ```nix -import-tree (it: it.addScoped { foo = 42 }) (it: it.addScoped { bar = 99 }) +import-tree (it: it.addScoped { foo = 42 }) (it: it.addScoped { bar = 99 }) ./modules # modules can access both foo and bar ``` +Scoped variables can be accessed inside scoped-imported modules as `builtins.scoped`: + +```nix +# module.nix +{ + imports = [ (import-tree.addScoped (builtins.scoped // { bar = foo; }) ./other-modules) ]; + # other-modules can now access `bar` directly in addition to `foo` and `mylib` +} + +``` + --- ## Output diff --git a/tests.nix b/tests.nix index 5149660..2429572 100644 --- a/tests.nix +++ b/tests.nix @@ -270,6 +270,78 @@ in expected = 22; }; + scoped."test access all scoped variable via scopedImport" = { + expr = + (lib.evalModules { + modules = [ + ( + (lit.addScoped { + foo = 22; + bar = "44"; + builtins = { + hello = "world"; + }; + }) + ./tree/_scoped + ) + ]; + }).config.builtins.scoped; + expected = { + foo = 22; + bar = "44"; + builtins = { + hello = "world"; + }; + }; + }; + + scoped."test settings builtins via scopedImport" = { + expr = + (lib.evalModules { + modules = [ + ( + (lit.addScoped { + foo = 22; + bar = "44"; + builtins = { + hello = "world"; + }; + }) + ./tree/_scoped + ) + ]; + }).config.builtins; + expected = { + hello = "world"; + scoped = { + foo = 22; + bar = "44"; + builtins = { + hello = "world"; + }; + }; + }; + }; + + scoped."test builtins.nixPath and __nixPath are empty via scopedImport" = { + expr = + let + eval = lib.evalModules { + modules = [ + ( + (lit.addScoped { + foo = 22; + bar = "44"; + }) + ./tree/_scoped + ) + ]; + }; + in + eval.config.builtins.nixPath == [ ] && eval.config.__nixPath == [ ]; + expected = true; + }; + combinator."test combinator syntax to compose import-tree" = { expr = it (it: it.withLib lib) (it: it.leaves) ./tree/_scoped; expected = [ ./tree/_scoped/foo.nix ]; diff --git a/tree/_scoped/foo.nix b/tree/_scoped/foo.nix index 8badecc..08175a5 100644 --- a/tree/_scoped/foo.nix +++ b/tree/_scoped/foo.nix @@ -1,4 +1,6 @@ { lib, ... }: { options.foo = lib.mkOption { default = foo; }; + options.__nixPath = lib.mkOption { default = __nixPath; }; + options.builtins = lib.mkOption { default = builtins; }; }