about summary refs log tree commit diff
path: root/nix
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-09-08T15·27+0300
committertazjin <mail@tazj.in>2021-09-09T11·37+0000
commitb1f4b530ec1548d75c0e318fcdf90d33a373a5ca (patch)
treed28d07ceeb1e5d834764bfdd6dc66b0f7b25daa1 /nix
parentaedde913d125737f81e63edbc7481e886b0a4f2d (diff)
feat(readTree): Support scoped import arguments r/2825
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>
Diffstat (limited to 'nix')
-rw-r--r--nix/readTree/README.md3
-rw-r--r--nix/readTree/default.nix21
2 files changed, 15 insertions, 9 deletions
diff --git a/nix/readTree/README.md b/nix/readTree/README.md
index b56bc944ca..f8bbe2255e 100644
--- a/nix/readTree/README.md
+++ b/nix/readTree/README.md
@@ -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
diff --git a/nix/readTree/default.nix b/nix/readTree/default.nix
index b105738a4f..7c48d177fb 100644
--- a/nix/readTree/default.nix
+++ b/nix/readTree/default.nix
@@ -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;