diff --git a/lib/compat/filter.nix b/lib/compat/filter.nix index b6f1f99..1b1cb2f 100644 --- a/lib/compat/filter.nix +++ b/lib/compat/filter.nix @@ -1,6 +1,57 @@ {l}: let filter = pred: t: p: let multiplePaths = l.isList (l.elemAt p 0); + + # function to expand wildcards in a path + expandPath = path: + if !(l.elem "*" path) + then [path] + else let + availableCells = t.__ren.cells or []; + + # get the first valid system + sampleSystem = l.head (l.filter (n: l.elem n l.systems.doubles.all) (l.attrNames t)); + + # handle different wildcard positions + expandWildcardAt = pos: + if pos >= l.length path + then [path] + else if (l.elemAt path pos) != "*" + then expandWildcardAt (pos + 1) + else let + prefix = l.take pos path; + suffix = l.drop (pos + 1) path; + + choices = + if pos == 0 # cell names + then availableCells + else if pos == 1 # cell block names + then let + cellName = l.elemAt path 0; + cellAttrs = t.${sampleSystem}.${cellName} or {}; + in + l.attrNames cellAttrs + else # target names (pos >= 2) + let + cellName = l.elemAt path 0; + blockName = l.elemAt path 1; + blockAttrs = t.${sampleSystem}.${cellName}.${blockName} or {}; + in + l.attrNames blockAttrs; + + expandedPaths = l.map (choice: prefix ++ [choice] ++ suffix) choices; + in + # recursively expand any remaining wildcards in each expanded path + l.concatMap expandPath expandedPaths; + in + expandWildcardAt 0; + + # expand all paths that contain wildcards + expandedPaths = + if multiplePaths + then l.concatMap expandPath p + else expandPath p; + hoist = path: let result = l.filterAttrs ( @@ -11,7 +62,7 @@ t; in if result == {} - then builtins.abort "[ren] filter: Path ${toString path} not found in any targets." + then null # return null for non-matching paths else l.mapAttrs ( _: v: let @@ -22,9 +73,13 @@ else l.filterAttrs pred attr ) result; + + # process all expanded paths and merge results + results = l.map hoist expandedPaths; + validResults = l.filter (r: r != null) results; in - if multiplePaths - then l.foldl' l.recursiveUpdate {} (map (path: hoist path) p) - else hoist p; + if validResults == [] + then builtins.abort "[ren] filter: No matching paths found for ${toString p}. Expanded to: ${toString expandedPaths}" + else l.foldl' l.recursiveUpdate {} validResults; in filter diff --git a/lib/core/builder.nix b/lib/core/builder.nix index f52ff2a..86c2a65 100644 --- a/lib/core/builder.nix +++ b/lib/core/builder.nix @@ -52,6 +52,7 @@ // { __ren = { __schema = "v0"; + cells = builtins.attrNames (l.readDir cellsFrom); init = l.listToAttrs res.init; actions = res.actions; cellsFrom = l.baseNameOf cellsFrom;