Skip to content

Commit

Permalink
feat: add configurable hoistLists transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
blaggacao committed Apr 10, 2023
1 parent 3d65f3d commit 5438611
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/transformers/_utils.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{lib}: let
inherit (lib)
attrValues
flip
foldl'
mapAttrs
pipe
;
in {
/*concatMapAttrsWith: map each attribute in the given set into
a list of attributes and subsequently merge them into
a new attribute set with the specified mergeFun.
Type:
concatMapAttrsWith :: (AttrSet -> AttrSet -> AttrSet) -> (String -> a -> AttrSet)
-> AttrSet -> AttrSet
Example:
concatMapAttrsWith (mergeAttrsButConcatOn "mykey")
(name: value: {
${name} = value;
${key} = value ++ value;
})
{ x = "a"; y = "b"; }
=> { x = "a"; y = "b"; mykey = [ "aa" "bb"]; }
*/
concatMapAttrsWith = mergeFun: f: flip pipe [ (mapAttrs f) attrValues (foldl' mergeFun { }) ];
}
52 changes: 52 additions & 0 deletions src/transformers/hoistLists.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{ lib, super }: from: to:

# Example from / to
# - Lifting `imports` from: _imports, to: imports
#
# Note: underscore used as mere convention to
# signalling to the user the "private"
# nature, they won't be part of the final
# view presented to the user

let
inherit (builtins)
removeAttrs
;

inherit (lib)
catAttrs
concatLists
;

inherit (super.utils)
concatMapAttrsWith
;

/*mergeAttrsButConcatOn: merge attributes shallowly, but
concat values of a specific key into a list in that key
Type:
(key :: String -> AttrSet -> AttrSet) -> { ${key} :: List; ... }
*/
mergeAttrsButConcatOn = key: x: y:
x // y // {
${key} = concatLists (catAttrs key [ x y ]);
};

in
cursor:
if cursor == [ ] # toplevel
then
concatMapAttrsWith (mergeAttrsButConcatOn to)
(file: value: if ! value ? ${from} then { ${file} = value; } else {
${file} = removeAttrs value [ from ];
# top level ${from} declarations are omitted from merging
${to} = value.${from};
})
else
concatMapAttrsWith (mergeAttrsButConcatOn from)
(file: value: if ! value ? ${from} then { ${file} = value; } else {
${file} = removeAttrs value [ from ];
${from} = value.${from};
})

0 comments on commit 5438611

Please sign in to comment.