about summary refs log tree commit diff
path: root/nix/readTree
diff options
context:
space:
mode:
Diffstat (limited to 'nix/readTree')
-rw-r--r--nix/readTree/README.md3
-rw-r--r--nix/readTree/default.nix20
2 files changed, 19 insertions, 4 deletions
diff --git a/nix/readTree/README.md b/nix/readTree/README.md
index c93cf2bfdd61..138abbe30583 100644
--- a/nix/readTree/README.md
+++ b/nix/readTree/README.md
@@ -60,6 +60,9 @@ with some exceptions:
 * If a folder contains a `default.nix` it is loaded and, if it evaluates to a
   set, *merged* with the children. If it evaluates to anything else the children
   are *not traversed*.
+* The `default.nix` of the top-level folder on which readTree is
+  called is **not** read to avoid infinite recursion (as, presumably,
+  this file is where readTree itself is called).
 
 Traversal is lazy, `readTree` will only build up the tree as requested. This
 currently has the downside that directories with no importable files end up in
diff --git a/nix/readTree/default.nix b/nix/readTree/default.nix
index 1f0de59e1ecc..4d5385921ee2 100644
--- a/nix/readTree/default.nix
+++ b/nix/readTree/default.nix
@@ -65,12 +65,15 @@ let
     let res = match "(.*)\\.nix" file;
     in if res == null then null else head res;
 
-  readTree = args: initPath: parts:
+  readTree = { args, initPath, rootDir, parts }:
     let
       dir = readDirVisible initPath;
-      self = importWithMark args initPath parts;
       joinChild = c: initPath + ("/" + c);
 
+      self = if rootDir
+        then { __readTree = []; }
+        else importWithMark args initPath parts;
+
       # Import subdirectories of the current one, unless the special
       # `.skip-subtree` file exists which makes readTree ignore the
       # children.
@@ -81,7 +84,12 @@ let
       filterDir = f: dir."${f}" == "directory";
       children = if hasAttr ".skip-subtree" dir then [] else map (c: {
         name = c;
-        value = readTree args (joinChild c) (parts ++ [ c ]);
+        value = readTree {
+          args = args;
+          initPath = (joinChild c);
+          rootDir = false;
+          parts = (parts ++ [ c ]);
+        };
       }) (filter filterDir (attrNames dir));
 
       # Import Nix files
@@ -95,5 +103,9 @@ let
       else (listToAttrs (nixChildren ++ children) // (marker parts));
 
 in {
-   __functor = _: args: initPath: readTree args initPath [ (baseNameOf initPath) ];
+  __functor = _: args: initPath: readTree {
+    inherit args initPath;
+    rootDir = true;
+    parts = [];
+  };
 }