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
|
||||
import based on the location in the tree. This can be used to, for
|
||||
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
|
||||
`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
|
||||
# readTree.
|
||||
importWithMark = args: path: parts: filter:
|
||||
let
|
||||
importedFile = import path;
|
||||
importWithMark = args: scopedArgs: path: parts: filter:
|
||||
let
|
||||
importedFile = if scopedArgs != {}
|
||||
then builtins.scopedImport scopedArgs path
|
||||
else import path;
|
||||
pathType = builtins.typeOf importedFile;
|
||||
imported =
|
||||
assert assertMsg
|
||||
|
@ -76,14 +78,14 @@ let
|
|||
let res = match "(.*)\\.nix" file;
|
||||
in if res == null then null else head res;
|
||||
|
||||
readTree = { args, initPath, rootDir, parts, argsFilter }:
|
||||
readTree = { args, initPath, rootDir, parts, argsFilter, scopedArgs }:
|
||||
let
|
||||
dir = readDirVisible initPath;
|
||||
joinChild = c: initPath + ("/" + c);
|
||||
|
||||
self = if rootDir
|
||||
then { __readTree = []; }
|
||||
else importWithMark args initPath parts argsFilter;
|
||||
else importWithMark args scopedArgs initPath parts argsFilter;
|
||||
|
||||
# Import subdirectories of the current one, unless the special
|
||||
# `.skip-subtree` file exists which makes readTree ignore the
|
||||
|
@ -96,7 +98,7 @@ let
|
|||
children = if hasAttr ".skip-subtree" dir then [] else map (c: {
|
||||
name = c;
|
||||
value = readTree {
|
||||
inherit argsFilter;
|
||||
inherit argsFilter scopedArgs;
|
||||
args = args;
|
||||
initPath = (joinChild c);
|
||||
rootDir = false;
|
||||
|
@ -108,7 +110,7 @@ let
|
|||
nixFiles = filter (f: f != null) (map nixFileName (attrNames dir));
|
||||
nixChildren = map (c: let p = joinChild (c + ".nix"); in {
|
||||
name = c;
|
||||
value = importWithMark args p (parts ++ [ c ]) argsFilter;
|
||||
value = importWithMark args scopedArgs p (parts ++ [ c ]) argsFilter;
|
||||
}) nixFiles;
|
||||
in if dir ? "default.nix"
|
||||
then (if isAttrs self then self // (listToAttrs children) else self)
|
||||
|
@ -118,9 +120,10 @@ in {
|
|||
__functor = _:
|
||||
{ path
|
||||
, args
|
||||
, filter ? (x: _parts: x) }:
|
||||
, filter ? (x: _parts: x)
|
||||
, scopedArgs ? {} }:
|
||||
readTree {
|
||||
inherit args;
|
||||
inherit args scopedArgs;
|
||||
argsFilter = filter;
|
||||
initPath = path;
|
||||
rootDir = true;
|
||||
|
|
Loading…
Reference in a new issue