git: support nested section options

Closes #614
This commit is contained in:
arcnmx 2019-03-12 16:06:36 -07:00 committed by Robert Helgesson
parent 472d7731d6
commit 95382060eb
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
3 changed files with 58 additions and 14 deletions

View file

@ -6,6 +6,19 @@ let
cfg = config.programs.git;
# create [section "subsection"] keys from "section.subsection" attrset names
mkSectionName = name:
let
containsQuote = strings.hasInfix ''"'' name;
sections = splitString "." name;
section = head sections;
subsections = tail sections;
subsection = concatStringsSep "." subsections;
in
if containsQuote || subsections == []
then name
else "${section} \"${subsection}\"";
# generation for multiple ini values
mkKeyValue = k: v:
let
@ -13,15 +26,33 @@ let
in
concatStringsSep "\n" (map mkKeyValue (toList v));
gitToIni = generators.toINI { inherit mkKeyValue; };
# converts { a.b.c = 5; } to { "a.b".c = 5; } for toINI
gitFlattenAttrs =
let
recurse = path: value:
if isAttrs 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));
gitToIni = attrs:
let
toIni = generators.toINI { inherit mkKeyValue mkSectionName; };
in
toIni (gitFlattenAttrs attrs);
gitIniType = with types;
let
primitiveType = either str (either bool int);
multipleType = either primitiveType (listOf primitiveType);
sectionType = attrsOf multipleType;
supersectionType = attrsOf (either multipleType sectionType);
in
attrsOf sectionType;
attrsOf supersectionType;
signModule = types.submodule {
options = {
@ -128,6 +159,7 @@ in
default = {};
example = {
core = { whitespace = "trailing-space,space-before-tab"; };
url."ssh://git@host".insteadOf = "otherhost";
};
description = "Additional configuration to add.";
};
@ -200,7 +232,7 @@ in
hasSmtp = name: account: account.smtp != null;
genIdentity = name: account: with account;
nameValuePair "sendemail \"${name}\"" ({
nameValuePair "sendemail.${name}" ({
smtpEncryption = if smtp.tls.enable then "tls" else "";
smtpServer = smtp.host;
smtpUser = userName;
@ -235,19 +267,23 @@ in
})
(mkIf (cfg.includes != []) {
xdg.configFile."git/config".text = mkAfter
(concatMapStringsSep "\n"
(i: with i; ''
[${if (condition == null) then "include" else "includeIf \"${condition}\""}]
path = ${path}
'')
cfg.includes);
xdg.configFile."git/config".text =
let
include = i: with i;
if condition != null
then { includeIf.${condition}.path = "${path}"; }
else { include.path = "${path}"; };
in
mkAfter
(concatStringsSep "\n"
(map gitToIni
(map include cfg.includes)));
})
(mkIf cfg.lfs.enable {
home.packages = [ pkgs.git-lfs ];
programs.git.iniContent."filter \"lfs\"" =
programs.git.iniContent.filter.lfs =
let
skipArg = optional cfg.lfs.skipSmudge "--skip";
in

View file

@ -12,6 +12,12 @@ multiple=1
multiple=2
name=value
[extra "backcompat.with.dots"]
previously=worked
[extra "subsection"]
value=test
[filter "lfs"]
clean=git-lfs clean -- %f
process=git-lfs filter-process
@ -27,10 +33,10 @@ name=John Doe
signingKey=00112233445566778899AABBCCDDEEFF
[include]
path = ~/path/to/config.inc
path=~/path/to/config.inc
[includeIf "gitdir:~/src/dir"]
path = ~/path/to/conditional.inc
path=~/path/to/conditional.inc
[includeIf "gitdir:~/src/dir"]
path = @git_include_path@
path=@git_include_path@

View file

@ -58,9 +58,11 @@ in
{
aliases.a2 = mkForce "baz";
extraConfig."extra \"backcompat.with.dots\"".previously = "worked";
extraConfig.extra.boolean = true;
extraConfig.extra.integer = 38;
extraConfig.extra.multiple = [2];
extraConfig.extra.subsection.value = "test";
}
];