-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add configurable hoistLists transformer
- Loading branch information
Showing
1 changed file
with
85 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
{ lib }: from: to: | ||
|
||
# Example from / to | ||
# - Lifting `imports` from: _imports, to: imports | ||
# - Lifting `options` from: _api, to: options | ||
# | ||
# 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 (lib) | ||
catAttrs | ||
flip | ||
pipe | ||
mapAttrs | ||
attrValues | ||
foldl' | ||
flatten | ||
; | ||
|
||
/*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} = flatten (catAttrs key [ x y ]); | ||
}; | ||
|
||
/*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 { }) ]; | ||
|
||
in | ||
cursor: mod: | ||
if cursor == [ ] # toplevel | ||
then | ||
concatMapAttrsWith (mergeAttrsButConcatOn to) | ||
(file: value: | ||
# to may be already lifted from a previous transformer (e.g. from default.nix) | ||
if file == to then { ${file} = value; } | ||
else if value ? ${from} | ||
then { | ||
${file} = if value ? ${from} then removeAttrs value [ from ] else value; | ||
${to} = value.${from} or null; | ||
} | ||
else { | ||
${file} = if value ? ${from} then removeAttrs value [ from ] else value; | ||
}) | ||
mod | ||
else | ||
concatMapAttrsWith (mergeAttrsButConcatOn from) | ||
(file: value: | ||
# from may be already lifted from a previous transformer (e.g. from default.nix) | ||
if file == from then { ${file} = value; } | ||
else if value ? ${from} | ||
then { | ||
${file} = if value ? ${from} then removeAttrs value [ from ] else value; | ||
${from} = value.${from} or null; | ||
} | ||
else { | ||
${file} = if value ? ${from} then removeAttrs value [ from ] else value; | ||
}) | ||
mod |