mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
lib.generators.toGitINI: performance improvements (#522818)
This commit is contained in:
@@ -23,9 +23,12 @@
|
||||
let
|
||||
inherit (lib)
|
||||
addErrorContext
|
||||
any
|
||||
assertMsg
|
||||
attrNames
|
||||
attrValues
|
||||
concatLists
|
||||
concatMap
|
||||
concatMapStringsSep
|
||||
concatStrings
|
||||
concatStringsSep
|
||||
@@ -52,6 +55,7 @@ let
|
||||
isString
|
||||
last
|
||||
length
|
||||
genAttrs
|
||||
mapAttrs
|
||||
mapAttrsToList
|
||||
optionals
|
||||
@@ -379,55 +383,69 @@ rec {
|
||||
See the [git-config documentation](https://git-scm.com/docs/git-config#_variables) for possible values.
|
||||
*/
|
||||
toGitINI =
|
||||
attrs:
|
||||
let
|
||||
mkSectionName =
|
||||
let
|
||||
containsQuote = hasInfix ''"'';
|
||||
in
|
||||
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}"'';
|
||||
if containsQuote name || length sections == 1 then
|
||||
name
|
||||
else
|
||||
''${head sections} "${concatStringsSep "." (tail sections)}"'';
|
||||
|
||||
mkValueString =
|
||||
v:
|
||||
let
|
||||
escapedV = ''"${replaceStrings [ "\n" " " ''"'' "\\" ] [ "\\n" "\\t" ''\"'' "\\\\" ] v}"'';
|
||||
escape = replaceStrings [ "\n" " " ''"'' "\\" ] [ "\\n" "\\t" ''\"'' "\\\\" ];
|
||||
in
|
||||
mkValueStringDefault { } (if isString v then escapedV else v);
|
||||
v: mkValueStringDefault { } (if isString v then ''"${escape v}"'' else v);
|
||||
|
||||
# generation for multiple ini values
|
||||
mkKeyValue =
|
||||
k: v:
|
||||
let
|
||||
mkKeyValue = mkKeyValueDefault { inherit mkValueString; } " = " k;
|
||||
mkKeyValue = mkKeyValueDefault { inherit mkValueString; } " = ";
|
||||
attrToString = k: v: "\t" + mkKeyValue k v;
|
||||
in
|
||||
concatStringsSep "\n" (map (kv: "\t" + mkKeyValue kv) (toList v));
|
||||
k: v: if isList v then concatStringsSep "\n" (map (attrToString k) v) else attrToString k v;
|
||||
|
||||
# converts { a.b.c = 5; } to { "a.b".c = 5; } for toINI
|
||||
gitFlattenAttrs =
|
||||
let
|
||||
isNonDrvAttrs = value: isAttrs value && !isDerivation value;
|
||||
recurse =
|
||||
path: value:
|
||||
if isAttrs value && !isDerivation value then
|
||||
mapAttrsToList (name: value: recurse ([ name ] ++ path) value) value
|
||||
if isNonDrvAttrs value then
|
||||
concatMap (name: recurse ([ name ] ++ path) value.${name}) (attrNames value)
|
||||
else if length path > 1 then
|
||||
{
|
||||
${concatStringsSep "." (reverseList (tail path))}.${head path} = value;
|
||||
}
|
||||
[
|
||||
{
|
||||
${concatStringsSep "." (reverseList (tail path))}.${head path} = value;
|
||||
}
|
||||
]
|
||||
else
|
||||
{
|
||||
${head path} = value;
|
||||
};
|
||||
[
|
||||
{
|
||||
${head path} = value;
|
||||
}
|
||||
];
|
||||
in
|
||||
attrs: foldl recursiveUpdate { } (flatten (recurse [ ] attrs));
|
||||
attrs:
|
||||
let
|
||||
# Filter the names for any that contain nested attrsets. attrs that
|
||||
# don't contain nested attrsets can stay the same =
|
||||
namesToRewrite = filter (
|
||||
name: isAttrs attrs.${name} && any isNonDrvAttrs (attrValues attrs.${name})
|
||||
) (attrNames attrs);
|
||||
attrsToRewrite = genAttrs namesToRewrite (name: attrs.${name});
|
||||
in
|
||||
removeAttrs attrs namesToRewrite // foldl recursiveUpdate { } (recurse [ ] attrsToRewrite);
|
||||
|
||||
toINI_ = toINI { inherit mkKeyValue mkSectionName; };
|
||||
in
|
||||
toINI_ (gitFlattenAttrs attrs);
|
||||
attrs: toINI_ (gitFlattenAttrs attrs);
|
||||
|
||||
/**
|
||||
`mkKeyValueDefault` wrapper that handles dconf INI quirks.
|
||||
|
||||
Reference in New Issue
Block a user