feat(readTree): Support scoped import arguments
This makes it possible to override Nix builtins within a readTree structure. Why would you want to do that, you might ask? Well ... Change-Id: Icc9cb32e5db4a2eba370cf81769c642d237d4937 Reviewed-on: https://cl.tvl.fyi/c/depot/+/3499 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
parent
aedde913d1
commit
b1f4b530ec
2 changed files with 15 additions and 9 deletions
|
@ -77,6 +77,9 @@ the tree as empty nodes (`{}`).
|
||||||
* `filter`: (optional) A function to filter the argument set on each
|
* `filter`: (optional) A function to filter the argument set on each
|
||||||
import based on the location in the tree. This can be used to, for
|
import based on the location in the tree. This can be used to, for
|
||||||
example, implement a "visibility" system inside of a tree.
|
example, implement a "visibility" system inside of a tree.
|
||||||
|
* `scopedArgs`: (optional) An argument set that is passed to all
|
||||||
|
imported files via `builtins.scopedImport`. This will forcefully
|
||||||
|
override the given values in the import scope, use with care!
|
||||||
|
|
||||||
The package headers in this repository follow the form `{ pkgs, ... }:` where
|
The package headers in this repository follow the form `{ pkgs, ... }:` where
|
||||||
`pkgs` is a fixed-point of the entire package tree (see the `default.nix` at the
|
`pkgs` is a fixed-point of the entire package tree (see the `default.nix` at the
|
||||||
|
|
|
@ -59,9 +59,11 @@ let
|
||||||
|
|
||||||
# The marker is added to every set that was imported directly by
|
# The marker is added to every set that was imported directly by
|
||||||
# readTree.
|
# readTree.
|
||||||
importWithMark = args: path: parts: filter:
|
importWithMark = args: scopedArgs: path: parts: filter:
|
||||||
let
|
let
|
||||||
importedFile = import path;
|
importedFile = if scopedArgs != {}
|
||||||
|
then builtins.scopedImport scopedArgs path
|
||||||
|
else import path;
|
||||||
pathType = builtins.typeOf importedFile;
|
pathType = builtins.typeOf importedFile;
|
||||||
imported =
|
imported =
|
||||||
assert assertMsg
|
assert assertMsg
|
||||||
|
@ -76,14 +78,14 @@ let
|
||||||
let res = match "(.*)\\.nix" file;
|
let res = match "(.*)\\.nix" file;
|
||||||
in if res == null then null else head res;
|
in if res == null then null else head res;
|
||||||
|
|
||||||
readTree = { args, initPath, rootDir, parts, argsFilter }:
|
readTree = { args, initPath, rootDir, parts, argsFilter, scopedArgs }:
|
||||||
let
|
let
|
||||||
dir = readDirVisible initPath;
|
dir = readDirVisible initPath;
|
||||||
joinChild = c: initPath + ("/" + c);
|
joinChild = c: initPath + ("/" + c);
|
||||||
|
|
||||||
self = if rootDir
|
self = if rootDir
|
||||||
then { __readTree = []; }
|
then { __readTree = []; }
|
||||||
else importWithMark args initPath parts argsFilter;
|
else importWithMark args scopedArgs initPath parts argsFilter;
|
||||||
|
|
||||||
# Import subdirectories of the current one, unless the special
|
# Import subdirectories of the current one, unless the special
|
||||||
# `.skip-subtree` file exists which makes readTree ignore the
|
# `.skip-subtree` file exists which makes readTree ignore the
|
||||||
|
@ -96,7 +98,7 @@ let
|
||||||
children = if hasAttr ".skip-subtree" dir then [] else map (c: {
|
children = if hasAttr ".skip-subtree" dir then [] else map (c: {
|
||||||
name = c;
|
name = c;
|
||||||
value = readTree {
|
value = readTree {
|
||||||
inherit argsFilter;
|
inherit argsFilter scopedArgs;
|
||||||
args = args;
|
args = args;
|
||||||
initPath = (joinChild c);
|
initPath = (joinChild c);
|
||||||
rootDir = false;
|
rootDir = false;
|
||||||
|
@ -108,7 +110,7 @@ let
|
||||||
nixFiles = filter (f: f != null) (map nixFileName (attrNames dir));
|
nixFiles = filter (f: f != null) (map nixFileName (attrNames dir));
|
||||||
nixChildren = map (c: let p = joinChild (c + ".nix"); in {
|
nixChildren = map (c: let p = joinChild (c + ".nix"); in {
|
||||||
name = c;
|
name = c;
|
||||||
value = importWithMark args p (parts ++ [ c ]) argsFilter;
|
value = importWithMark args scopedArgs p (parts ++ [ c ]) argsFilter;
|
||||||
}) nixFiles;
|
}) nixFiles;
|
||||||
in if dir ? "default.nix"
|
in if dir ? "default.nix"
|
||||||
then (if isAttrs self then self // (listToAttrs children) else self)
|
then (if isAttrs self then self // (listToAttrs children) else self)
|
||||||
|
@ -118,9 +120,10 @@ in {
|
||||||
__functor = _:
|
__functor = _:
|
||||||
{ path
|
{ path
|
||||||
, args
|
, args
|
||||||
, filter ? (x: _parts: x) }:
|
, filter ? (x: _parts: x)
|
||||||
|
, scopedArgs ? {} }:
|
||||||
readTree {
|
readTree {
|
||||||
inherit args;
|
inherit args scopedArgs;
|
||||||
argsFilter = filter;
|
argsFilter = filter;
|
||||||
initPath = path;
|
initPath = path;
|
||||||
rootDir = true;
|
rootDir = true;
|
||||||
|
|
Loading…
Reference in a new issue