mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 11:36:05 +01:00
generators: rewrite toSCFG
The former toSCFG implementation had several shortcomings which did not consider a few possibilities SCFG provides. Details were lined out in #7465. The new interface needs more verbosity, but reflects better the properties of the SCFG format. I also chose to use the names used in the [Specification]. [Specification]: https://git.sr.ht/~emersion/scfg#specification-draft
This commit is contained in:
parent
c9d758b500
commit
89a9fa0f3f
4 changed files with 80 additions and 90 deletions
|
|
@ -211,9 +211,15 @@
|
|||
toSCFG =
|
||||
{ }:
|
||||
let
|
||||
inherit (lib) concatStringsSep mapAttrsToList any;
|
||||
inherit (lib) concatStringsSep any;
|
||||
inherit (builtins) typeOf replaceStrings elem;
|
||||
|
||||
filterNullDirectives = lib.filter (
|
||||
directive:
|
||||
!(directive ? "params" || directive ? "children")
|
||||
|| !(directive.params or [ null ] == [ null ] && directive.children or [ ] == [ ])
|
||||
);
|
||||
|
||||
# ListOf String -> String
|
||||
indentStrings =
|
||||
let
|
||||
|
|
@ -221,8 +227,8 @@
|
|||
# the strings themselves *will* contain newlines, so you need
|
||||
# to normalize the list by joining and resplitting them.
|
||||
unlines = lib.splitString "\n";
|
||||
lines = lib.concatStringsSep "\n";
|
||||
indentAll = lines: concatStringsSep "\n" (map (x: " " + x) lines);
|
||||
lines = concatStringsSep "\n";
|
||||
indentAll = lines: concatStringsSep "\n" (map (x: "\t" + x) lines);
|
||||
in
|
||||
stringsWithNewlines: indentAll (unlines (lines stringsWithNewlines));
|
||||
|
||||
|
|
@ -256,7 +262,7 @@
|
|||
"\\"
|
||||
"\r"
|
||||
"\n"
|
||||
" "
|
||||
"\t"
|
||||
];
|
||||
|
||||
# OneOf [Int Float String Bool] -> String
|
||||
|
|
@ -284,7 +290,7 @@
|
|||
# Bool -> ListOf (OneOf [Int Float String Bool]) -> String
|
||||
toOptParamsString =
|
||||
cond: list:
|
||||
lib.optionalString (cond) (
|
||||
lib.optionalString cond (
|
||||
lib.pipe list [
|
||||
(map literalValueToString)
|
||||
(concatStringsSep " ")
|
||||
|
|
@ -292,65 +298,25 @@
|
|||
]
|
||||
);
|
||||
|
||||
# Attrset Conversion
|
||||
# String -> AttrsOf Anything -> String
|
||||
convertAttrsToSCFG =
|
||||
name: attrs:
|
||||
let
|
||||
optParamsString = toOptParamsString (attrs ? "_params") attrs._params;
|
||||
in
|
||||
''
|
||||
${name}${optParamsString} {
|
||||
${indentStrings (convertToAttrsSCFG' attrs)}
|
||||
}'';
|
||||
|
||||
# Attrset Conversion
|
||||
# AttrsOf Anything -> ListOf String
|
||||
convertToAttrsSCFG' =
|
||||
attrs:
|
||||
mapAttrsToList convertAttributeToSCFG (
|
||||
lib.filterAttrs (name: val: !isNull val && name != "_params") attrs
|
||||
);
|
||||
|
||||
# List Conversion
|
||||
# String -> ListOf (OneOf [Int Float String Bool]) -> String
|
||||
convertListOfFlatAttrsToSCFG =
|
||||
name: list:
|
||||
let
|
||||
optParamsString = toOptParamsString (list != [ ]) list;
|
||||
in
|
||||
"${name}${optParamsString}";
|
||||
|
||||
# Combined Conversion
|
||||
# String -> Anything -> String
|
||||
convertAttributeToSCFG =
|
||||
name: value:
|
||||
lib.throwIf (name == "") "Directive must not be empty" (
|
||||
let
|
||||
vType = typeOf value;
|
||||
in
|
||||
if
|
||||
elem vType [
|
||||
"int"
|
||||
"float"
|
||||
"bool"
|
||||
"string"
|
||||
]
|
||||
then
|
||||
"${name} ${literalValueToString value}"
|
||||
else if vType == "set" then
|
||||
convertAttrsToSCFG name value
|
||||
else if vType == "list" then
|
||||
convertListOfFlatAttrsToSCFG name value
|
||||
else
|
||||
throw ''
|
||||
Cannot convert type `(${typeOf value})` to SCFG:
|
||||
${name} = ${toString value}
|
||||
''
|
||||
);
|
||||
# Directive Conversion
|
||||
# ListOf NameParamChildrenTriplet -> ListOf String
|
||||
convertDirectivesToSCFG =
|
||||
directives:
|
||||
map (
|
||||
directive:
|
||||
(literalValueToString directive.name)
|
||||
+ toOptParamsString (directive ? "params" && directive.params != null) directive.params
|
||||
+ lib.optionalString (directive ? "children" && directive.children != null) (
|
||||
" "
|
||||
+ ''
|
||||
{
|
||||
${indentStrings (convertDirectivesToSCFG directive.children)}
|
||||
}''
|
||||
)
|
||||
) (filterNullDirectives directives);
|
||||
in
|
||||
attrs:
|
||||
lib.optionalString (attrs != { }) ''
|
||||
${concatStringsSep "\n" (convertToAttrsSCFG' attrs)}
|
||||
directives:
|
||||
lib.optionalString (directives != [ ]) ''
|
||||
${lib.concatStringsSep "\n" (convertDirectivesToSCFG directives)}
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
home.file."toscfg-empty-result.txt".text = lib.hm.generators.toSCFG { } { };
|
||||
home.file."toscfg-empty-result.txt".text = lib.hm.generators.toSCFG { } [ ];
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ dir {
|
|||
blk1 p1 "\"p2\"" {
|
||||
sub1 arg11 arg12
|
||||
sub2 arg21 arg22
|
||||
sub2 arg1 arg2
|
||||
sub3 arg31 arg32 {
|
||||
sub-sub1
|
||||
"sub sub1"
|
||||
sub-sub2 arg321 arg322
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,58 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
home.file."toscfg-example-result.txt".text = lib.hm.generators.toSCFG { } {
|
||||
dir = {
|
||||
blk1 = {
|
||||
_params = [
|
||||
home.file."toscfg-example-result.txt".text = lib.hm.generators.toSCFG { } (
|
||||
lib.singleton {
|
||||
name = "dir";
|
||||
children = lib.singleton {
|
||||
name = "blk1";
|
||||
params = [
|
||||
"p1"
|
||||
''"p2"''
|
||||
];
|
||||
sub1 = [
|
||||
"arg11"
|
||||
"arg12"
|
||||
children = [
|
||||
{
|
||||
name = "sub1";
|
||||
params = [
|
||||
"arg11"
|
||||
"arg12"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "sub2";
|
||||
params = [
|
||||
"arg21"
|
||||
"arg22"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "sub2";
|
||||
params = [
|
||||
"arg1"
|
||||
"arg2"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "sub3";
|
||||
params = [
|
||||
"arg31"
|
||||
"arg32"
|
||||
];
|
||||
children = [
|
||||
{ name = "sub sub1"; }
|
||||
{
|
||||
name = "sub-sub2";
|
||||
params = [
|
||||
"arg321"
|
||||
"arg322"
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
sub2 = [
|
||||
"arg21"
|
||||
"arg22"
|
||||
];
|
||||
sub3 = {
|
||||
_params = [
|
||||
"arg31"
|
||||
"arg32"
|
||||
];
|
||||
sub-sub1 = [ ];
|
||||
sub-sub2 = [
|
||||
"arg321"
|
||||
"arg322"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue