about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-11-25T15·32+0000
committerVincent Ambo <tazjin@google.com>2019-11-25T15·32+0000
commit43f91c44bd0fac60aed86eeeb1b57d482e1199e4 (patch)
treed410d7039b086b45e5bc8b12d7f7764096e5fe77
parent48ed487bddb7429e6d79db1151e82b7316c31b37 (diff)
feat(read-tree): Pass in-tree location to imported package sets
Passes the location from the root at which packages are imported on to
all packages.

The path is passed in as a parameter called 'locatedAt' which contains
a list of strings with each individual path component.

For example, the blog source in `services/tazblog` will have a list
with `[ "services" "tazblog" ]` passed in as the `locatedAt`
attribute.

This can be used for enabling features such as path-specific imports
when using things like buildGo.
-rw-r--r--read-tree.nix26
1 files changed, 23 insertions, 3 deletions
diff --git a/read-tree.nix b/read-tree.nix
index 2c53ee1d9b0f..d742c69ea411 100644
--- a/read-tree.nix
+++ b/read-tree.nix
@@ -1,4 +1,4 @@
-path: { pkgs, ... } @ args:
+initPath: { pkgs, ... } @ args:
 
 let
   inherit (builtins)
@@ -6,10 +6,13 @@ let
     filter
     head
     isString
+    length
     listToAttrs
     map
     match
     readDir
+    split
+    tail
     toPath
     toString;
 
@@ -37,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: {
@@ -51,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