Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions pre_commit/commands/install_uninstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import os
import os.path
import stat
import sys

from pre_commit.logging_handler import LoggingHandler
from pre_commit.util import resource_filename
Expand All @@ -15,12 +16,13 @@


# This is used to identify the hook file we install
PREVIOUS_IDENTIFYING_HASHES = [
PREVIOUS_IDENTIFYING_HASHES = (
'4d9958c90bc262f47553e2c073f14cfe',
'd8ee923c46731b42cd95cc869add4062',
]
)


IDENTIFYING_HASH = '4d9958c90bc262f47553e2c073f14cfe'
IDENTIFYING_HASH = '49fd668cb42069aa1b6048464be5d395'


def is_our_pre_commit(filename):
Expand Down Expand Up @@ -63,8 +65,11 @@ def install(runner, overwrite=False, hooks=False):
)
)

with open(runner.pre_commit_path, 'w') as pre_commit_file_obj:
pre_commit_file_obj.write(open(pre_commit_file).read())
with io.open(runner.pre_commit_path, 'w') as pre_commit_file_obj:
contents = io.open(pre_commit_file).read().format(
sys_executable=sys.executable,
)
pre_commit_file_obj.write(contents)
make_executable(runner.pre_commit_path)

print('pre-commit installed at {0}'.format(runner.pre_commit_path))
Expand Down
3 changes: 2 additions & 1 deletion pre_commit/output.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import unicode_literals

import os
import subprocess
import sys

Expand All @@ -10,7 +11,7 @@
# TODO: smell: import side-effects
COLS = int(
subprocess.Popen(
['tput', 'cols'], stdout=subprocess.PIPE
['tput', 'cols'], stdout=subprocess.PIPE, stderr=open(os.devnull, 'w'),
).communicate()[0] or
# Default in the case of no terminal
80
Expand Down
20 changes: 16 additions & 4 deletions pre_commit/resources/pre-commit-hook
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
#!/usr/bin/env bash
# This is a randomish md5 to identify this script
# 4d9958c90bc262f47553e2c073f14cfe
# 49fd668cb42069aa1b6048464be5d395

pushd `dirname $0` > /dev/null
HERE=`pwd`
popd > /dev/null

retv=0

ENV_PYTHON='{sys_executable}'

which pre-commit >& /dev/null
WHICH_RETV=$?
"$ENV_PYTHON" -c 'import pre_commit.main' >& /dev/null
ENV_PYTHON_RETV=$?
python -c 'import pre_commit.main' >& /dev/null
PYTHON_RETV=$?

if [ $WHICH_RETV -ne 0 ] && [ $PYTHON_RETV -ne 0 ]; then

if ((
(WHICH_RETV != 0) &&
(ENV_PYTHON_RETV != 0) &&
(PYTHON_RETV != 0)
)); then
echo '`pre-commit` not found. Did you forget to activate your virtualenv?'
exit 1
fi
Expand All @@ -29,15 +38,18 @@ fi


# Run pre-commit
if [ $WHICH_RETV -eq 0 ]; then
if ((WHICH_RETV == 0)); then
pre-commit
PRE_COMMIT_RETV=$?
elif ((ENV_PYTHON_RETV == 0)); then
"$ENV_PYTHON" -m pre_commit.main
PRE_COMMIT_RETV=$?
else
python -m pre_commit.main
PRE_COMMIT_RETV=$?
fi

if [ $PRE_COMMIT_RETV -ne 0 ]; then
if ((PRE_COMMIT_RETV != 0)); then
retv=1
fi

Expand Down
34 changes: 29 additions & 5 deletions tests/commands/install_uninstall_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
from __future__ import unicode_literals

import io
import mock
import os
import os.path
import re
import subprocess
import stat
import sys
from plumbum import local

from pre_commit.commands.install_uninstall import IDENTIFYING_HASH
Expand Down Expand Up @@ -53,7 +55,9 @@ def test_install_pre_commit(tmpdir_factory):
assert os.path.exists(runner.pre_commit_path)
pre_commit_contents = io.open(runner.pre_commit_path).read()
pre_commit_script = resource_filename('pre-commit-hook')
expected_contents = io.open(pre_commit_script).read()
expected_contents = io.open(pre_commit_script).read().format(
sys_executable=sys.executable,
)
assert pre_commit_contents == expected_contents
stat_result = os.stat(runner.pre_commit_path)
assert stat_result.st_mode & (stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
Expand All @@ -76,12 +80,17 @@ def test_uninstall(tmpdir_factory):
assert not os.path.exists(runner.pre_commit_path)


def _get_commit_output(tmpdir_factory, touch_file='foo', home=None):
def _get_commit_output(
tmpdir_factory,
touch_file='foo',
home=None,
env_base=os.environ,
):
local['touch'](touch_file)
local['git']('add', touch_file)
# Don't want to write to home directory
home = home or tmpdir_factory.get()
env = dict(os.environ, **{'PRE_COMMIT_HOME': home})
env = dict(env_base, **{'PRE_COMMIT_HOME': home})
return local['git'].run(
['commit', '-m', 'Commit!', '--allow-empty'],
# git commit puts pre-commit to stderr
Expand Down Expand Up @@ -136,11 +145,12 @@ def test_install_idempotent(tmpdir_factory):
def test_environment_not_sourced(tmpdir_factory):
path = make_consuming_repo(tmpdir_factory, 'script_hooks_repo')
with local.cwd(path):
assert install(Runner(path)) == 0
# Patch the executable to simulate rming virtualenv
with mock.patch.object(sys, 'executable', '/bin/false'):
assert install(Runner(path)) == 0

ret, stdout, stderr = local['git'].run(
['commit', '--allow-empty', '-m', 'foo'],
# XXX: 'HOME' makes this test pass on OSX
env={'HOME': os.environ['HOME']},
retcode=None,
)
Expand Down Expand Up @@ -362,3 +372,17 @@ def test_installs_hooks_with_hooks_True(

assert ret == 0
assert PRE_INSTALLED.match(output)


def test_installed_from_venv(tmpdir_factory):
path = make_consuming_repo(tmpdir_factory, 'script_hooks_repo')
with local.cwd(path):
install(Runner(path))
# No environment so pre-commit is not on the path when running!
# Should still pick up the python from when we installed
ret, output = _get_commit_output(
tmpdir_factory,
env_base={'HOME': os.environ['HOME']},
)
assert ret == 0
assert NORMAL_PRE_COMMIT_RUN.match(output)