mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 11:36:05 +01:00
Allow a user to disable an email account by setting `accounts.email.accounts.<name>.enable = false`. This is useful if someone wants to configure email accounts globally but only use them in certain circumstances. Everywhere email account configuration is used, check if the account is enabled before checking any attributes of the account.
936 lines
27 KiB
Nix
936 lines
27 KiB
Nix
{
|
||
config,
|
||
lib,
|
||
pkgs,
|
||
...
|
||
}:
|
||
let
|
||
inherit (lib)
|
||
concatStringsSep
|
||
literalExpression
|
||
mkDefault
|
||
mkEnableOption
|
||
mkIf
|
||
mkOption
|
||
mkOptionDefault
|
||
mkPackageOption
|
||
types
|
||
;
|
||
|
||
cfg = config.programs.git;
|
||
|
||
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 supersectionType;
|
||
|
||
includeModule = types.submodule (
|
||
{ config, ... }:
|
||
{
|
||
options = {
|
||
condition = mkOption {
|
||
type = types.nullOr types.str;
|
||
default = null;
|
||
description = ''
|
||
Include this configuration only when {var}`condition`
|
||
matches. Allowed conditions are described in
|
||
{manpage}`git-config(1)`.
|
||
'';
|
||
};
|
||
|
||
path = mkOption {
|
||
type = with types; either str path;
|
||
description = "Path of the configuration file to include.";
|
||
};
|
||
|
||
contents = mkOption {
|
||
type = types.attrsOf types.anything;
|
||
default = { };
|
||
example = literalExpression ''
|
||
{
|
||
user = {
|
||
email = "bob@work.example.com";
|
||
name = "Bob Work";
|
||
signingKey = "1A2B3C4D5E6F7G8H";
|
||
};
|
||
commit = {
|
||
gpgSign = true;
|
||
};
|
||
};
|
||
'';
|
||
description = ''
|
||
Configuration to include. If empty then a path must be given.
|
||
|
||
This follows the configuration structure as described in
|
||
{manpage}`git-config(1)`.
|
||
'';
|
||
};
|
||
|
||
contentSuffix = mkOption {
|
||
type = types.str;
|
||
default = "gitconfig";
|
||
description = ''
|
||
Nix store name for the git configuration text file,
|
||
when generating the configuration text from nix options.
|
||
'';
|
||
|
||
};
|
||
};
|
||
config.path = mkIf (config.contents != { }) (
|
||
mkDefault (
|
||
pkgs.writeText (lib.hm.strings.storeFileName config.contentSuffix) (
|
||
lib.generators.toGitINI config.contents
|
||
)
|
||
)
|
||
);
|
||
}
|
||
);
|
||
|
||
in
|
||
{
|
||
meta.maintainers = with lib.maintainers; [
|
||
khaneliman
|
||
rycee
|
||
];
|
||
|
||
options = {
|
||
programs.git = {
|
||
enable = mkEnableOption "Git";
|
||
|
||
package = lib.mkPackageOption pkgs "git" {
|
||
example = "pkgs.gitFull";
|
||
extraDescription = ''
|
||
Use {var}`pkgs.gitFull`
|
||
to gain access to {command}`git send-email` for instance.
|
||
'';
|
||
};
|
||
|
||
userName = mkOption {
|
||
type = types.nullOr types.str;
|
||
default = null;
|
||
description = "Default user name to use.";
|
||
};
|
||
|
||
userEmail = mkOption {
|
||
type = types.nullOr types.str;
|
||
default = null;
|
||
description = "Default user email to use.";
|
||
};
|
||
|
||
aliases = mkOption {
|
||
type = types.attrsOf types.str;
|
||
default = { };
|
||
example = {
|
||
co = "checkout";
|
||
};
|
||
description = "Git aliases to define.";
|
||
};
|
||
|
||
signing = {
|
||
key = mkOption {
|
||
type = types.nullOr types.str;
|
||
default = null;
|
||
description = ''
|
||
The default signing key fingerprint.
|
||
|
||
Set to `null` to let the signer decide what signing key
|
||
to use depending on commit’s author.
|
||
'';
|
||
};
|
||
|
||
format = mkOption {
|
||
type = types.nullOr (
|
||
types.enum [
|
||
"openpgp"
|
||
"ssh"
|
||
"x509"
|
||
]
|
||
);
|
||
defaultText = literalExpression ''
|
||
"openpgp" for state version < 25.05,
|
||
undefined for state version ≥ 25.05
|
||
'';
|
||
description = ''
|
||
The signing method to use when signing commits and tags.
|
||
Valid values are `openpgp` (OpenPGP/GnuPG), `ssh` (SSH), and `x509` (X.509 certificates).
|
||
'';
|
||
};
|
||
|
||
signByDefault = mkOption {
|
||
type = types.nullOr types.bool;
|
||
default = null;
|
||
description = "Whether commits and tags should be signed by default.";
|
||
};
|
||
|
||
signer = mkOption {
|
||
type = types.nullOr types.str;
|
||
description = "Path to signer binary to use.";
|
||
};
|
||
};
|
||
|
||
extraConfig = mkOption {
|
||
type = types.either types.lines gitIniType;
|
||
default = { };
|
||
example = {
|
||
core = {
|
||
whitespace = "trailing-space,space-before-tab";
|
||
};
|
||
url."ssh://git@host".insteadOf = "otherhost";
|
||
};
|
||
description = ''
|
||
Additional configuration to add. The use of string values is
|
||
deprecated and will be removed in the future.
|
||
'';
|
||
};
|
||
|
||
hooks = mkOption {
|
||
type = types.attrsOf types.path;
|
||
default = { };
|
||
example = literalExpression ''
|
||
{
|
||
pre-commit = ./pre-commit-script;
|
||
}
|
||
'';
|
||
description = ''
|
||
Configuration helper for Git hooks.
|
||
See <https://git-scm.com/docs/githooks>
|
||
for reference.
|
||
'';
|
||
};
|
||
|
||
iniContent = mkOption {
|
||
type = gitIniType;
|
||
internal = true;
|
||
};
|
||
|
||
ignores = mkOption {
|
||
type = types.listOf types.str;
|
||
default = [ ];
|
||
example = [
|
||
"*~"
|
||
"*.swp"
|
||
];
|
||
description = "List of paths that should be globally ignored.";
|
||
};
|
||
|
||
attributes = mkOption {
|
||
type = types.listOf types.str;
|
||
default = [ ];
|
||
example = [ "*.pdf diff=pdf" ];
|
||
description = "List of defining attributes set globally.";
|
||
};
|
||
|
||
includes = mkOption {
|
||
type = types.listOf includeModule;
|
||
default = [ ];
|
||
example = literalExpression ''
|
||
[
|
||
{ path = "~/path/to/config.inc"; }
|
||
{
|
||
path = "~/path/to/conditional.inc";
|
||
condition = "gitdir:~/src/dir";
|
||
}
|
||
]
|
||
'';
|
||
description = "List of configuration files to include.";
|
||
};
|
||
|
||
lfs = {
|
||
enable = mkEnableOption "Git Large File Storage";
|
||
|
||
skipSmudge = mkOption {
|
||
type = types.bool;
|
||
default = false;
|
||
description = ''
|
||
Skip automatic downloading of objects on clone or pull.
|
||
This requires a manual {command}`git lfs pull`
|
||
every time a new commit is checked out on your repository.
|
||
'';
|
||
};
|
||
};
|
||
|
||
maintenance = {
|
||
enable = mkEnableOption "" // {
|
||
description = ''
|
||
Enable the automatic {command}`git maintenance`.
|
||
|
||
If you have SSH remotes, set {option}`programs.git.package` to a
|
||
git version with SSH support (eg: `pkgs.gitFull`).
|
||
|
||
See <https://git-scm.com/docs/git-maintenance>.
|
||
'';
|
||
};
|
||
|
||
repositories = mkOption {
|
||
type = with types; listOf str;
|
||
default = [ ];
|
||
description = ''
|
||
Repositories on which {command}`git maintenance` should run.
|
||
|
||
Should be a list of absolute paths.
|
||
'';
|
||
};
|
||
|
||
timers = mkOption {
|
||
type = types.attrsOf types.str;
|
||
default = {
|
||
hourly = "*-*-* 1..23:53:00";
|
||
daily = "Tue..Sun *-*-* 0:53:00";
|
||
weekly = "Mon 0:53:00";
|
||
};
|
||
description = ''
|
||
Systemd timers to create for scheduled {command}`git maintenance`.
|
||
|
||
Key is passed to `--schedule` argument in {command}`git maintenance run`
|
||
and value is passed to `Timer.OnCalendar` in `systemd.user.timers`.
|
||
'';
|
||
};
|
||
};
|
||
|
||
diff-highlight = {
|
||
enable = mkEnableOption "" // {
|
||
description = ''
|
||
Enable the contrib {command}`diff-highlight` syntax highlighter.
|
||
See <https://github.com/git/git/blob/master/contrib/diff-highlight/README>,
|
||
'';
|
||
};
|
||
|
||
pagerOpts = mkOption {
|
||
type = types.listOf types.str;
|
||
default = [ ];
|
||
example = [
|
||
"--tabs=4"
|
||
"-RFX"
|
||
];
|
||
description = ''
|
||
Arguments to be passed to {command}`less`.
|
||
'';
|
||
};
|
||
};
|
||
|
||
difftastic = {
|
||
enable = mkEnableOption "" // {
|
||
description = ''
|
||
Enable the {command}`difftastic` syntax highlighter.
|
||
See <https://github.com/Wilfred/difftastic>.
|
||
'';
|
||
};
|
||
|
||
package = mkPackageOption pkgs "difftastic" { };
|
||
|
||
enableAsDifftool = mkEnableOption "" // {
|
||
description = ''
|
||
Enable the {command}`difftastic` syntax highlighter as a git difftool.
|
||
See <https://github.com/Wilfred/difftastic>.
|
||
'';
|
||
};
|
||
|
||
background = mkOption {
|
||
type = types.enum [
|
||
"light"
|
||
"dark"
|
||
];
|
||
default = "light";
|
||
example = "dark";
|
||
description = ''
|
||
Determines whether difftastic should use the lighter or darker colors
|
||
for syntax highlighting.
|
||
'';
|
||
};
|
||
|
||
color = mkOption {
|
||
type = types.enum [
|
||
"always"
|
||
"auto"
|
||
"never"
|
||
];
|
||
default = "auto";
|
||
example = "always";
|
||
description = ''
|
||
Determines when difftastic should color its output.
|
||
'';
|
||
};
|
||
|
||
display = mkOption {
|
||
type = types.enum [
|
||
"side-by-side"
|
||
"side-by-side-show-both"
|
||
"inline"
|
||
];
|
||
default = "side-by-side";
|
||
example = "inline";
|
||
description = ''
|
||
Determines how the output displays - in one column or two columns.
|
||
'';
|
||
};
|
||
};
|
||
|
||
delta = {
|
||
enable = mkEnableOption "" // {
|
||
description = ''
|
||
Whether to enable the {command}`delta` syntax highlighter.
|
||
See <https://github.com/dandavison/delta>.
|
||
'';
|
||
};
|
||
|
||
package = mkPackageOption pkgs "delta" { };
|
||
|
||
options = mkOption {
|
||
type =
|
||
with types;
|
||
let
|
||
primitiveType = either str (either bool int);
|
||
sectionType = attrsOf primitiveType;
|
||
in
|
||
attrsOf (either primitiveType sectionType);
|
||
default = { };
|
||
example = {
|
||
features = "decorations";
|
||
whitespace-error-style = "22 reverse";
|
||
decorations = {
|
||
commit-decoration-style = "bold yellow box ul";
|
||
file-style = "bold yellow ul";
|
||
file-decoration-style = "none";
|
||
};
|
||
};
|
||
description = ''
|
||
Options to configure delta.
|
||
'';
|
||
};
|
||
};
|
||
|
||
diff-so-fancy = {
|
||
enable = mkEnableOption "" // {
|
||
description = ''
|
||
Enable the {command}`diff-so-fancy` diff colorizer.
|
||
See <https://github.com/so-fancy/diff-so-fancy>.
|
||
'';
|
||
};
|
||
|
||
pagerOpts = mkOption {
|
||
type = types.listOf types.str;
|
||
default = [
|
||
"--tabs=4"
|
||
"-RFX"
|
||
];
|
||
description = ''
|
||
Arguments to be passed to {command}`less`.
|
||
'';
|
||
};
|
||
|
||
markEmptyLines = mkOption {
|
||
type = types.bool;
|
||
default = true;
|
||
example = false;
|
||
description = ''
|
||
Whether the first block of an empty line should be colored.
|
||
'';
|
||
};
|
||
|
||
changeHunkIndicators = mkOption {
|
||
type = types.bool;
|
||
default = true;
|
||
example = false;
|
||
description = ''
|
||
Simplify git header chunks to a more human readable format.
|
||
'';
|
||
};
|
||
|
||
stripLeadingSymbols = mkOption {
|
||
type = types.bool;
|
||
default = true;
|
||
example = false;
|
||
description = ''
|
||
Whether the `+` or `-` at
|
||
line-start should be removed.
|
||
'';
|
||
};
|
||
|
||
useUnicodeRuler = mkOption {
|
||
type = types.bool;
|
||
default = true;
|
||
example = false;
|
||
description = ''
|
||
By default, the separator for the file header uses Unicode
|
||
line-drawing characters. If this is causing output errors on
|
||
your terminal, set this to false to use ASCII characters instead.
|
||
'';
|
||
};
|
||
|
||
rulerWidth = mkOption {
|
||
type = types.nullOr types.int;
|
||
default = null;
|
||
example = false;
|
||
description = ''
|
||
By default, the separator for the file header spans the full
|
||
width of the terminal. Use this setting to set the width of
|
||
the file header manually.
|
||
'';
|
||
};
|
||
};
|
||
|
||
riff = {
|
||
enable = mkEnableOption "" // {
|
||
description = ''
|
||
Enable the <command>riff</command> diff highlighter.
|
||
See <link xlink:href="https://github.com/walles/riff" />.
|
||
'';
|
||
};
|
||
|
||
package = mkPackageOption pkgs "riffdiff" { };
|
||
|
||
commandLineOptions = mkOption {
|
||
type = types.listOf types.str;
|
||
default = [ ];
|
||
example = literalExpression ''[ "--no-adds-only-special" ]'';
|
||
apply = lib.concatStringsSep " ";
|
||
description = ''
|
||
Command line arguments to include in the <command>RIFF</command> environment variable.
|
||
|
||
Run <command>riff --help</command> for a full list of options
|
||
'';
|
||
};
|
||
};
|
||
|
||
patdiff = {
|
||
enable = mkEnableOption "" // {
|
||
description = ''
|
||
Whether to enable the {command}`patdiff` differ.
|
||
See <https://opensource.janestreet.com/patdiff/>
|
||
'';
|
||
};
|
||
|
||
package = mkPackageOption pkgs "patdiff" { };
|
||
};
|
||
};
|
||
};
|
||
|
||
imports = [
|
||
(lib.mkRenamedOptionModule
|
||
[ "programs" "git" "signing" "gpgPath" ]
|
||
[
|
||
"programs"
|
||
"git"
|
||
"signing"
|
||
"signer"
|
||
]
|
||
)
|
||
];
|
||
|
||
config = mkIf cfg.enable (
|
||
lib.mkMerge [
|
||
{
|
||
home.packages = [ cfg.package ];
|
||
|
||
assertions = [
|
||
{
|
||
assertion =
|
||
let
|
||
enabled = [
|
||
cfg.delta.enable
|
||
cfg.diff-so-fancy.enable
|
||
cfg.difftastic.enable
|
||
cfg.diff-highlight.enable
|
||
cfg.riff.enable
|
||
cfg.patdiff.enable
|
||
];
|
||
in
|
||
lib.count lib.id enabled <= 1;
|
||
message = "Only one of 'programs.git.delta.enable' or 'programs.git.difftastic.enable' or 'programs.git.diff-so-fancy.enable' or 'programs.git.diff-highlight' or 'programs.git.patdiff' can be set to true at the same time.";
|
||
}
|
||
];
|
||
|
||
programs.git.iniContent.user = {
|
||
name = mkIf (cfg.userName != null) cfg.userName;
|
||
email = mkIf (cfg.userEmail != null) cfg.userEmail;
|
||
};
|
||
|
||
xdg.configFile = {
|
||
"git/config".text = lib.generators.toGitINI cfg.iniContent;
|
||
|
||
"git/ignore" = mkIf (cfg.ignores != [ ]) {
|
||
text = concatStringsSep "\n" cfg.ignores + "\n";
|
||
};
|
||
|
||
"git/attributes" = mkIf (cfg.attributes != [ ]) {
|
||
text = concatStringsSep "\n" cfg.attributes + "\n";
|
||
};
|
||
};
|
||
}
|
||
|
||
{
|
||
programs.git.iniContent =
|
||
let
|
||
hasSmtp = name: account: account.enable && account.smtp != null;
|
||
|
||
genIdentity =
|
||
name: account:
|
||
let
|
||
inherit (account)
|
||
address
|
||
realName
|
||
smtp
|
||
userName
|
||
;
|
||
in
|
||
lib.nameValuePair "sendemail.${name}" (
|
||
if account.msmtp.enable then
|
||
{
|
||
sendmailCmd = "${pkgs.msmtp}/bin/msmtp";
|
||
envelopeSender = "auto";
|
||
from = "${realName} <${address}>";
|
||
}
|
||
else
|
||
{
|
||
smtpEncryption =
|
||
if smtp.tls.enable then
|
||
(if smtp.tls.useStartTls || lib.versionOlder config.home.stateVersion "20.09" then "tls" else "ssl")
|
||
else
|
||
"";
|
||
smtpSslCertPath = mkIf smtp.tls.enable (toString smtp.tls.certificatesFile);
|
||
smtpServer = smtp.host;
|
||
smtpUser = userName;
|
||
from = "${realName} <${address}>";
|
||
}
|
||
// lib.optionalAttrs (smtp.port != null) {
|
||
smtpServerPort = smtp.port;
|
||
}
|
||
);
|
||
in
|
||
lib.mapAttrs' genIdentity (lib.filterAttrs hasSmtp config.accounts.email.accounts);
|
||
}
|
||
|
||
(mkIf (cfg.signing != { }) {
|
||
programs.git = {
|
||
signing = {
|
||
format =
|
||
if (lib.versionOlder config.home.stateVersion "25.05") then
|
||
(mkOptionDefault "openpgp")
|
||
else
|
||
(mkOptionDefault null);
|
||
signer =
|
||
let
|
||
defaultSigners = {
|
||
openpgp = lib.getExe config.programs.gpg.package;
|
||
ssh = lib.getExe' pkgs.openssh "ssh-keygen";
|
||
x509 = lib.getExe' config.programs.gpg.package "gpgsm";
|
||
};
|
||
in
|
||
mkIf (cfg.signing.format != null) (mkOptionDefault defaultSigners.${cfg.signing.format});
|
||
};
|
||
|
||
iniContent = lib.mkMerge [
|
||
(mkIf (cfg.signing.key != null) {
|
||
user.signingKey = mkDefault cfg.signing.key;
|
||
})
|
||
(mkIf (cfg.signing.signByDefault != null) {
|
||
commit.gpgSign = mkDefault cfg.signing.signByDefault;
|
||
tag.gpgSign = mkDefault cfg.signing.signByDefault;
|
||
})
|
||
(mkIf (cfg.signing.format != null) {
|
||
gpg = {
|
||
format = mkDefault cfg.signing.format;
|
||
${cfg.signing.format}.program = mkDefault cfg.signing.signer;
|
||
};
|
||
})
|
||
];
|
||
};
|
||
})
|
||
|
||
(mkIf (cfg.hooks != { }) {
|
||
programs.git.iniContent = {
|
||
core.hooksPath =
|
||
let
|
||
entries = lib.mapAttrsToList (name: path: { inherit name path; }) cfg.hooks;
|
||
in
|
||
toString (pkgs.linkFarm "git-hooks" entries);
|
||
};
|
||
})
|
||
|
||
(mkIf (cfg.aliases != { }) { programs.git.iniContent.alias = cfg.aliases; })
|
||
|
||
(mkIf (lib.isAttrs cfg.extraConfig) {
|
||
programs.git.iniContent = cfg.extraConfig;
|
||
})
|
||
|
||
(mkIf (lib.isString cfg.extraConfig) {
|
||
warnings = [
|
||
''
|
||
Using programs.git.extraConfig as a string option is
|
||
deprecated and will be removed in the future. Please
|
||
change to using it as an attribute set instead.
|
||
''
|
||
];
|
||
|
||
xdg.configFile."git/config".text = cfg.extraConfig;
|
||
})
|
||
|
||
(mkIf (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
|
||
lib.mkAfter (concatStringsSep "\n" (map lib.generators.toGitINI (map include cfg.includes)));
|
||
})
|
||
|
||
(mkIf cfg.lfs.enable {
|
||
home.packages = [ pkgs.git-lfs ];
|
||
|
||
programs.git.iniContent.filter.lfs =
|
||
let
|
||
skipArg = lib.optional cfg.lfs.skipSmudge "--skip";
|
||
in
|
||
{
|
||
clean = "git-lfs clean -- %f";
|
||
process = concatStringsSep " " (
|
||
[
|
||
"git-lfs"
|
||
"filter-process"
|
||
]
|
||
++ skipArg
|
||
);
|
||
required = true;
|
||
smudge = concatStringsSep " " (
|
||
[
|
||
"git-lfs"
|
||
"smudge"
|
||
]
|
||
++ skipArg
|
||
++ [
|
||
"--"
|
||
"%f"
|
||
]
|
||
);
|
||
};
|
||
})
|
||
|
||
(mkIf cfg.maintenance.enable {
|
||
programs.git.iniContent.maintenance.repo = cfg.maintenance.repositories;
|
||
|
||
systemd.user.services."git-maintenance@" = {
|
||
Unit = {
|
||
Description = "Optimize Git repositories data";
|
||
Documentation = [ "man:git-maintenance(1)" ];
|
||
};
|
||
|
||
Service = {
|
||
Type = "oneshot";
|
||
ExecStart =
|
||
let
|
||
exe = lib.getExe cfg.package;
|
||
in
|
||
''
|
||
"${exe}" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%i
|
||
'';
|
||
LockPersonality = "yes";
|
||
MemoryDenyWriteExecute = "yes";
|
||
NoNewPrivileges = "yes";
|
||
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_VSOCK";
|
||
RestrictNamespaces = "yes";
|
||
RestrictRealtime = "yes";
|
||
RestrictSUIDSGID = "yes";
|
||
SystemCallArchitectures = "native";
|
||
SystemCallFilter = "@system-service";
|
||
};
|
||
};
|
||
|
||
systemd.user.timers =
|
||
let
|
||
toSystemdTimer =
|
||
name: time:
|
||
lib.attrsets.nameValuePair "git-maintenance@${name}" {
|
||
Unit.Description = "Optimize Git repositories data";
|
||
|
||
Timer = {
|
||
OnCalendar = time;
|
||
Persistent = true;
|
||
};
|
||
|
||
Install.WantedBy = [ "timers.target" ];
|
||
};
|
||
in
|
||
lib.attrsets.mapAttrs' toSystemdTimer cfg.maintenance.timers;
|
||
|
||
launchd.agents =
|
||
let
|
||
baseArguments = [
|
||
"${lib.getExe cfg.package}"
|
||
"for-each-repo"
|
||
"--keep-going"
|
||
"--config=maintenance.repo"
|
||
"maintenance"
|
||
"run"
|
||
];
|
||
in
|
||
{
|
||
"git-maintenance-hourly" = {
|
||
enable = true;
|
||
config = {
|
||
ProgramArguments = baseArguments ++ [ "--schedule=hourly" ];
|
||
StartCalendarInterval = map (hour: {
|
||
Hour = hour;
|
||
Minute = 53;
|
||
}) (lib.range 1 23);
|
||
};
|
||
};
|
||
"git-maintenance-daily" = {
|
||
enable = true;
|
||
config = {
|
||
ProgramArguments = baseArguments ++ [ "--schedule=daily" ];
|
||
StartCalendarInterval = map (weekday: {
|
||
Weekday = weekday;
|
||
Hour = 0;
|
||
Minute = 53;
|
||
}) (lib.range 1 6);
|
||
};
|
||
};
|
||
"git-maintenance-weekly" = {
|
||
enable = true;
|
||
config = {
|
||
ProgramArguments = baseArguments ++ [ "--schedule=weekly" ];
|
||
StartCalendarInterval = [
|
||
{
|
||
Weekday = 0;
|
||
Hour = 0;
|
||
Minute = 53;
|
||
}
|
||
];
|
||
};
|
||
};
|
||
};
|
||
})
|
||
|
||
(mkIf cfg.diff-highlight.enable {
|
||
programs.git.iniContent =
|
||
let
|
||
dhCommand = "${cfg.package}/share/git/contrib/diff-highlight/diff-highlight";
|
||
in
|
||
{
|
||
core.pager = "${dhCommand} | ${lib.getExe pkgs.less} ${lib.escapeShellArgs cfg.diff-highlight.pagerOpts}";
|
||
interactive.diffFilter = dhCommand;
|
||
};
|
||
})
|
||
|
||
(
|
||
let
|
||
difftCommand = concatStringsSep " " [
|
||
"${lib.getExe cfg.difftastic.package}"
|
||
"--color ${cfg.difftastic.color}"
|
||
"--background ${cfg.difftastic.background}"
|
||
"--display ${cfg.difftastic.display}"
|
||
];
|
||
in
|
||
(lib.mkMerge [
|
||
(mkIf cfg.difftastic.enable {
|
||
home.packages = [ cfg.difftastic.package ];
|
||
programs.git.iniContent = {
|
||
diff.external = difftCommand;
|
||
};
|
||
})
|
||
(mkIf cfg.difftastic.enableAsDifftool {
|
||
home.packages = [ cfg.difftastic.package ];
|
||
programs.git.iniContent = {
|
||
diff = {
|
||
tool = lib.mkDefault "difftastic";
|
||
};
|
||
difftool = {
|
||
difftastic = {
|
||
cmd = "${difftCommand} $LOCAL $REMOTE";
|
||
};
|
||
};
|
||
};
|
||
})
|
||
])
|
||
)
|
||
|
||
(
|
||
let
|
||
deltaPackage = cfg.delta.package;
|
||
deltaCommand = "${deltaPackage}/bin/delta";
|
||
in
|
||
mkIf cfg.delta.enable {
|
||
home.packages = [ deltaPackage ];
|
||
|
||
programs.git.iniContent = {
|
||
core.pager = deltaCommand;
|
||
interactive.diffFilter = "${deltaCommand} --color-only";
|
||
delta = cfg.delta.options;
|
||
};
|
||
}
|
||
)
|
||
|
||
(mkIf cfg.diff-so-fancy.enable {
|
||
home.packages = [ pkgs.diff-so-fancy ];
|
||
|
||
programs.git.iniContent =
|
||
let
|
||
dsfCommand = "${pkgs.diff-so-fancy}/bin/diff-so-fancy";
|
||
in
|
||
{
|
||
core.pager = "${dsfCommand} | ${pkgs.less}/bin/less ${lib.escapeShellArgs cfg.diff-so-fancy.pagerOpts}";
|
||
interactive.diffFilter = "${dsfCommand} --patch";
|
||
diff-so-fancy = {
|
||
markEmptyLines = cfg.diff-so-fancy.markEmptyLines;
|
||
changeHunkIndicators = cfg.diff-so-fancy.changeHunkIndicators;
|
||
stripLeadingSymbols = cfg.diff-so-fancy.stripLeadingSymbols;
|
||
useUnicodeRuler = cfg.diff-so-fancy.useUnicodeRuler;
|
||
rulerWidth = mkIf (cfg.diff-so-fancy.rulerWidth != null) (cfg.diff-so-fancy.rulerWidth);
|
||
};
|
||
};
|
||
})
|
||
|
||
(
|
||
let
|
||
riffExe = baseNameOf (lib.getExe cfg.riff.package);
|
||
in
|
||
mkIf cfg.riff.enable {
|
||
home.packages = [ cfg.riff.package ];
|
||
|
||
# https://github.com/walles/riff/blob/b17e6f17ce807c8652bc59cd46758661d23ce358/README.md#usage
|
||
programs.git.iniContent = {
|
||
pager = {
|
||
diff = riffExe;
|
||
log = riffExe;
|
||
show = riffExe;
|
||
};
|
||
|
||
interactive.diffFilter = "${riffExe} --color=on";
|
||
};
|
||
}
|
||
)
|
||
|
||
(
|
||
let
|
||
patdiffPackage = cfg.patdiff.package;
|
||
patdiffCommand = "${lib.getExe' patdiffPackage "patdiff-git-wrapper"}";
|
||
in
|
||
mkIf cfg.patdiff.enable {
|
||
home.packages = [ patdiffPackage ];
|
||
|
||
programs.git.iniContent = {
|
||
diff.external = patdiffCommand;
|
||
};
|
||
}
|
||
)
|
||
|
||
(mkIf (cfg.riff.enable && cfg.riff.commandLineOptions != "") {
|
||
home.sessionVariables.RIFF = cfg.riff.commandLineOptions;
|
||
})
|
||
]
|
||
);
|
||
}
|