about summary refs log tree commit diff
path: root/modules/git/default.nix
blob: 65aefb455f89ffc2bff67dfb2e5857e554ed598f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{ config, lib, pkgs, ... }:

with lib;

let
  genConf = attrs: let
    escStr = s: "\"${escape [ "\"" "\\" ] s}\"";
    mkVal = v: if isBool v && v  then "true"
          else if isBool v && !v then "false"
          else escStr (toString v);
    mkLine = key: val: "${key} = ${mkVal val}";

    filterNull = filterAttrs (_: v: !(isNull v));

    mkSection = sect: subsect: vals: ''
      [${sect}${optionalString (subsect != null) " ${escStr subsect}"}]
      ${concatStringsSep "\n" (mapAttrsToList mkLine (filterNull vals))}
    '';

    mkConf = sect: content: let
      subs = filterAttrs (_: isAttrs) content;
      nonSubs = filterAttrs (_: s: !isAttrs s) content;
      hasPlain = (attrNames nonSubs) != [];
      plainSects = singleton (mkSection sect null nonSubs);
    in mapAttrsToList (mkSection sect) subs ++ optional hasPlain plainSects;

    text = concatStringsSep "\n" (flatten (mapAttrsToList mkConf attrs));
  in pkgs.writeText "gitconfig" text;

  gitPatched = overrideDerivation pkgs.gitFull (git: {
    makeFlags = let
      oldFlags = git.makeFlags or [];
      newVal = "ETC_GITCONFIG=${config.vuizvui.git.config}";
    in if isList oldFlags
       then oldFlags ++ [ newVal ]
       else "${oldFlags} ${newVal}";
  });
in {
  options.vuizvui.git = {
    enable = mkEnableOption "Git";

    config = mkOption {
      description = "System-wide default config for Git";

      type = let
        superType = types.attrsOf types.unspecified;
      in mkOptionType {
        name = "attribute set of either plain values or "
             + "attribute sets of values (if it is a subsection)";
        inherit (superType) check merge;
        inherit (superType) getSubOptions getSubModules substSubModules;
      };

      default = {};
      example = {
        color.ui = "auto";
        merge.tool = "vimdiff";
        guitool.foobar.noconsole = true;
      };

      apply = genConf;
    };
  };

  config = mkIf config.vuizvui.git.enable {
    environment.systemPackages = [
      gitPatched
      pkgs.gitAndTools.git-remote-hg
      pkgs.gitAndTools.hub
    ];
  };
}