Something went wrong. Try again.
A small, fast, drop-in replacement for git-hooks.nix
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990{lib}: let scriptFn = hook: "nixhooks_hook_${hook.name}";
# a subshell function, with options reset so it runs like a standalone script scriptDef = hook: '' ${scriptFn hook}() ( set +e +u +o pipefail ${hook.script} )'';
mkArgs = hook: let args = [ hook.name hook.files hook.exclude ( if hook.pass_filenames then "1" else "0" ) ( if hook.always_run then "1" else "0" ) ( if hook.required then "1" else "0" ) ( if hook.fallback == null then "" else hook.fallback ) ( if hook.script != null then scriptFn hook else hook.entry ) (lib.makeBinPath hook.path) ] ++ hook.args; in args;
# serial calls are guarded with `|| true`, an ungaurded call would abort the # script on the first failure serialCall = hook: " run_hook ${lib.concatMapStringsSep " " lib.escapeShellArg (mkArgs hook)} || true";
# run_hook_parallel never fails, so there's nothing to guard parallelCall = hook: " run_hook_parallel ${lib.concatMapStringsSep " " lib.escapeShellArg (mkArgs hook)}";
precomputeCall = pair: " nixhooks_precompute_matches ${lib.escapeShellArg pair.files} ${lib.escapeShellArg pair.exclude}";
# always_run hooks skip matching entirely, so they need no precompute. genPrecomputeCalls = hooks: let pairs = lib.unique (map (h: {inherit (h) files exclude;}) (builtins.filter (h: !h.always_run) hooks)); in map precomputeCall pairs;
# partitions an already-stage-filtered hook set into a parallel batch # followed by a nixhooks_wait_parallel barrier and then the serial tail genPartitionedCalls = hooks: let ordered = lib.attrValues hooks; parallelHooks = builtins.filter (h: h.parallel) ordered; serialHooks = builtins.filter (h: !h.parallel) ordered; lines = map scriptDef (builtins.filter (h: h.script != null) ordered) ++ genPrecomputeCalls ordered ++ map parallelCall parallelHooks ++ lib.optional (parallelHooks != []) " nixhooks_wait_parallel" ++ map serialCall serialHooks; in lib.concatStringsSep "\n" lines;
hooksForStage = stage: hooks: lib.filterAttrs (_: h: builtins.elem stage h.stages) hooks;in { # calls for a single stage genStageCalls = stage: hooks: genPartitionedCalls (hooksForStage stage hooks);
# calls for CI, commit-msg hooks are filtered out genAllCalls = hooks: genPartitionedCalls (lib.filterAttrs (_: h: builtins.any (s: s != "commit-msg") h.stages) hooks);}