about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-11-23T12·00+0300
committertazjin <mail@tazj.in>2021-11-23T14·42+0000
commit5cad3f7b81b1460aeceb40936e0c7dcb029936a6 (patch)
treed73c08bc12e84fa8adc640ec6b62e0105dd68686
parentab92c42f594c22ad6a5bb090e7f4f347ddddcd34 (diff)
refactor(readTree): Move 'gather' into readTree itself r/3087
Discovering CI targets is relevant to all readTree consumers and this
logic is not TVL-specific.

Change-Id: I81ed3d3f76a6c36119f04bee28ca995a013f0e35
-rw-r--r--default.nix27
-rw-r--r--nix/readTree/default.nix34
2 files changed, 35 insertions, 26 deletions
diff --git a/default.nix b/default.nix
index 991010c5ff..7ccd7413db 100644
--- a/default.nix
+++ b/default.nix
@@ -6,7 +6,6 @@
 
 let
   inherit (builtins)
-    concatMap
     filter
     ;
 
@@ -69,30 +68,6 @@ let
   # Is this tree node eligible for build inclusion?
   eligible = node: (node ? outPath) && (node.meta.ci or true);
 
-  # Walk the tree starting with 'node', recursively extending the list
-  # of build targets with anything that looks buildable.
-  #
-  # Any tree node can specify logical targets by exporting a
-  # 'meta.targets' attribute containing a list of keys in itself. This
-  # enables target specifications that do not exist on disk directly.
-  gather = node:
-    if node ? __readTree then
-      # Include the node itself if it is eligible.
-      (if eligible node then [ node ] else [])
-      # Include eligible children of the node
-      ++ concatMap gather (map (attr: node."${attr}") node.__readTreeChildren)
-      # Include specified sub-targets of the node
-      ++ filter eligible (map
-           (k: (node."${k}" or {}) // {
-             # Keep the same tree location, but explicitly mark this
-             # node as a subtarget.
-             __readTree = node.__readTree;
-             __readTreeChildren = [];
-             __subtarget = k;
-           })
-           (node.meta.targets or []))
-    else [];
-
 in readTree.fix(self: (readDepot {
   depot = self;
 
@@ -118,7 +93,7 @@ in readTree.fix(self: (readDepot {
   #
   # Note: To prevent infinite recursion, this *must* be a nested
   # attribute set (which does not have a __readTree attribute).
-  ci.targets = gather (self // {
+  ci.targets = readTree.gather eligible (self // {
     # remove the pipelines themselves from the set over which to
     # generate pipelines because that also leads to infinite
     # recursion.
diff --git a/nix/readTree/default.nix b/nix/readTree/default.nix
index 3738a6cea6..5e805b5f4a 100644
--- a/nix/readTree/default.nix
+++ b/nix/readTree/default.nix
@@ -20,6 +20,7 @@
 let
   inherit (builtins)
     attrNames
+    concatMap
     concatStringsSep
     elem
     elemAt
@@ -125,7 +126,40 @@ let
       then nodeValue // allChildren // (marker parts allChildren)
       else nodeValue;
 
+  # Function can be used to find all readTree targets within an
+  # attribute set.
+  #
+  # This function will gather physical targets, that is targets which
+  # correspond directly to a location in the repository, as well as
+  # subtargets (specified in the meta.targets attribute of a node).
+  #
+  # This can be used to discover targets for inclusion in CI
+  # pipelines.
+  #
+  # Called with the arguments:
+  #
+  #   eligible: Function to determine whether the given derivation
+  #             should be included in the build.
+  gather = eligible: node:
+    if node ? __readTree then
+      # Include the node itself if it is eligible.
+      (if eligible node then [ node ] else [])
+      # Include eligible children of the node
+      ++ concatMap (gather eligible) (map (attr: node."${attr}") node.__readTreeChildren)
+      # Include specified sub-targets of the node
+      ++ filter eligible (map
+           (k: (node."${k}" or {}) // {
+             # Keep the same tree location, but explicitly mark this
+             # node as a subtarget.
+             __readTree = node.__readTree;
+             __readTreeChildren = [];
+             __subtarget = k;
+           })
+           (node.meta.targets or []))
+    else [];
 in {
+  inherit gather;
+
   __functor = _:
     { path
     , args