treewide: Format all Nix files

Format all Nix files using the officially approved formatter,
making the CI check introduced in the previous commit succeed:

  nix-build ci -A fmt.check

This is the next step of the of the [implementation](https://github.com/NixOS/nixfmt/issues/153)
of the accepted [RFC 166](https://github.com/NixOS/rfcs/pull/166).

This commit will lead to merge conflicts for a number of PRs,
up to an estimated ~1100 (~33%) among the PRs with activity in the past 2
months, but that should be lower than what it would be without the previous
[partial treewide format](https://github.com/NixOS/nixpkgs/pull/322537).

Merge conflicts caused by this commit can now automatically be resolved while rebasing using the
[auto-rebase script](8616af08d9/maintainers/scripts/auto-rebase).

If you run into any problems regarding any of this, please reach out to the
[formatting team](https://nixos.org/community/teams/formatting/) by
pinging @NixOS/nix-formatting.
This commit is contained in:
Silvan Mosberger
2025-04-01 20:10:43 +02:00
parent 2140bf39e4
commit 374e6bcc40
1523 changed files with 986047 additions and 513621 deletions

View File

@@ -35,7 +35,7 @@ let
filter
flatten
foldl
functionArgs # Note: not the builtin; considers `__functor` in attrsets.
functionArgs # Note: not the builtin; considers `__functor` in attrsets.
gvariant
hasInfix
head
@@ -45,7 +45,7 @@ let
isBool
isDerivation
isFloat
isFunction # Note: not the builtin; considers `__functor` in attrsets.
isFunction # Note: not the builtin; considers `__functor` in attrsets.
isInt
isList
isPath
@@ -74,7 +74,8 @@ let
;
## -- HELPER FUNCTIONS & DEFAULTS --
in rec {
in
rec {
/**
Convert a value to a sensible default string representation.
The builtin `toString` function has some strange defaults,
@@ -88,32 +89,44 @@ in rec {
`v`
: 2\. Function argument
*/
mkValueStringDefault = {}: v:
let err = t: v: abort
("generators.mkValueStringDefault: " +
"${t} not supported: ${toPretty {} v}");
in if isInt v then toString v
mkValueStringDefault =
{ }:
v:
let
err = t: v: abort ("generators.mkValueStringDefault: " + "${t} not supported: ${toPretty { } v}");
in
if isInt v then
toString v
# convert derivations to store paths
else if isDerivation v then toString v
else if isDerivation v then
toString v
# we default to not quoting strings
else if isString v then v
else if isString v then
v
# isString returns "1", which is not a good default
else if true == v then "true"
else if true == v then
"true"
# here it returns to "", which is even less of a good default
else if false == v then "false"
else if null == v then "null"
else if false == v then
"false"
else if null == v then
"null"
# if you have lists you probably want to replace this
else if isList v then err "lists" v
else if isList v then
err "lists" v
# same as for lists, might want to replace
else if isAttrs v then err "attrsets" v
else if isAttrs v then
err "attrsets" v
# functions cant be printed of course
else if isFunction v then err "functions" v
else if isFunction v then
err "functions" v
# Floats currently can't be converted to precise strings,
# condition warning on nix version once this isn't a problem anymore
# See https://github.com/NixOS/nix/pull/3480
else if isFloat v then floatToString v
else err "this value is" (toString v);
else if isFloat v then
floatToString v
else
err "this value is" (toString v);
/**
Generate a line of key k and value v, separated by
@@ -145,15 +158,15 @@ in rec {
: 4\. Function argument
*/
mkKeyValueDefault = {
mkValueString ? mkValueStringDefault {}
}: sep: k: v:
"${escape [sep] k}${sep}${mkValueString v}";
mkKeyValueDefault =
{
mkValueString ? mkValueStringDefault { },
}:
sep: k: v:
"${escape [ sep ] k}${sep}${mkValueString v}";
## -- FILE FORMAT GENERATORS --
/**
Generate a key-value-style config file from an attrset.
@@ -169,19 +182,22 @@ in rec {
: indent (optional, default: `""`)
: Initial indentation level
*/
toKeyValue = {
mkKeyValue ? mkKeyValueDefault {} "=",
listsAsDuplicateKeys ? false,
indent ? ""
}:
let mkLine = k: v: indent + mkKeyValue k v + "\n";
mkLines = if listsAsDuplicateKeys
then k: v: map (mkLine k) (if isList v then v else [v])
else k: v: [ (mkLine k v) ];
in attrs: concatStrings (concatLists (mapAttrsToList mkLines attrs));
toKeyValue =
{
mkKeyValue ? mkKeyValueDefault { } "=",
listsAsDuplicateKeys ? false,
indent ? "",
}:
let
mkLine = k: v: indent + mkKeyValue k v + "\n";
mkLines =
if listsAsDuplicateKeys then
k: v: map (mkLine k) (if isList v then v else [ v ])
else
k: v: [ (mkLine k v) ];
in
attrs: concatStrings (concatLists (mapAttrsToList mkLines attrs));
/**
Generate an INI-style config file from an
@@ -225,22 +241,27 @@ in rec {
:::
*/
toINI = {
mkSectionName ? (name: escape [ "[" "]" ] name),
mkKeyValue ? mkKeyValueDefault {} "=",
listsAsDuplicateKeys ? false
}: attrsOfAttrs:
toINI =
{
mkSectionName ? (name: escape [ "[" "]" ] name),
mkKeyValue ? mkKeyValueDefault { } "=",
listsAsDuplicateKeys ? false,
}:
attrsOfAttrs:
let
# map function to string for each key val
mapAttrsToStringsSep = sep: mapFn: attrs:
concatStringsSep sep
(mapAttrsToList mapFn attrs);
mkSection = sectName: sectValues: ''
# map function to string for each key val
mapAttrsToStringsSep =
sep: mapFn: attrs:
concatStringsSep sep (mapAttrsToList mapFn attrs);
mkSection =
sectName: sectValues:
''
[${mkSectionName sectName}]
'' + toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } sectValues;
''
+ toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } sectValues;
in
# map input to ini sections
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
# map input to ini sections
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
/**
Generate an INI-style config file from an attrset
@@ -303,15 +324,22 @@ in rec {
`generators.toINI` directly, which only takes
the part in `sections`.
*/
toINIWithGlobalSection = {
mkSectionName ? (name: escape [ "[" "]" ] name),
mkKeyValue ? mkKeyValueDefault {} "=",
listsAsDuplicateKeys ? false
}: { globalSection, sections ? {} }:
( if globalSection == {}
then ""
else (toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } globalSection)
+ "\n")
toINIWithGlobalSection =
{
mkSectionName ? (name: escape [ "[" "]" ] name),
mkKeyValue ? mkKeyValueDefault { } "=",
listsAsDuplicateKeys ? false,
}:
{
globalSection,
sections ? { },
}:
(
if globalSection == { } then
""
else
(toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } globalSection) + "\n"
)
+ (toINI { inherit mkSectionName mkKeyValue listsAsDuplicateKeys; } sections);
/**
@@ -349,50 +377,57 @@ in rec {
: Key-value pairs to be converted to a git-config file.
See: https://git-scm.com/docs/git-config#_variables for possible values.
*/
toGitINI = attrs:
toGitINI =
attrs:
let
mkSectionName = name:
mkSectionName =
name:
let
containsQuote = hasInfix ''"'' name;
sections = splitString "." name;
section = head sections;
subsections = tail sections;
subsection = concatStringsSep "." subsections;
in if containsQuote || subsections == [ ] then
name
else
''${section} "${subsection}"'';
in
if containsQuote || subsections == [ ] then name else ''${section} "${subsection}"'';
mkValueString = v:
mkValueString =
v:
let
escapedV = ''
"${
replaceStrings [ "\n" " " ''"'' "\\" ] [ "\\n" "\\t" ''\"'' "\\\\" ] v
}"'';
in mkValueStringDefault { } (if isString v then escapedV else v);
escapedV = ''"${replaceStrings [ "\n" " " ''"'' "\\" ] [ "\\n" "\\t" ''\"'' "\\\\" ] v}"'';
in
mkValueStringDefault { } (if isString v then escapedV else v);
# generation for multiple ini values
mkKeyValue = k: v:
let mkKeyValue = mkKeyValueDefault { inherit mkValueString; } " = " k;
in concatStringsSep "\n" (map (kv: "\t" + mkKeyValue kv) (toList v));
mkKeyValue =
k: v:
let
mkKeyValue = mkKeyValueDefault { inherit mkValueString; } " = " k;
in
concatStringsSep "\n" (map (kv: "\t" + mkKeyValue kv) (toList v));
# converts { a.b.c = 5; } to { "a.b".c = 5; } for toINI
gitFlattenAttrs = let
recurse = path: value:
if isAttrs value && !isDerivation value then
mapAttrsToList (name: value: recurse ([ name ] ++ path) value) value
else if length path > 1 then {
${concatStringsSep "." (reverseList (tail path))}.${head path} = value;
} else {
${head path} = value;
};
in attrs: foldl recursiveUpdate { } (flatten (recurse [ ] attrs));
gitFlattenAttrs =
let
recurse =
path: value:
if isAttrs value && !isDerivation value then
mapAttrsToList (name: value: recurse ([ name ] ++ path) value) value
else if length path > 1 then
{
${concatStringsSep "." (reverseList (tail path))}.${head path} = value;
}
else
{
${head path} = value;
};
in
attrs: foldl recursiveUpdate { } (flatten (recurse [ ] attrs));
toINI_ = toINI { inherit mkKeyValue mkSectionName; };
in
toINI_ (gitFlattenAttrs attrs);
toINI_ (gitFlattenAttrs attrs);
/**
mkKeyValueDefault wrapper that handles dconf INI quirks.
@@ -427,35 +462,39 @@ in rec {
withRecursion =
{
depthLimit,
throwOnDepthLimit ? true
throwOnDepthLimit ? true,
}:
assert isInt depthLimit;
let
specialAttrs = [
"__functor"
"__functionArgs"
"__toString"
"__pretty"
];
stepIntoAttr = evalNext: name:
if elem name specialAttrs
then id
else evalNext;
transform = depth:
if depthLimit != null && depth > depthLimit then
if throwOnDepthLimit
then throw "Exceeded maximum eval-depth limit of ${toString depthLimit} while trying to evaluate with `generators.withRecursion'!"
else const "<unevaluated>"
else id;
mapAny = depth: v:
let
evalNext = x: mapAny (depth + 1) (transform (depth + 1) x);
in
if isAttrs v then mapAttrs (stepIntoAttr evalNext) v
else if isList v then map evalNext v
else transform (depth + 1) v;
in
mapAny 0;
assert isInt depthLimit;
let
specialAttrs = [
"__functor"
"__functionArgs"
"__toString"
"__pretty"
];
stepIntoAttr = evalNext: name: if elem name specialAttrs then id else evalNext;
transform =
depth:
if depthLimit != null && depth > depthLimit then
if throwOnDepthLimit then
throw "Exceeded maximum eval-depth limit of ${toString depthLimit} while trying to evaluate with `generators.withRecursion'!"
else
const "<unevaluated>"
else
id;
mapAny =
depth: v:
let
evalNext = x: mapAny (depth + 1) (transform (depth + 1) x);
in
if isAttrs v then
mapAttrs (stepIntoAttr evalNext) v
else if isList v then
map evalNext v
else
transform (depth + 1) v;
in
mapAny 0;
/**
Pretty print a value, akin to `builtins.trace`.
@@ -481,68 +520,96 @@ in rec {
Value
: The value to be pretty printed
*/
toPretty = {
allowPrettyValues ? false,
multiline ? true,
indent ? ""
}:
toPretty =
{
allowPrettyValues ? false,
multiline ? true,
indent ? "",
}:
let
go = indent: v:
let introSpace = if multiline then "\n${indent} " else " ";
outroSpace = if multiline then "\n${indent}" else " ";
in if isInt v then toString v
# toString loses precision on floats, so we use toJSON instead. This isn't perfect
# as the resulting string may not parse back as a float (e.g. 42, 1e-06), but for
# pretty-printing purposes this is acceptable.
else if isFloat v then builtins.toJSON v
else if isString v then
let
lines = filter (v: ! isList v) (split "\n" v);
escapeSingleline = escape [ "\\" "\"" "\${" ];
escapeMultiline = replaceStrings [ "\${" "''" ] [ "''\${" "'''" ];
singlelineResult = "\"" + concatStringsSep "\\n" (map escapeSingleline lines) + "\"";
multilineResult = let
escapedLines = map escapeMultiline lines;
# The last line gets a special treatment: if it's empty, '' is on its own line at the "outer"
# indentation level. Otherwise, '' is appended to the last line.
lastLine = last escapedLines;
in "''" + introSpace + concatStringsSep introSpace (init escapedLines)
+ (if lastLine == "" then outroSpace else introSpace + lastLine) + "''";
in
if multiline && length lines > 1 then multilineResult else singlelineResult
else if true == v then "true"
else if false == v then "false"
else if null == v then "null"
else if isPath v then toString v
else if isList v then
if v == [] then "[ ]"
else "[" + introSpace
+ concatMapStringsSep introSpace (go (indent + " ")) v
+ outroSpace + "]"
else if isFunction v then
let fna = functionArgs v;
showFnas = concatStringsSep ", " (mapAttrsToList
(name: hasDefVal: if hasDefVal then name + "?" else name)
fna);
in if fna == {} then "<function>"
else "<function, args: {${showFnas}}>"
else if isAttrs v then
# apply pretty values if allowed
if allowPrettyValues && v ? __pretty && v ? val
then v.__pretty v.val
else if v == {} then "{ }"
else if v ? type && v.type == "derivation" then
"<derivation ${v.name or "???"}>"
else "{" + introSpace
+ concatStringsSep introSpace (mapAttrsToList
(name: value:
go =
indent: v:
let
introSpace = if multiline then "\n${indent} " else " ";
outroSpace = if multiline then "\n${indent}" else " ";
in
if isInt v then
toString v
# toString loses precision on floats, so we use toJSON instead. This isn't perfect
# as the resulting string may not parse back as a float (e.g. 42, 1e-06), but for
# pretty-printing purposes this is acceptable.
else if isFloat v then
builtins.toJSON v
else if isString v then
let
lines = filter (v: !isList v) (split "\n" v);
escapeSingleline = escape [
"\\"
"\""
"\${"
];
escapeMultiline = replaceStrings [ "\${" "''" ] [ "''\${" "'''" ];
singlelineResult = "\"" + concatStringsSep "\\n" (map escapeSingleline lines) + "\"";
multilineResult =
let
escapedLines = map escapeMultiline lines;
# The last line gets a special treatment: if it's empty, '' is on its own line at the "outer"
# indentation level. Otherwise, '' is appended to the last line.
lastLine = last escapedLines;
in
"''"
+ introSpace
+ concatStringsSep introSpace (init escapedLines)
+ (if lastLine == "" then outroSpace else introSpace + lastLine)
+ "''";
in
if multiline && length lines > 1 then multilineResult else singlelineResult
else if true == v then
"true"
else if false == v then
"false"
else if null == v then
"null"
else if isPath v then
toString v
else if isList v then
if v == [ ] then
"[ ]"
else
"[" + introSpace + concatMapStringsSep introSpace (go (indent + " ")) v + outroSpace + "]"
else if isFunction v then
let
fna = functionArgs v;
showFnas = concatStringsSep ", " (
mapAttrsToList (name: hasDefVal: if hasDefVal then name + "?" else name) fna
);
in
if fna == { } then "<function>" else "<function, args: {${showFnas}}>"
else if isAttrs v then
# apply pretty values if allowed
if allowPrettyValues && v ? __pretty && v ? val then
v.__pretty v.val
else if v == { } then
"{ }"
else if v ? type && v.type == "derivation" then
"<derivation ${v.name or "???"}>"
else
"{"
+ introSpace
+ concatStringsSep introSpace (
mapAttrsToList (
name: value:
"${escapeNixIdentifier name} = ${
addErrorContext "while evaluating an attribute `${name}`"
(go (indent + " ") value)
};") v)
+ outroSpace + "}"
else abort "generators.toPretty: should never happen (v = ${v})";
in go indent;
addErrorContext "while evaluating an attribute `${name}`" (go (indent + " ") value)
};"
) v
)
+ outroSpace
+ "}"
else
abort "generators.toPretty: should never happen (v = ${v})";
in
go indent;
/**
Translate a simple Nix expression to [Plist notation](https://en.wikipedia.org/wiki/Property_list).
@@ -557,61 +624,90 @@ in rec {
Value
: The value to be converted to Plist
*/
toPlist = {
escape ? false
}: v: let
expr = ind: x:
if x == null then "" else
if isBool x then bool ind x else
if isInt x then int ind x else
if isString x then str ind x else
if isList x then list ind x else
if isAttrs x then attrs ind x else
if isPath x then str ind (toString x) else
if isFloat x then float ind x else
abort "generators.toPlist: should never happen (v = ${v})";
toPlist =
{
escape ? false,
}:
v:
let
expr =
ind: x:
if x == null then
""
else if isBool x then
bool ind x
else if isInt x then
int ind x
else if isString x then
str ind x
else if isList x then
list ind x
else if isAttrs x then
attrs ind x
else if isPath x then
str ind (toString x)
else if isFloat x then
float ind x
else
abort "generators.toPlist: should never happen (v = ${v})";
literal = ind: x: ind + x;
literal = ind: x: ind + x;
maybeEscapeXML = if escape then escapeXML else x: x;
maybeEscapeXML = if escape then escapeXML else x: x;
bool = ind: x: literal ind (if x then "<true/>" else "<false/>");
int = ind: x: literal ind "<integer>${toString x}</integer>";
str = ind: x: literal ind "<string>${maybeEscapeXML x}</string>";
key = ind: x: literal ind "<key>${maybeEscapeXML x}</key>";
float = ind: x: literal ind "<real>${toString x}</real>";
bool = ind: x: literal ind (if x then "<true/>" else "<false/>");
int = ind: x: literal ind "<integer>${toString x}</integer>";
str = ind: x: literal ind "<string>${maybeEscapeXML x}</string>";
key = ind: x: literal ind "<key>${maybeEscapeXML x}</key>";
float = ind: x: literal ind "<real>${toString x}</real>";
indent = ind: expr "\t${ind}";
indent = ind: expr "\t${ind}";
item = ind: concatMapStringsSep "\n" (indent ind);
item = ind: concatMapStringsSep "\n" (indent ind);
list = ind: x: concatStringsSep "\n" [
(literal ind "<array>")
(item ind x)
(literal ind "</array>")
];
list =
ind: x:
concatStringsSep "\n" [
(literal ind "<array>")
(item ind x)
(literal ind "</array>")
];
attrs = ind: x: concatStringsSep "\n" [
(literal ind "<dict>")
(attr ind x)
(literal ind "</dict>")
];
attrs =
ind: x:
concatStringsSep "\n" [
(literal ind "<dict>")
(attr ind x)
(literal ind "</dict>")
];
attr = let attrFilter = name: value: name != "_module" && value != null;
in ind: x: concatStringsSep "\n" (flatten (mapAttrsToList
(name: value: optionals (attrFilter name value) [
(key "\t${ind}" name)
(expr "\t${ind}" value)
]) x));
attr =
let
attrFilter = name: value: name != "_module" && value != null;
in
ind: x:
concatStringsSep "\n" (
flatten (
mapAttrsToList (
name: value:
optionals (attrFilter name value) [
(key "\t${ind}" name)
(expr "\t${ind}" value)
]
) x
)
);
in
# TODO: As discussed in #356502, deprecated functionality should be removed sometime after 25.11.
lib.warnIf (!escape && lib.oldestSupportedReleaseIsAtLeast 2505) "Using `lib.generators.toPlist` without `escape = true` is deprecated" ''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
${expr "" v}
</plist>'';
in
# TODO: As discussed in #356502, deprecated functionality should be removed sometime after 25.11.
lib.warnIf (!escape && lib.oldestSupportedReleaseIsAtLeast 2505)
"Using `lib.generators.toPlist` without `escape = true` is deprecated"
''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
${expr "" v}
</plist>'';
/**
Translate a simple Nix expression to Dhall notation.
@@ -629,13 +725,14 @@ in rec {
: The value to be converted to Dhall
*/
toDhall = { }@args: v:
let concatItems = concatStringsSep ", ";
in if isAttrs v then
"{ ${
concatItems (mapAttrsToList
(key: value: "${key} = ${toDhall args value}") v)
} }"
toDhall =
{ }@args:
v:
let
concatItems = concatStringsSep ", ";
in
if isAttrs v then
"{ ${concatItems (mapAttrsToList (key: value: "${key} = ${toDhall args value}") v)} }"
else if isList v then
"[ ${concatItems (map (toDhall args) v)} ]"
else if isInt v then
@@ -663,7 +760,6 @@ in rec {
Regardless of multiline parameter there is no trailing newline.
# Inputs
Structured function argument
@@ -711,11 +807,13 @@ in rec {
:::
*/
toLua = {
multiline ? true,
indent ? "",
asBindings ? false,
}@args: v:
toLua =
{
multiline ? true,
indent ? "",
asBindings ? false,
}@args:
v:
let
innerIndent = "${indent} ";
introSpace = if multiline then "\n${innerIndent}" else " ";
@@ -725,13 +823,16 @@ in rec {
asBindings = false;
};
concatItems = concatStringsSep ",${introSpace}";
isLuaInline = { _type ? null, ... }: _type == "lua-inline";
isLuaInline =
{
_type ? null,
...
}:
_type == "lua-inline";
generatedBindings =
assert assertMsg (badVarNames == []) "Bad Lua var names: ${toPretty {} badVarNames}";
concatStrings (
mapAttrsToList (key: value: "${indent}${key} = ${toLua innerArgs value}\n") v
);
assert assertMsg (badVarNames == [ ]) "Bad Lua var names: ${toPretty { } badVarNames}";
concatStrings (mapAttrsToList (key: value: "${indent}${key} = ${toLua innerArgs value}\n") v);
# https://en.wikibooks.org/wiki/Lua_Programming/variable#Variable_names
matchVarName = match "[[:alpha:]_][[:alnum:]_]*(\\.[[:alpha:]_][[:alnum:]_]*)*";
@@ -746,8 +847,12 @@ in rec {
else if isPath v || isDerivation v then
toJSON "${v}"
else if isList v then
(if v == [ ] then "{}" else
"{${introSpace}${concatItems (map (value: "${toLua innerArgs value}") v)}${outroSpace}}")
(
if v == [ ] then
"{}"
else
"{${introSpace}${concatItems (map (value: "${toLua innerArgs value}") v)}${outroSpace}}"
)
else if isAttrs v then
(
if isLuaInline v then
@@ -755,9 +860,9 @@ in rec {
else if v == { } then
"{}"
else
"{${introSpace}${concatItems (
mapAttrsToList (key: value: "[${toJSON key}] = ${toLua innerArgs value}") v
)}${outroSpace}}"
"{${introSpace}${
concatItems (mapAttrsToList (key: value: "[${toJSON key}] = ${toLua innerArgs value}") v)
}${outroSpace}}"
)
else
abort "generators.toLua: type ${typeOf v} is unsupported";
@@ -765,7 +870,6 @@ in rec {
/**
Mark string as Lua expression to be inlined when processed by toLua.
# Inputs
`expr`
@@ -778,8 +882,12 @@ in rec {
mkLuaInline :: String -> AttrSet
```
*/
mkLuaInline = expr: { _type = "lua-inline"; inherit expr; };
} // {
mkLuaInline = expr: {
_type = "lua-inline";
inherit expr;
};
}
// {
/**
Generates JSON from an arbitrary (non-function) value.
For more information see the documentation of the builtin.
@@ -794,7 +902,7 @@ in rec {
: The value to be converted to JSON
*/
toJSON = {}: lib.strings.toJSON;
toJSON = { }: lib.strings.toJSON;
/**
YAML has been a strict superset of JSON since 1.2, so we
@@ -812,5 +920,5 @@ in rec {
: The value to be converted to YAML
*/
toYAML = {}: lib.strings.toJSON;
toYAML = { }: lib.strings.toJSON;
}