mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
Tests pass on windows
This commit is contained in:
parent
56e5c4eb2d
commit
143ed94500
21 changed files with 224 additions and 109 deletions
|
|
@ -2,11 +2,12 @@ from __future__ import print_function
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import os.path
|
||||
import shutil
|
||||
|
||||
from pre_commit.util import rmtree
|
||||
|
||||
|
||||
def clean(runner):
|
||||
if os.path.exists(runner.store.directory):
|
||||
shutil.rmtree(runner.store.directory)
|
||||
rmtree(runner.store.directory)
|
||||
print('Cleaned {0}.'.format(runner.store.directory))
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -6,5 +6,17 @@ PY3 = str is not bytes
|
|||
|
||||
if PY2: # pragma: no cover (PY2 only)
|
||||
text = unicode # flake8: noqa
|
||||
|
||||
def n(s):
|
||||
if isinstance(s, bytes):
|
||||
return s
|
||||
else:
|
||||
return s.encode('UTF-8')
|
||||
else: # pragma: no cover (PY3 only)
|
||||
text = str
|
||||
|
||||
def n(s):
|
||||
if isinstance(s, text):
|
||||
return s
|
||||
else:
|
||||
return s.decode('UTF-8')
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ logger = logging.getLogger('pre_commit')
|
|||
|
||||
def get_root():
|
||||
path = os.getcwd()
|
||||
while len(path) > 1:
|
||||
while path != os.path.normpath(os.path.join(path, '../')):
|
||||
if os.path.exists(os.path.join(path, '.git')):
|
||||
return path
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ ENVIRONMENT_DIR = 'node_env'
|
|||
class NodeEnv(helpers.Environment):
|
||||
@property
|
||||
def env_prefix(self):
|
||||
return '. {{prefix}}{0}/bin/activate &&'.format(ENVIRONMENT_DIR)
|
||||
return ". '{{prefix}}{0}/bin/activate' &&".format(ENVIRONMENT_DIR)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
@ -37,7 +37,7 @@ def install_environment(repo_cmd_runner, version='default'):
|
|||
repo_cmd_runner.run(cmd)
|
||||
|
||||
with in_env(repo_cmd_runner) as node_env:
|
||||
node_env.run('cd {prefix} && npm install -g')
|
||||
node_env.run("cd '{prefix}' && npm install -g")
|
||||
|
||||
|
||||
def run_hook(repo_cmd_runner, hook, file_args):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import contextlib
|
||||
import distutils.spawn
|
||||
import os
|
||||
|
||||
import virtualenv
|
||||
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.util import clean_path_on_failure
|
||||
|
|
@ -12,7 +16,12 @@ ENVIRONMENT_DIR = 'py_env'
|
|||
class PythonEnv(helpers.Environment):
|
||||
@property
|
||||
def env_prefix(self):
|
||||
return '. {{prefix}}{0}/bin/activate &&'.format(ENVIRONMENT_DIR)
|
||||
return ". '{{prefix}}{0}activate' &&".format(
|
||||
virtualenv.path_locations(
|
||||
ENVIRONMENT_DIR,
|
||||
)[-1].rstrip(os.sep) + os.sep,
|
||||
'activate',
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
@ -20,6 +29,15 @@ def in_env(repo_cmd_runner):
|
|||
yield PythonEnv(repo_cmd_runner)
|
||||
|
||||
|
||||
def norm_version(version):
|
||||
if os.name == 'nt': # pragma: no cover (windows)
|
||||
if not distutils.spawn.find_executable(version):
|
||||
# The default place for python on windows is:
|
||||
# C:\PythonXX\python.exe
|
||||
version = r'C:\{0}\python.exe'.format(version.replace('.', ''))
|
||||
return version
|
||||
|
||||
|
||||
def install_environment(repo_cmd_runner, version='default'):
|
||||
assert repo_cmd_runner.exists('setup.py')
|
||||
|
||||
|
|
@ -27,10 +45,10 @@ def install_environment(repo_cmd_runner, version='default'):
|
|||
with clean_path_on_failure(repo_cmd_runner.path(ENVIRONMENT_DIR)):
|
||||
venv_cmd = ['virtualenv', '{{prefix}}{0}'.format(ENVIRONMENT_DIR)]
|
||||
if version != 'default':
|
||||
venv_cmd.extend(['-p', version])
|
||||
venv_cmd.extend(['-p', norm_version(version)])
|
||||
repo_cmd_runner.run(venv_cmd)
|
||||
with in_env(repo_cmd_runner) as env:
|
||||
env.run('cd {prefix} && pip install .')
|
||||
env.run("cd '{prefix}' && pip install .")
|
||||
|
||||
|
||||
def run_hook(repo_cmd_runner, hook, file_args):
|
||||
|
|
|
|||
|
|
@ -31,3 +31,4 @@ class LoggingHandler(logging.Handler):
|
|||
record.getMessage(),
|
||||
)
|
||||
)
|
||||
sys.stdout.flush()
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@ from __future__ import print_function
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import os.path
|
||||
import shutil
|
||||
|
||||
from pre_commit import five
|
||||
from pre_commit.util import cmd_output
|
||||
from pre_commit.util import cwd
|
||||
from pre_commit.util import rmtree
|
||||
from pre_commit.util import tarfile_open
|
||||
from pre_commit.util import tmpdir
|
||||
|
||||
|
|
@ -50,11 +51,9 @@ def make_archive(name, repo, ref, destdir):
|
|||
# We don't want the '.git' directory
|
||||
# It adds a bunch of size to the archive and we don't use it at
|
||||
# runtime
|
||||
shutil.rmtree(os.path.join(tempdir, '.git'))
|
||||
rmtree(os.path.join(tempdir, '.git'))
|
||||
|
||||
# XXX: py2.6 derps if filename is unicode while writing
|
||||
# XXX: str() is used to preserve behavior in py3
|
||||
with tarfile_open(str(output_path), 'w|gz') as tf:
|
||||
with tarfile_open(five.n(output_path), 'w|gz') as tf:
|
||||
tf.add(tempdir, name)
|
||||
|
||||
return output_path
|
||||
|
|
|
|||
|
|
@ -8,13 +8,16 @@ from pre_commit import five
|
|||
|
||||
|
||||
# TODO: smell: import side-effects
|
||||
COLS = int(
|
||||
subprocess.Popen(
|
||||
['tput', 'cols'], stdout=subprocess.PIPE,
|
||||
).communicate()[0] or
|
||||
# Default in the case of no terminal
|
||||
80
|
||||
)
|
||||
try:
|
||||
COLS = int(
|
||||
subprocess.Popen(
|
||||
['tput', 'cols'], stdout=subprocess.PIPE,
|
||||
).communicate()[0] or
|
||||
# Default in the case of no terminal
|
||||
80
|
||||
)
|
||||
except OSError: # pragma: no cover (windows)
|
||||
COLS = 80
|
||||
|
||||
|
||||
def get_hook_message(
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ def _get_default_directory():
|
|||
"""
|
||||
return os.environ.get(
|
||||
'PRE_COMMIT_HOME',
|
||||
os.path.join(os.environ['HOME'], '.pre-commit'),
|
||||
os.path.join(os.path.expanduser('~'), '.pre-commit'),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,20 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import contextlib
|
||||
import errno
|
||||
import functools
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import tarfile
|
||||
import tempfile
|
||||
|
||||
import pkg_resources
|
||||
|
||||
from pre_commit import five
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def cwd(path):
|
||||
|
|
@ -46,7 +50,7 @@ def clean_path_on_failure(path):
|
|||
yield
|
||||
except BaseException:
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
rmtree(path)
|
||||
raise
|
||||
|
||||
|
||||
|
|
@ -78,7 +82,7 @@ def tmpdir():
|
|||
try:
|
||||
yield tempdir
|
||||
finally:
|
||||
shutil.rmtree(tempdir)
|
||||
rmtree(tempdir)
|
||||
|
||||
|
||||
def resource_filename(filename):
|
||||
|
|
@ -135,6 +139,13 @@ def cmd_output(*cmd, **kwargs):
|
|||
if stdin is not None:
|
||||
stdin = stdin.encode('UTF-8')
|
||||
|
||||
# py2/py3 on windows are more strict about the types here
|
||||
cmd = [five.n(arg) for arg in cmd]
|
||||
kwargs['env'] = dict(
|
||||
(five.n(key), five.n(value))
|
||||
for key, value in kwargs.pop('env', {}).items()
|
||||
) or None
|
||||
|
||||
popen_kwargs.update(kwargs)
|
||||
proc = __popen(cmd, **popen_kwargs)
|
||||
stdout, stderr = proc.communicate(stdin)
|
||||
|
|
@ -150,3 +161,15 @@ def cmd_output(*cmd, **kwargs):
|
|||
)
|
||||
|
||||
return proc.returncode, stdout, stderr
|
||||
|
||||
|
||||
def rmtree(path):
|
||||
"""On windows, rmtree fails for readonly dirs."""
|
||||
def handle_remove_readonly(func, path, exc): # pragma: no cover (windows)
|
||||
excvalue = exc[1]
|
||||
if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
|
||||
os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
|
||||
func(path)
|
||||
else:
|
||||
raise
|
||||
shutil.rmtree(path, ignore_errors=False, onerror=handle_remove_readonly)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue