1{
2 lib,
3 stdenv,
4 python3Packages,
5 fetchFromGitHub,
6
7 # tests
8 cabal-install,
9 cargo,
10 gitMinimal,
11 go,
12 perl,
13 versionCheckHook,
14 writableTmpDirAsHomeHook,
15 coursier,
16 dotnet-sdk,
17 nodejs,
18
19 # passthru
20 callPackage,
21 pre-commit,
22}:
23
24let
25 i686Linux = stdenv.buildPlatform.system == "i686-linux";
26in
27python3Packages.buildPythonApplication rec {
28 pname = "pre-commit";
29 version = "4.2.0";
30 pyproject = true;
31
32 src = fetchFromGitHub {
33 owner = "pre-commit";
34 repo = "pre-commit";
35 tag = "v${version}";
36 hash = "sha256-rUhI9NaxyRfLu/mfLwd5B0ybSnlAQV2Urx6+fef0sGM=";
37 };
38
39 patches = [
40 ./languages-use-the-hardcoded-path-to-python-binaries.patch
41 ./hook-tmpl.patch
42 ./pygrep-pythonpath.patch
43 ];
44
45 build-system = with python3Packages; [
46 setuptools
47 ];
48
49 dependencies = with python3Packages; [
50 cfgv
51 identify
52 nodeenv
53 pyyaml
54 toml
55 virtualenv
56 ];
57
58 nativeCheckInputs = [
59 cabal-install
60 cargo
61 gitMinimal
62 go
63 perl
64 versionCheckHook
65 writableTmpDirAsHomeHook
66 ]
67 ++ (with python3Packages; [
68 pytest-env
69 pytest-forked
70 pytest-xdist
71 pytestCheckHook
72 re-assert
73 ])
74 ++ lib.optionals (!i686Linux) [
75 # coursier can be moved back to the main nativeCheckInputs list once we’re able to bootstrap a
76 # JRE on i686-linux: <https://github.com/NixOS/nixpkgs/issues/314873>. When coursier gets
77 # moved back to the main nativeCheckInputs list, don’t forget to re-enable the
78 # coursier-related test that is currently disabled on i686-linux.
79 coursier
80 # i686-linux: dotnet-sdk not available
81 dotnet-sdk
82 # nodejs can be moved back to the main nativeCheckInputs list once this
83 # issue is fixed: <https://github.com/NixOS/nixpkgs/issues/387658>. When nodejs gets
84 # moved back to the main nativeCheckInputs list, don’t forget to re-enable the
85 # Node.js-related tests that are currently disabled on i686-linux.
86 nodejs
87 ];
88 versionCheckProgramArg = "--version";
89
90 postPatch = ''
91 substituteInPlace pre_commit/resources/hook-tmpl \
92 --subst-var-by pre-commit $out
93 substituteInPlace pre_commit/languages/python.py \
94 --subst-var-by virtualenv ${python3Packages.virtualenv}
95 substituteInPlace pre_commit/languages/node.py \
96 --subst-var-by nodeenv ${python3Packages.nodeenv}
97
98 patchShebangs pre_commit/resources/hook-tmpl
99 '';
100
101 pytestFlags = [
102 "--forked"
103 ];
104
105 preCheck =
106 lib.optionalString (!(stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch64)) ''
107 # Disable outline atomics for rust tests on aarch64-linux.
108 export RUSTFLAGS="-Ctarget-feature=-outline-atomics"
109 ''
110 + ''
111 export GIT_AUTHOR_NAME=test GIT_COMMITTER_NAME=test \
112 GIT_AUTHOR_EMAIL=test@example.com GIT_COMMITTER_EMAIL=test@example.com \
113 VIRTUALENV_NO_DOWNLOAD=1 PRE_COMMIT_NO_CONCURRENCY=1
114 ''
115 + lib.optionalString (!i686Linux) ''
116 # Resolve `.NET location: Not found` errors for dotnet tests
117 export DOTNET_ROOT="${dotnet-sdk}/share/dotnet"
118 ''
119 + ''
120 git init -b master
121
122 python -m venv --system-site-packages venv
123 source "$PWD/venv/bin/activate"
124 '';
125
126 postCheck = ''
127 deactivate
128 '';
129
130 disabledTests = [
131 # ERROR: The install method you used for conda--probably either `pip install conda`
132 # or `easy_install conda`--is not compatible with using conda as an application.
133 "test_conda_"
134 "test_local_conda_"
135
136 # /build/pytest-of-nixbld/pytest-0/test_install_ruby_with_version0/rbenv-2.7.2/libexec/rbenv-init:
137 # /usr/bin/env: bad interpreter: No such file or directory
138 "test_ruby_"
139
140 # network
141 "test_additional_dependencies_roll_forward"
142 "test_additional_golang_dependencies_installed"
143 "test_additional_node_dependencies_installed"
144 "test_additional_rust_cli_dependencies_installed"
145 "test_additional_rust_lib_dependencies_installed"
146 "test_automatic_toolchain_switching"
147 "test_coursier_hook"
148 "test_coursier_hook_additional_dependencies"
149 "test_dart"
150 "test_dart_additional_deps"
151 "test_dart_additional_deps_versioned"
152 "test_during_commit_all"
153 "test_golang_default_version"
154 "test_golang_hook"
155 "test_golang_hook_still_works_when_gobin_is_set"
156 "test_golang_infer_go_version_default"
157 "test_golang_system"
158 "test_golang_versioned"
159 "test_language_version_with_rustup"
160 "test_installs_rust_missing_rustup"
161 "test_installs_without_links_outside_env"
162 "test_julia_hook"
163 "test_julia_repo_local"
164 "test_local_golang_additional_deps"
165 "test_lua"
166 "test_lua_additional_dependencies"
167 "test_node_additional_deps"
168 "test_node_hook_versions"
169 "test_perl_additional_dependencies"
170 "test_r_hook"
171 "test_r_inline"
172 "test_r_inline_hook"
173 "test_r_local_with_additional_dependencies_hook"
174 "test_r_with_additional_dependencies_hook"
175 "test_run_a_node_hook_default_version"
176 "test_run_lib_additional_dependencies"
177 "test_run_versioned_node_hook"
178 "test_rust_cli_additional_dependencies"
179 "test_swift_language"
180 "test_run_example_executable"
181 "test_run_dep"
182
183 # i don't know why these fail
184 "test_install_existing_hooks_no_overwrite"
185 "test_installed_from_venv"
186 "test_uninstall_restores_legacy_hooks"
187 "test_dotnet_"
188 "test_health_check_"
189
190 # Expects `git commit` to fail when `pre-commit` is not in the `$PATH`,
191 # but we use an absolute path so it's not an issue.
192 "test_environment_not_sourced"
193
194 # Docker required
195 "test_docker_"
196 ]
197 ++ lib.optionals i686Linux [
198 # From coursier_test.py:
199 "test_error_if_no_deps_or_channel"
200 # From node_test.py:
201 "test_healthy_system_node"
202 "test_unhealthy_if_system_node_goes_missing"
203 "test_node_hook_system"
204 "test_node_with_user_config_set"
205 ];
206
207 pythonImportsCheck = [
208 "pre_commit"
209 ];
210
211 # add gitMinimal as fallback, if git is not installed
212 preFixup = ''
213 makeWrapperArgs+=(--suffix PATH : ${lib.makeBinPath [ gitMinimal ]})
214 '';
215
216 passthru.tests = callPackage ./tests.nix {
217 inherit gitMinimal pre-commit;
218 };
219
220 meta = {
221 description = "Framework for managing and maintaining multi-language pre-commit hooks";
222 homepage = "https://pre-commit.com/";
223 changelog = "https://github.com/pre-commit/pre-commit/blob/v${version}/CHANGELOG.md";
224 license = lib.licenses.mit;
225 maintainers = with lib.maintainers; [ borisbabic ];
226 mainProgram = "pre-commit";
227 };
228}