about summary refs log tree commit diff
path: root/read-tree.nix
diff options
context:
space:
mode:
Diffstat (limited to 'read-tree.nix')
-rw-r--r--read-tree.nix39
1 files changed, 26 insertions, 13 deletions
diff --git a/read-tree.nix b/read-tree.nix
index d883d12c8171..d742c69ea411 100644
--- a/read-tree.nix
+++ b/read-tree.nix
@@ -1,29 +1,25 @@
-path: { pkgs, ... } @ args:
+initPath: { pkgs, ... } @ args:
 
 let
   inherit (builtins)
     attrNames
-    attrValues
     filter
     head
     isString
+    length
     listToAttrs
     map
     match
     readDir
+    split
     tail
     toPath
     toString;
 
-  zipAttrs = names: values:
-    if (names == []) || (values == [])
-    then []
-    else [{
-      name = head names;
-      value = head values;
-    }] ++ zipAttrs (tail names) (tail values);
-
-  attrsToList = attrs: zipAttrs (attrNames attrs) (attrValues attrs);
+  attrsToList = attrs: map (name: {
+    inherit name;
+    value = attrs."${name}";
+  }) (attrNames attrs);
 
   isFile = s: s == "regular";
   isDir = s: s == "directory";
@@ -44,6 +40,23 @@ let
         }) files;
     in filter (f: isString f.name) nixFiles;
 
+  # Some packages require that their position in the tree is passed in
+  # as an argument. To do this the root directory (i.e. $PWD during
+  # imports) is chopped off the front of the path components in
+  # imports.
+  pathParts = p: tail (filter isString (split "/" (toString p)));
+  initLen = length (pathParts ./.);
+  drop = n: l:
+    if n == 0
+      then l
+      else if l == []
+        then []
+        else drop (n - 1) (tail l);
+
+  argsWithPath = args: parts: args // {
+    locatedAt = drop initLen parts;
+  };
+
   traverse = path: dir:
     let nixFiles = filterNixFiles dir;
         imported = map (f: {
@@ -58,8 +71,8 @@ let
 
   importOr = path: dir: f:
     if dir ? "default.nix"
-      then import path args
+      then import path (argsWithPath args (pathParts path))
       else f path (attrsToList dir);
 
   readTree = path: importOr path (readDir path) traverse;
-in readTree path
+in readTree initPath