git-hooks.nix
git-hooks.nix copied to clipboard
Supported pre-commit hook
How can I integrate the supported hook from pre-commit such as end-of-file-fixer
or trailing-whitespace
into pre-commit-hooks.nix ?
As an aside question, is there a way to integrate local hooks ?
tldr; supported hooks: requires change, local hooks: already possible
supported hooks
Looks like you want to add hooks from pre-commit's standard repo https://github.com/pre-commit/pre-commit-hooks
This possibility is not properly exposed through an option yet, but it can be added via the rawConfig
option. Since only a small set of options is exposed via run.nix
, this means changing pre-commit-hooks.nix.
local hooks
The latest version has been simplified from what it used to be and basically only works exclusively via the local hooks feature.
To put it differently, pre-commit.nix translates everything to local hooks.
Basically where you define enable = true
in your config, you can define all the other attributes as well.
This should be tested and documented (#2).
Supported hooks
If I add to the rawConfig
option something like:
{
repo = "https://github.com/pre-commit/pre-commit-hooks";
rev = "v2.4.0";
hooks = [ { id = "trailing-whitespace"; } ];
}
How can I ensure that the hook is pinned (and goes in a binary cache) ? The integrity and self-encapsulation of pre-commit-hooks.nix
is on my side the biggest motivation/use case for pre-commit-hooks.nix
Precisely those are possibly most elegantly addressed in an .editorconfig
- special case, though.
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
I managed to get the trailing-whitespace
hook to run by adding the pre-commit-hooks
to nixpkgs (pr) and activate it in my config like this:
trailing-whitespace = {
enable = true;
name = "Trim Trailing Whitespace";
description = "This hook trims trailing whitespace.";
entry = "${pkgs.python3Packages.pre-commit-hooks}/bin/trailing-whitespace-fixer";
types = ["text"];
};
Ideal because it's now self-contained within the Nix store, not ideal because you have to replicate the hook's settings.
It took me a while to figure out how to use rawConfig
? So here's a gist for someone looking (and a request to make it simpler :sweat_smile: ):
pre-commit = {
hooks = {
nil.enable = true; # HACK: some hook needs to be enabled for pre-commit to enable itself - but will be overwritten anyways
};
rawConfig = {
repos = [
{
"repo" = "https://github.com/codingjoe/relint";
"rev" = "1.2.1";
"hooks" = [
{ "id" = "relint"; "exclude" = ''...''; }
];
}
];
};
};
I managed to get the
trailing-whitespace
hook to run by adding thepre-commit-hooks
to nixpkgs (pr) and activate it in my config like this:trailing-whitespace = { enable = true; name = "Trim Trailing Whitespace"; description = "This hook trims trailing whitespace."; entry = "${pkgs.python3Packages.pre-commit-hooks}/bin/trailing-whitespace-fixer"; types = ["text"]; };
Ideal because it's now self-contained within the Nix store, not ideal because you have to replicate the hook's settings.
I ended up writing this to make them all available in the same vein:
pre-commit.settings.hooks = lib.trivial.pipe source [
(pkg: "${pkg.src}/.pre-commit-hooks.yaml")
fromYAMLFile
(builtins.map (hook: lib.attrsets.nameValuePair hook.id hook))
builtins.listToAttrs
(builtins.mapAttrs (_: hook: lib.trivial.pipe hook [
(hook: hook // {enable = false; entry = "${source}/bin/${hook.entry}";})
# stages are excluded to support setting pre-commit.settings.default_stages
(hook: builtins.removeAttrs hook ["id" "stages"])
(builtins.mapAttrs (_: lib.mkDefault))
]))
];
where source
is pkgs.python311Packages.pre-commit-hooks
and fromYAMLFile
is my custom yaml parsing function:
fromYAMLFile = input_f:
lib.trivial.pipe input_f [
(file: "remarshal -if yaml -i \"${file}\" -of json -o \"$out\"")
(pkgs.runCommand "from-yaml" {nativeBuildInputs = [pkgs.remarshal];})
lib.trivial.importJSON
];
In a separate module I then enable and override the ones I want:
pre-commit.settings.default_stages = ["pre-push" "manual"];
pre-commit.settings.hooks = {
check-merge-conflict.enable = true;
check-merge-conflict.raw.args = ["--assume-in-merge"];
no-commit-to-branch.enable = true;
no-commit-to-branch.raw.args = ["--branch" "trunk"];
trailing-whitespace.enable = true;
};
There's probably something horribly wrong with this approach (lib.mkDefault
all attributes, for example) but seems to be working. Maybe generating options instead is a better idea for this public library? Happy to contribute this / improve it if it's helpful.
The built-in pre-commit hooks should now be exposed. See #401.