Skip to content

Commit e622f79

Browse files
committed
port hook template to bash
this avoids some version-specific code in python this also makes the bootstrap script slightly more portable
1 parent ef7b126 commit e622f79

File tree

3 files changed

+20
-49
lines changed

3 files changed

+20
-49
lines changed

pre_commit/commands/install_uninstall.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import itertools
22
import logging
33
import os.path
4+
import shlex
45
import shutil
56
import sys
67
from typing import Optional
@@ -100,19 +101,17 @@ def _install_hook_script(
100101
args = ['hook-impl', f'--config={config_file}', f'--hook-type={hook_type}']
101102
if skip_on_missing_config:
102103
args.append('--skip-on-missing-config')
103-
params = {'INSTALL_PYTHON': sys.executable, 'ARGS': args}
104104

105105
with open(hook_path, 'w') as hook_file:
106106
contents = resource_text('hook-tmpl')
107107
before, rest = contents.split(TEMPLATE_START)
108-
to_template, after = rest.split(TEMPLATE_END)
109-
110-
before = before.replace('#!/usr/bin/env python3', shebang())
108+
_, after = rest.split(TEMPLATE_END)
111109

112110
hook_file.write(before + TEMPLATE_START)
113-
for line in to_template.splitlines():
114-
var = line.split()[0]
115-
hook_file.write(f'{var} = {params[var]!r}\n')
111+
hook_file.write(f'INSTALL_PYTHON={shlex.quote(sys.executable)}\n')
112+
# TODO: python3.8+: shlex.join
113+
args_s = ' '.join(shlex.quote(part) for part in args)
114+
hook_file.write(f'ARGS=({args_s})\n')
116115
hook_file.write(TEMPLATE_END + after)
117116
make_executable(hook_path)
118117

pre_commit/resources/hook-tmpl

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,20 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env bash
22
# File generated by pre-commit: https://pre-commit.com
33
# ID: 138fd403232d2ddd5efb44317e38bf03
4-
import os
5-
import sys
6-
7-
# we try our best, but the shebang of this script is difficult to determine:
8-
# - macos doesn't ship with python3
9-
# - windows executables are almost always `python.exe`
10-
# therefore we continue to support python2 for this small script
11-
if sys.version_info < (3, 3):
12-
from distutils.spawn import find_executable as which
13-
else:
14-
from shutil import which
15-
16-
# work around https://github.com/Homebrew/homebrew-core/issues/30445
17-
os.environ.pop('__PYVENV_LAUNCHER__', None)
184

195
# start templated
20-
INSTALL_PYTHON = ''
21-
ARGS = ['hook-impl']
6+
INSTALL_PYTHON=''
7+
ARGS=(hook-impl)
228
# end templated
23-
ARGS.extend(('--hook-dir', os.path.realpath(os.path.dirname(__file__))))
24-
ARGS.append('--')
25-
ARGS.extend(sys.argv[1:])
26-
27-
DNE = '`pre-commit` not found. Did you forget to activate your virtualenv?'
28-
if os.access(INSTALL_PYTHON, os.X_OK):
29-
CMD = [INSTALL_PYTHON, '-mpre_commit']
30-
elif which('pre-commit'):
31-
CMD = ['pre-commit']
32-
else:
33-
raise SystemExit(DNE)
349

35-
CMD.extend(ARGS)
36-
if sys.platform == 'win32': # https://bugs.python.org/issue19124
37-
import subprocess
10+
HERE="$(cd "$(dirname "$0")" && pwd)"
11+
ARGS+=(--hook-dir "$HERE" -- "$@")
3812

39-
if sys.version_info < (3, 7): # https://bugs.python.org/issue25942
40-
raise SystemExit(subprocess.Popen(CMD).wait())
41-
else:
42-
raise SystemExit(subprocess.call(CMD))
43-
else:
44-
os.execvp(CMD[0], CMD)
13+
if [ -x "$INSTALL_PYTHON" ]; then
14+
exec "$INSTALL_PYTHON" -mpre_commit "${ARGS[@]}"
15+
elif command -v pre-commit; then
16+
exec pre-commit "${ARGS[@]}"
17+
else
18+
echo '`pre-commit` not found. Did you forget to activate your virtualenv?' 1>&2
19+
exit 1
20+
fi

tests/commands/install_uninstall_test.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,7 @@ def test_environment_not_sourced(tempdir_factory, store):
278278
hook = os.path.join(path, '.git/hooks/pre-commit')
279279
with open(hook) as f:
280280
src = f.read()
281-
src = re.sub(
282-
'\nINSTALL_PYTHON =.*\n',
283-
'\nINSTALL_PYTHON = "/dne"\n',
284-
src,
285-
)
281+
src = re.sub('\nINSTALL_PYTHON=.*\n', '\nINSTALL_PYTHON="/dne"\n', src)
286282
with open(hook, 'w') as f:
287283
f.write(src)
288284

0 commit comments

Comments
 (0)