diff --git a/checks/git-hooks.nix b/checks/git-hooks.nix index 6b147e2..f0e7071 100644 --- a/checks/git-hooks.nix +++ b/checks/git-hooks.nix @@ -68,6 +68,32 @@ let inherit (flakeboxLib.config.git.pre-commit.hooks) shellcheck; }; + gitDisabledLib = mkLib pkgs { + config = { + git.enable = false; + github.ci.enable = true; + }; + }; + + preCommitDisabledLib = mkLib pkgs { + config = { + git.pre-commit.enable = false; + github.ci.enable = true; + }; + }; + + commitMsgDisabledLib = mkLib pkgs { + config.git.commit-msg.enable = false; + }; + + commitTemplateDisabledLib = mkLib pkgs { + config.git.commit-template.enable = false; + }; + + gitEnabledCiLib = mkLib pkgs { + config.github.ci.enable = true; + }; + stashHooks = mkHookFixture { stash-probe = '' grep -qx staged tracked.txt @@ -134,6 +160,23 @@ let emptyHooks = mkHookFixture { }; in assert pkgs.lib.elem timer flakeboxLib.config.env.shellPackages; +assert flakeboxLib.config.git.enable; +assert gitDisabledLib.config.git.pre-commit.enable; +assert gitDisabledLib.config.git.commit-msg.enable; +assert gitDisabledLib.config.git.commit-template.enable; +assert !(pkgs.lib.elem timer gitDisabledLib.config.env.shellPackages); +assert + !(pkgs.lib.hasInfix "hooks/pre-commit" ( + builtins.concatStringsSep "\n" gitDisabledLib.config.env.shellHooks + )); +assert + !(pkgs.lib.hasInfix "hooks/commit-msg" ( + builtins.concatStringsSep "\n" gitDisabledLib.config.env.shellHooks + )); +assert + !(pkgs.lib.hasInfix "git config commit.template" ( + builtins.concatStringsSep "\n" gitDisabledLib.config.env.shellHooks + )); pkgs.runCommand "git-hooks-tests" { nativeBuildInputs = [ @@ -178,6 +221,45 @@ pkgs.runCommand "git-hooks-tests" fi bash -n "$commit_msg" + [ -e "${flakeboxLib.root}/misc/git-hooks/commit-template.txt" ] + grep -q 'git config commit.template misc/git-hooks/commit-template.txt' \ + "${flakeboxLib.root}/.config/flakebox/shellHook.sh" + grep -q 'hooks/pre-commit' "${flakeboxLib.root}/justfile" + grep -q 'misc/git-hooks/pre-commit' \ + "${gitEnabledCiLib.root}/.github/workflows/flakebox-ci.yml" + + # The grouped opt-out omits every generated commit integration artifact and + # every installer/configuration action and generated consumer. + [ ! -e ${gitDisabledLib.root}/misc/git-hooks/pre-commit ] + [ ! -e ${gitDisabledLib.root}/misc/git-hooks/commit-msg ] + [ ! -e ${gitDisabledLib.root}/misc/git-hooks/commit-template.txt ] + disabled_shell_hook="${gitDisabledLib.root}/.config/flakebox/shellHook.sh" + ! grep -q 'hooks/pre-commit' "$disabled_shell_hook" + ! grep -q 'hooks/commit-msg' "$disabled_shell_hook" + ! grep -q 'git config commit.template' "$disabled_shell_hook" + ! grep -q 'hooks/pre-commit' "${gitDisabledLib.root}/justfile" + ! grep -q 'misc/git-hooks/pre-commit' \ + "${gitDisabledLib.root}/.github/workflows/flakebox-ci.yml" + + # Existing granular options still suppress only their own integration, and + # pre-commit consumers follow the effective pre-commit setting. + [ ! -e ${preCommitDisabledLib.root}/misc/git-hooks/pre-commit ] + [ -e ${preCommitDisabledLib.root}/misc/git-hooks/commit-msg ] + [ -e ${preCommitDisabledLib.root}/misc/git-hooks/commit-template.txt ] + ! grep -q 'hooks/pre-commit' "${preCommitDisabledLib.root}/justfile" + ! grep -q 'misc/git-hooks/pre-commit' \ + "${preCommitDisabledLib.root}/.github/workflows/flakebox-ci.yml" + + [ -e ${commitMsgDisabledLib.root}/misc/git-hooks/pre-commit ] + [ ! -e ${commitMsgDisabledLib.root}/misc/git-hooks/commit-msg ] + [ -e ${commitMsgDisabledLib.root}/misc/git-hooks/commit-template.txt ] + + [ -e ${commitTemplateDisabledLib.root}/misc/git-hooks/pre-commit ] + [ -e ${commitTemplateDisabledLib.root}/misc/git-hooks/commit-msg ] + [ ! -e ${commitTemplateDisabledLib.root}/misc/git-hooks/commit-template.txt ] + ! grep -q 'git config commit.template' \ + "${commitTemplateDisabledLib.root}/.config/flakebox/shellHook.sh" + # The timer preserves success, failures, errexit, signals, and byte-exact # ordinary output when no warning is emitted. function check_output() { diff --git a/docs/technical-details.md b/docs/technical-details.md index 58f7a63..925fffd 100644 --- a/docs/technical-details.md +++ b/docs/technical-details.md @@ -67,6 +67,41 @@ value runs the checks normally. This does not affect hooks not generated by Flakebox. Git's `git commit --no-verify` is also available as a one-shot alternative. +### Disabling commit integration + +Set `git.enable = false` in the Flakebox configuration to disable the complete +Git commit integration. Flakebox then does not generate or install its +`pre-commit` or `commit-msg` hooks, generate its commit-message template, or set +Git's `commit.template` configuration. The existing `git.pre-commit.enable`, +`git.commit-msg.enable`, and `git.commit-template.enable` options remain +available for partial control when `git.enable` is true. + +This option does not clean up state installed by an earlier configuration. +After changing it, remove the old generated files: + +```console +rm -f misc/git-hooks/pre-commit \ + misc/git-hooks/commit-msg \ + misc/git-hooks/commit-template.txt +``` + +Remove installed hooks only after confirming they are Flakebox-owned: + +```console +hooks_dir="$(git rev-parse --git-common-dir)/hooks" +ls -l "$hooks_dir/pre-commit" "$hooks_dir/commit-msg" +rm -f "$hooks_dir/pre-commit" "$hooks_dir/commit-msg" +``` + +Finally, remove the template setting only when it still has the Flakebox value: + +```console +if [ "$(git config --get commit.template || true)" = \ + "misc/git-hooks/commit-template.txt" ]; then + git config --unset commit.template +fi +``` + ## Flakebox `lib` output Flakebox's Flake exposes a `lib` flake output which allows: diff --git a/lib/modules/git.nix b/lib/modules/git.nix index d9d984c..ef634e9 100644 --- a/lib/modules/git.nix +++ b/lib/modules/git.nix @@ -12,6 +12,10 @@ in { options.git = { + enable = lib.mkEnableOption "Flakebox Git commit hooks and commit template integration" // { + default = true; + }; + pre-commit = { enable = lib.mkEnableOption "git pre-commit hook" // { default = true; @@ -107,7 +111,7 @@ in ''; }) - (lib.mkIf config.git.commit-msg.enable { + (lib.mkIf (config.git.enable && config.git.commit-msg.enable) { rootDir."misc/git-hooks/commit-msg" = let content = ( @@ -168,7 +172,7 @@ in }) - (lib.mkIf config.git.pre-commit.enable { + (lib.mkIf (config.git.enable && config.git.pre-commit.enable) { rootDir."misc/git-hooks/pre-commit" = let indentString = @@ -280,7 +284,7 @@ in }) - (lib.mkIf config.git.commit-template.enable { + (lib.mkIf (config.git.enable && config.git.commit-template.enable) { rootDir."misc/git-hooks/commit-template.txt" = { source = pkgs.writeText "commit-template" ( lib.removeSuffix "\n" '' diff --git a/lib/modules/github.nix b/lib/modules/github.nix index c40348c..57208b0 100644 --- a/lib/modules/github.nix +++ b/lib/modules/github.nix @@ -184,7 +184,7 @@ in }) { - lint = { + lint = lib.mkIf (config.git.enable && config.git.pre-commit.enable) { name = "Lint"; runs-on = config.github.ci.runsOn; steps = [ diff --git a/lib/modules/just.nix b/lib/modules/just.nix index aa107e9..0bb41da 100644 --- a/lib/modules/just.nix +++ b/lib/modules/just.nix @@ -159,7 +159,7 @@ in ''; }; - lint = { + lint = lib.mkIf (config.git.enable && config.git.pre-commit.enable) { priority = 100; content = '' # run lints (git pre-commit hook) @@ -174,7 +174,7 @@ in priority = 100; content = '' # run all checks recommended before opening a PR - final-check: lint ${ + final-check: ${lib.optionalString (config.git.enable && config.git.pre-commit.enable) "lint"} ${ if config.just.rules ? clippy && config.just.rules.clippy.enable then "clippy" else "" } #!/usr/bin/env bash