Tests pass on windows

This commit is contained in:
Anthony Sottile 2015-01-18 19:45:44 -08:00
parent 56e5c4eb2d
commit 143ed94500
21 changed files with 224 additions and 109 deletions

View file

@ -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

View file

@ -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')

View file

@ -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:

View file

@ -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):

View file

@ -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):

View file

@ -31,3 +31,4 @@ class LoggingHandler(logging.Handler):
record.getMessage(),
)
)
sys.stdout.flush()

View file

@ -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

View file

@ -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(

View file

@ -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'),
)

View file

@ -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)