Skip to content

Commit 360e17a

Browse files
committed
add installation test
1 parent c11e43a commit 360e17a

File tree

8 files changed

+150
-17
lines changed

8 files changed

+150
-17
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ jobs:
3030
name: pre-commit-hooks
3131
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
3232
- run: rm -rf /opt&
33-
- run: nix flake check --show-trace
33+
- run: nix flake check -L --show-trace
3434
- run: nix eval .#lib.x86_64-linux.run --show-trace

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ nix develop
9292
ormolu.enable = true;
9393
ormolu.package = pkgs.haskellPackages.ormolu;
9494
ormolu.settings.defaultExtensions = [ "lhs" "hs" ];
95-
95+
9696
# some hooks have more than one package, like clippy:
9797
clippy.enable = true;
9898
clippy.packageOverrides.cargo = pkgs.cargo;
@@ -109,7 +109,7 @@ nix develop
109109
3. Integrate hooks to prepare environment as part of `shell.nix`:
110110

111111
```nix
112-
let
112+
let
113113
pre-commit = import ./default.nix;
114114
in (import <nixpkgs> {}).mkShell {
115115
shellHook = ''
@@ -318,7 +318,7 @@ clang-format = {
318318
};
319319
```
320320

321-
Otherwise, the default internal list is used which includes everything that
321+
Otherwise, the default internal list is used which includes everything that
322322
clang-format supports.
323323

324324
## Git
@@ -373,6 +373,9 @@ Example configuration:
373373
# Set this to false to not pass the changed files
374374
# to the command (default: true):
375375
pass_filenames = false;
376+
377+
# Which git hooks the command should run for (default: [ "pre-commit" ]):
378+
stages = ["pre-push"];
376379
};
377380
};
378381
};

flake.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
}
3636
// flake-utils.lib.eachSystem defaultSystems (system:
3737
let
38-
exposed = import ./nix { nixpkgs = nixpkgs; inherit system; gitignore-nix-src = gitignore; isFlakes = true; };
38+
exposed = import ./nix { inherit nixpkgs system; gitignore-nix-src = gitignore; isFlakes = true; };
3939
exposed-stable = import ./nix { nixpkgs = nixpkgs-stable; inherit system; gitignore-nix-src = gitignore; isFlakes = true; };
4040
in
4141
{

modules/hook.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ in
155155
};
156156

