mirror of
https://gitlab.com/rensa-nix/devtools.git
synced 2025-12-11 22:00:07 +01:00
153 lines
4 KiB
Nix
153 lines
4 KiB
Nix
|
|
{
|
||
|
|
lib,
|
||
|
|
pkgs,
|
||
|
|
config,
|
||
|
|
...
|
||
|
|
}: let
|
||
|
|
inherit (lib) concatStringsSep concatMapStringsSep subtractLists mkEnableOption mkOption types mkIf;
|
||
|
|
cfg = config.lefthook;
|
||
|
|
|
||
|
|
allHookNames = [
|
||
|
|
"applypatch-msg"
|
||
|
|
"pre-applypatch"
|
||
|
|
"post-applypatch"
|
||
|
|
"pre-commit"
|
||
|
|
"prepare-commit-msg"
|
||
|
|
"commit-msg"
|
||
|
|
"post-commit"
|
||
|
|
"pre-rebase"
|
||
|
|
"post-rewrite"
|
||
|
|
"post-checkout"
|
||
|
|
"post-merge"
|
||
|
|
"pre-push"
|
||
|
|
"pre-auto-gc"
|
||
|
|
"post-update"
|
||
|
|
"sendemail-validate"
|
||
|
|
"fsmonitor-watchman"
|
||
|
|
"p4-changelist"
|
||
|
|
"p4-prepare-changelist"
|
||
|
|
"p4-post-changelist"
|
||
|
|
"p4-pre-submit"
|
||
|
|
"post-index-change"
|
||
|
|
"pre-receive"
|
||
|
|
"update"
|
||
|
|
"proc-receive"
|
||
|
|
"reference-transaction"
|
||
|
|
"push-to-checkout"
|
||
|
|
"pre-merge-commit"
|
||
|
|
];
|
||
|
|
currentHookNames = builtins.filter (h: builtins.elem h allHookNames) (builtins.attrNames cfg.config);
|
||
|
|
unusedNixHookNames = subtractLists allHookNames currentHookNames;
|
||
|
|
unusedNixHookNamesStr = concatStringsSep " " unusedNixHookNames;
|
||
|
|
|
||
|
|
hookContent = hookName:
|
||
|
|
pkgs.writeShellScript hookName ''
|
||
|
|
if [ "$LEFTHOOK" = "0" ]; then
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
${lefthookAlias}/bin/${cfg.alias} run "${hookName}" "$@"
|
||
|
|
'';
|
||
|
|
|
||
|
|
lefthookConfig = (pkgs.formats.yaml {}).generate "lefthook.yaml" cfg.config;
|
||
|
|
lefthookAlias = pkgs.writeShellScriptBin cfg.alias ''
|
||
|
|
if [ "$1" = "install" ]; then
|
||
|
|
echo "Warning, using 'lefthook install' should not be used, use the shellHook instead"
|
||
|
|
fi
|
||
|
|
if [ "$1" = "install" ]; then
|
||
|
|
echo "Warning, using 'lefthook install' should not be used, use the shellHook instead"
|
||
|
|
fi
|
||
|
|
if [ "$1" = "install" ]; then
|
||
|
|
echo "Warning, using 'lefthook install' should not be used, use the shellHook instead"
|
||
|
|
fi
|
||
|
|
LEFTHOOK_CONFIG="${lefthookConfig}" ${pkgs.lefthook}/bin/lefthook ''${@:1}
|
||
|
|
'';
|
||
|
|
in {
|
||
|
|
options.lefthook = {
|
||
|
|
enable =
|
||
|
|
mkEnableOption "Lefthook"
|
||
|
|
// {
|
||
|
|
default = cfg.config != {};
|
||
|
|
};
|
||
|
|
shellHook = mkOption {
|
||
|
|
type = types.bool;
|
||
|
|
default = true;
|
||
|
|
description = ''
|
||
|
|
Whether to add a shell hook which automatically installs the git hooks.
|
||
|
|
'';
|
||
|
|
};
|
||
|
|
alias = mkOption {
|
||
|
|
type = types.str;
|
||
|
|
default = "lefthook";
|
||
|
|
example = "hooks";
|
||
|
|
description = ''
|
||
|
|
Alias for the lefthook command.
|
||
|
|
'';
|
||
|
|
};
|
||
|
|
config = mkOption {
|
||
|
|
type = types.attrs;
|
||
|
|
default = {};
|
||
|
|
description = ''
|
||
|
|
Config for lefthook. See https://lefthook.dev/configuration/.
|
||
|
|
'';
|
||
|
|
example = {
|
||
|
|
pre-commit = {
|
||
|
|
parallel = true;
|
||
|
|
jobs = [
|
||
|
|
{
|
||
|
|
name = "hello";
|
||
|
|
run = "echo world";
|
||
|
|
}
|
||
|
|
];
|
||
|
|
};
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
outputs = {
|
||
|
|
shellHook = mkOption {
|
||
|
|
type = types.str;
|
||
|
|
readOnly = true;
|
||
|
|
description = ''
|
||
|
|
The script to run on shell activation.
|
||
|
|
It automatically installs the git hooks and removes unused/previously used ones.
|
||
|
|
'';
|
||
|
|
};
|
||
|
|
};
|
||
|
|
};
|
||
|
|
config = {
|
||
|
|
lefthook.outputs.shellHook =
|
||
|
|
# sh
|
||
|
|
''
|
||
|
|
${builtins.readFile ./lefthook_helpers.sh}
|
||
|
|
|
||
|
|
# ensure git is available and we are in a Git repository
|
||
|
|
if ! command -v git &> /dev/null; then
|
||
|
|
__log ERROR "Git command not found. Cannot manage Git hooks." >&2
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
local GIT_REAL_DIR
|
||
|
|
GIT_REAL_DIR=$(git rev-parse --git-dir 2>/dev/null)
|
||
|
|
if [ $? -ne 0 ]; then
|
||
|
|
__log INFO "Not inside a Git repository. Skipping Git hook setup." >&2
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
# Use realpath to handle .git file for worktrees, and resolve relative path
|
||
|
|
GIT_REAL_DIR=$(realpath "$GIT_REAL_DIR")
|
||
|
|
|
||
|
|
# clean up unused hooks
|
||
|
|
cleanup_git_hooks "${unusedNixHookNamesStr}"
|
||
|
|
|
||
|
|
${concatMapStringsSep "\n" (hook: ''
|
||
|
|
setup_git_hook "${hook}" "${hookContent hook}"
|
||
|
|
'')
|
||
|
|
currentHookNames}
|
||
|
|
'';
|
||
|
|
packages = mkIf cfg.enable [lefthookAlias];
|
||
|
|
enterShellCommands."lefthook" = mkIf (cfg.enable && cfg.shellHook) {
|
||
|
|
text = cfg.outputs.shellHook;
|
||
|
|
deps = ["env"];
|
||
|
|
};
|
||
|
|
};
|
||
|
|
}
|