about summary refs log tree commit diff
path: root/nix
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-04-12T19·49+0200
committertazjin <mail@tazj.in>2021-04-12T21·55+0000
commita5591359702b62e4edd7fdbbd135475037aa6727 (patch)
treef4728bf352866c2e3555011b7029c7dfe65b00c4 /nix
parentf59ab9aba506c1ed149f7093f5543ef021567ebc (diff)
refactor(readTree): Initialise repo roots without recursing r/2496
Plumbs an additional internal argument through readTree that indicates
whether the top-level of a tree is being read, and avoids recursing
into itself in that case. This changes the externally visible
behaviour of readTree (it is now expected to be called a level higher
than previously).

This allows us to reduce the amount of boilerplate needed to bootstrap
the TVL repository (by not having to specify the individual folders
that need to be read).

For reasons related to an infinite recursion we could not (be bothered
to) debug, the top-level `config` key (which held the attribute set
passed on by readTree) has been removed. This is not needed, as it is
already passed on by readTree ...

Co-Authored-By: Florian Klink <flokli@flokli.de>
Change-Id: Id6e39b57b2f5b3473c4b695a72dd1d01fcfb7a66
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2961
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Reviewed-by: grfn <grfn@gws.fyi>
Diffstat (limited to 'nix')
-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 = [];
+  };
 }