diff --git a/modules/programs/git.nix b/modules/programs/git.nix index a833e2c37..363ed3339 100644 --- a/modules/programs/git.nix +++ b/modules/programs/git.nix @@ -201,6 +201,21 @@ in { ''; }; + hooks = mkOption { + type = types.attrsOf types.path; + default = { }; + example = literalExpression '' + { + pre-commit = ./pre-commit-script; + } + ''; + description = '' + Configuration helper for Git hooks. + See + for reference. + ''; + }; + iniContent = mkOption { type = gitIniType; internal = true; @@ -449,6 +464,15 @@ in { }; }) + (mkIf (cfg.hooks != { }) { + programs.git.iniContent = { + core.hooksPath = let + entries = + 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) { diff --git a/tests/modules/programs/git/default.nix b/tests/modules/programs/git/default.nix index 3d401d8fc..3b92b2ff1 100644 --- a/tests/modules/programs/git/default.nix +++ b/tests/modules/programs/git/default.nix @@ -5,4 +5,5 @@ git-with-str-extra-config = ./git-with-str-extra-config.nix; git-with-signing-key-id = ./git-with-signing-key-id.nix; git-without-signing-key-id = ./git-without-signing-key-id.nix; + git-with-hooks = ./git-with-hooks.nix; } diff --git a/tests/modules/programs/git/git-pre-commit-hook.sh b/tests/modules/programs/git/git-pre-commit-hook.sh new file mode 100644 index 000000000..291cfd30f --- /dev/null +++ b/tests/modules/programs/git/git-pre-commit-hook.sh @@ -0,0 +1,2 @@ +#!/bin/sh +echo "pre-commit hook..." diff --git a/tests/modules/programs/git/git-with-hooks.nix b/tests/modules/programs/git/git-with-hooks.nix new file mode 100644 index 000000000..83f1059bc --- /dev/null +++ b/tests/modules/programs/git/git-with-hooks.nix @@ -0,0 +1,26 @@ +{ pkgs, ... }: + +{ + programs.git = { + enable = true; + hooks = { pre-commit = ./git-pre-commit-hook.sh; }; + }; + + nmt.script = '' + function getGitConfig() { + ${pkgs.gitMinimal}/bin/git config \ + --file $TESTED/home-files/.config/git/config \ + --get $1 + } + + assertFileExists home-files/.config/git/config + hookPath=$(getGitConfig core.hooksPath) + assertLinkExists $hookPath/pre-commit + + actual="$(readlink "$hookPath/pre-commit")" + expected="${./git-pre-commit-hook.sh}" + if [[ $actual != $expected ]]; then + fail "Symlink $hookPath/pre-commit should point to $expected via the Nix store, but it actually points to $actual." + fi + ''; +}