{ config, lib, pkgs, ... }: with lib; let cfg = config.programs.git; signModule = types.submodule { options = { key = mkOption { type = types.str; description = "The default GPG signing key fingerprint."; }; signByDefault = mkOption { type = types.bool; default = false; description = "Whether commits should be signed by default."; }; gpgPath = mkOption { type = types.str; default = "${pkgs.gnupg}/bin/gpg2"; defaultText = "\${pkgs.gnupg}/bin/gpg2"; description = "Path to GnuPG binary to use."; }; }; }; in { options = { programs.git = { enable = mkEnableOption "Git"; package = mkOption { type = types.package; default = pkgs.git; defaultText = "pkgs.git"; description = "Git package to install."; }; userName = mkOption { type = types.str; description = "Default user name to use."; }; userEmail = mkOption { type = types.str; description = "Default user email to use."; }; aliases = mkOption { type = types.attrs; default = {}; description = "Git aliases to define."; }; signing = mkOption { type = types.nullOr signModule; default = null; description = "Options related to signing commits using GnuPG."; }; extraConfig = mkOption { type = types.lines; default = ""; description = "Additional configuration to add."; }; }; }; config = mkIf cfg.enable ( let ini = { user = { name = cfg.userName; email = cfg.userEmail; } // optionalAttrs (cfg.signing != null) { signingKey = cfg.signing.key; }; } // optionalAttrs (cfg.signing != null) { commit.gpgSign = cfg.signing.signByDefault; gpg.program = cfg.signing.gpgPath; } // optionalAttrs (cfg.aliases != {}) { alias = cfg.aliases; }; in { home.packages = [ cfg.package ]; home.file.".gitconfig".text = generators.toINI {} ini + "\n" + cfg.extraConfig; } ); }