OMG we're running a hook

This commit is contained in:
Anthony Sottile
2014-03-13 22:12:33 -07:00
parent 47bad120e4
commit 871ab4d72f
11 changed files with 105 additions and 25 deletions

View File

@@ -5,8 +5,8 @@ HOOKS_WORKSPACE = '.pre-commit-files'
MANIFEST_FILE = 'manifest.yaml'
SUPPORTED_LANGUAGES = [
SUPPORTED_LANGUAGES = set([
'python',
'ruby',
'node',
]
])

View File

View File

@@ -0,0 +1,24 @@
from pre_commit.languages import node
from pre_commit.languages import python
from pre_commit.languages import ruby
# A language implements the following two functions in its module:
#
# def install_environment():
# """Installs a repository in the given repository. Note that the current
# working directory will already be inside the repository.
# """
#
# def run_hook(hook, file_args):
# """Runs a hook and returns the returncode and output of running that hook.
#
# Returns:
# (returncode, stdout, stderr)
# """
languages = {
'node': node,
'python': python,
'ruby': ruby,
}

View File

@@ -0,0 +1,7 @@
def install_environment():
raise NotImplementedError
def run_hook(hook, file_args):
raise NotImplementedError

View File

@@ -0,0 +1,32 @@
import contextlib
from plumbum import local
from plumbum.machines.session import ShellSession
PY_ENV = 'py_env'
@contextlib.contextmanager
def in_env():
with ShellSession(local['bash'].popen()) as env:
env.run('source {0}/bin/activate'.format(PY_ENV))
yield env
def install_environment():
assert local.path('setup.py').exists()
# Install a virtualenv
local['virtualenv'][PY_ENV]()
with in_env() as env:
# Run their setup.py
env.run('pip install .')
def run_hook(hook, file_args):
with in_env() as env:
# TODO: batch filenames
return env.run(
' '.join([hook['entry']] + hook.get('args', []) + list(file_args)),
retcode=None,
)

View File

@@ -0,0 +1,7 @@
def install_environment():
raise NotImplementedError
def run_hook(hook, file_args):
raise NotImplementedError

View File

@@ -5,30 +5,10 @@ from plumbum import local
import pre_commit.constants as C
from pre_commit.clientlib.validate_manifest import validate_manifest
from pre_commit.hooks_workspace import in_hooks_workspace
from pre_commit.languages.all import languages
from pre_commit.util import cached_property
def install_python(repo):
assert local.path('setup.py').exists()
local['virtualenv']['py_env']()
local['bash']['-c', 'source py_env/bin/activate && pip install .']()
def install_ruby(repo):
raise NotImplementedError
def install_node(repo):
raise NotImplementedError
language_to_repo_setup_strategy = {
'python': install_python,
'ruby': install_ruby,
'node': install_node,
}
class Repository(object):
def __init__(self, repo_config):
self.repo_config = repo_config
@@ -84,4 +64,9 @@ class Repository(object):
with self.in_checkout():
for language in C.SUPPORTED_LANGUAGES:
if language in self.languages:
language_to_repo_setup_strategy[language](self)
languages[language].install_environment()
def run_hook(self, hook_id, file_args):
with self.in_checkout():
hook = self.hooks[hook_id]
return languages[hook['language']].run_hook(hook, file_args)

View File

@@ -66,6 +66,7 @@ setup(
local.path('__init__.py').write('')
local.path('main.py').write("""
def func():
print 'Hello World'
return 0
""")

View File

View File

@@ -0,0 +1,15 @@
import pytest
import pre_commit.constants as C
from pre_commit.languages.all import languages
def test_all_languages_have_repo_setups():
assert set(languages.keys()) == C.SUPPORTED_LANGUAGES
@pytest.mark.parametrize('language', C.SUPPORTED_LANGUAGES)
def test_all_languages_support_interface(language):
assert hasattr(languages[language], 'install_environment')
assert hasattr(languages[language], 'run_hook')

View File

@@ -30,7 +30,6 @@ def test_create_repo_in_env(dummy_repo_config, dummy_git_repo):
@pytest.mark.integration
def test_install_python_repo_in_env(python_pre_commit_git_repo, config_for_python_pre_commit_git_repo):
repo = Repository(config_for_python_pre_commit_git_repo)
# TODO: do we need create here?
repo.install()
assert os.path.exists(
@@ -43,6 +42,16 @@ def test_install_python_repo_in_env(python_pre_commit_git_repo, config_for_pytho
)
@pytest.mark.integration
def test_run_a_hook_omg(config_for_python_pre_commit_git_repo):
repo = Repository(config_for_python_pre_commit_git_repo)
repo.install()
ret = repo.run_hook('foo', [])
assert ret[0] == 0
assert ret[1] == 'Hello World\n'
@pytest.fixture
def mock_repo_config():
config = {