refactor(readTree): Move 'gather' into readTree itself

Discovering CI targets is relevant to all readTree consumers and this
logic is not TVL-specific.

Change-Id: I81ed3d3f76a6c36119f04bee28ca995a013f0e35
This commit is contained in:
Vincent Ambo 2021-11-23 15:00:27 +03:00 committed by tazjin
parent ab92c42f59
commit 5cad3f7b81
2 changed files with 35 additions and 26 deletions

View file

@ -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.

View file

@ -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