157157
stages = mkOption {
158-
type = types.listOf types.str;
158+
type = (import ./supported-hooks.nix { inherit lib; }).supportedHooksType;
159159
description = lib.mdDoc ''
160160
Confines the hook to run at a particular stage.
161161
'';

modules/pre-commit.nix

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ let
1010
mkIf
1111
mkOption
1212
types
13+
remove
1314
;
1415

1516
inherit (pkgs) runCommand writeText git;
1617

1718
cfg = config;
18-
install_stages = lib.unique (cfg.default_stages ++ (builtins.concatLists (lib.mapAttrsToList (_: h: h.stages) enabledHooks)));
19+
install_stages = lib.unique (builtins.concatLists (lib.mapAttrsToList (_: h: h.stages) enabledHooks));
20+
21+
supportedHooksLib = import ./supported-hooks.nix { inherit lib; };
1922

2023
hookType = types.submodule {
2124
imports = [
@@ -175,7 +178,7 @@ in
175178
The predefined hooks are:
176179
177180
${
178-
lib.concatStringsSep
181+
concatStringsSep
179182
"\n"
180183
(lib.mapAttrsToList
181184
(hookName: hookConf:
@@ -253,14 +256,14 @@ in
253256

254257
default_stages =
255258
mkOption {
256-
type = types.listOf types.str;
259+
type = supportedHooksLib.supportedHooksType;
257260
description = lib.mdDoc
258261
''
259262
A configuration wide option for the stages property.
260263
Installs hooks to the defined stages.
261264
See [https://pre-commit.com/#confining-hooks-to-run-at-certain-stages](https://pre-commit.com/#confining-hooks-to-run-at-certain-stages).
262265
'';
263-
default = [ "commit" ];
266+
default = [ "pre-commit" ];
264267
};
265268

266269
rawConfig =
@@ -332,12 +335,11 @@ in
332335
333336
# These update procedures compare before they write, to avoid
334337
# filesystem churn. This improves performance with watch tools like lorri
335-
# and prevents installation loops by via lorri.
338+
# and prevents installation loops by lorri.
336339
337340
if ! readlink "''${GIT_WC}/.pre-commit-config.yaml" >/dev/null \
338341
|| [[ $(readlink "''${GIT_WC}/.pre-commit-config.yaml") != ${configFile} ]]; then
339342
echo 1>&2 "pre-commit-hooks.nix: updating $PWD repo"
340-
341343
[ -L .pre-commit-config.yaml ] && unlink .pre-commit-config.yaml
342344
343345
if [ -e "''${GIT_WC}/.pre-commit-config.yaml" ]; then
@@ -349,24 +351,23 @@ in
349351
else
350352
ln -fs ${configFile} "''${GIT_WC}/.pre-commit-config.yaml"
351353
# Remove any previously installed hooks (since pre-commit itself has no convergent design)
352-
hooks="pre-commit pre-merge-commit pre-push prepare-commit-msg commit-msg post-checkout post-commit"
354+
hooks="${concatStringsSep " " (remove "manual" supportedHooksLib.supportedHooks )}"
353355
for hook in $hooks; do
354356
pre-commit uninstall -t $hook
355357
done
356358
${git}/bin/git config --local core.hooksPath ""
357359
# Add hooks for configured stages (only) ...
358360
if [ ! -z "${concatStringsSep " " install_stages}" ]; then
359361
for stage in ${concatStringsSep " " install_stages}; do
360-
if [[ "$stage" == "manual" ]]; then
361-
continue
362-
fi
363362
case $stage in
363+
manual)
364+
;;
364365
# if you amend these switches please also review $hooks above
365366
commit | merge-commit | push)
366367
stage="pre-"$stage
367368
pre-commit install -t $stage
368369
;;
369-
prepare-commit-msg | commit-msg | post-checkout | post-commit)
370+
${concatStringsSep "|" supportedHooksLib.supportedHooks})
370371
pre-commit install -t $stage
371372
;;
372373
*)

modules/supported-hooks.nix

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{ lib }:
2+
let inherit (lib) types;
3+
# according to https://pre-commit.com/#supported-git-hooks
4+
supportedHooks = [
5+
"commit-msg"
6+
"post-checkout"
7+
"post-commit"
8+
"post-merge"
9+
"post-rewrite"
10+
"pre-commit"
11+
"pre-merge-commit"
12+
"pre-push"
13+
"pre-rebase"
14+
"prepare-commit-msg"
15+
"manual"
16+
];
17+
in
18+
{
19+
inherit supportedHooks;
20+
21+
supportedHooksType =
22+
let
23+
deprecatedHooks = [
24+
"commit"
25+
"push"
26+
"merge-commit"
27+
];
28+
in
29+
types.listOf (types.enum (supportedHooks ++ deprecatedHooks));
30+
}

nix/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ let
2727
typos.enable = true;
2828
};
2929
};
30+
installation-test = pkgs.callPackage ./installation-test.nix { inherit run; };
3031
all-tools-eval =
3132
let
3233
config = lib.evalModules {

nix/installation-test.nix

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Test that checks whether the correct hooks are created in the hooks folder.
2+
{ git, perl, coreutils, runCommand, run, lib }:
3+
let
4+
tests = {
5+
basic-test = {
6+
expectedHooks = [ "pre-commit" ];
7+
conf.hooks.shellcheck.enable = true;
8+
};
9+
10+
multiple-hooks-test = {
11+
expectedHooks = [ "commit-msg" "pre-commit" ];
12+
conf.hooks = {
13+
shellcheck.enable = true;
14+
nixpkgs-fmt = {
15+
enable = true;
16+
stages = [ "commit-msg" ];
17+
};
18+
};
19+
};
20+
21+
non-default-stage-test = {
22+
expectedHooks = [ "commit-msg" ];
23+
conf.hooks.nixpkgs-fmt = {
24+
enable = true;
25+
stages = [ "commit-msg" ];
26+
};
27+
};
28+
29+
default-stage-test = {
30+
expectedHooks = [ "commit-msg" ];
31+
conf = {
32+
default_stages = [ "commit-msg" ];
33+
hooks.nixpkgs-fmt.enable = true;
34+
};
35+
};
36+
37+
manual-default-stage-test = {
38+
expectedHooks = [ ];
39+
conf = {
40+
default_stages = [ "manual" ];
41+
hooks.nixpkgs-fmt.enable = true;
42+
};
43+
};
44+
45+
multiple-default-stages-test = {
46+
expectedHooks = [ "pre-push" ];
47+
conf = {
48+
default_stages = [ "manual" "pre-push" ];
49+
hooks.nixpkgs-fmt.enable = true;
50+
};
51+
};
52+
53+
deprecated-gets-prefixed-test = {
54+
expectedHooks = [ "pre-push" ];
55+
conf.hooks.nixpkgs-fmt = {
56+
enable = true;
57+
stages = [ "push" ];
58+
};
59+
};
60+
};
61+
62+
executeTest = lib.mapAttrsToList
63+
(name: test:
64+
let runDerivation = run ({ src = null; } // test.conf);
65+
in ''
66+
rm -f /build/.git/hooks/*
67+
${runDerivation.shellHook}
68+
actualHooks=(`find /build/.git/hooks -type f -printf "%f "`)
69+
read -a expectedHooks <<< "${builtins.toString test.expectedHooks}"
70+
if ! assertArraysEqual actualHooks expectedHooks; then
71+
echo "${name} failed: Expected hooks '${builtins.toString test.expectedHooks}' but found '$actualHooks'."
72+
return 1
73+
fi
74+
'')
75+
tests;
76+
in
77+
runCommand "installation-test" { nativeBuildInputs = [ git perl coreutils ]; } ''
78+
set -eoux
79+
80+
HOME=/build
81+
git init
82+
83+
assertArraysEqual() {
84+
local -n _array_one=$1
85+
local -n _array_two=$2
86+
diffArray=(`echo ''${_array_one[@]} ''${_array_two[@]} | tr ' ' '\n' | sort | uniq -u`)
87+
if [ ''${#diffArray[@]} -eq 0 ]
88+
then
89+
return 0
90+
else
91+
return 1
92+
fi
93+
}
94+
95+
${lib.concatStrings executeTest}
96+
97+
echo "success" > $out
98+
''

0 commit comments

Comments
 (0)