mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-01-13 12:30:08 -06:00
Implement no-dependency system and script hook types. Closes #39.
This commit is contained in:
@@ -23,4 +23,5 @@
|
||||
name: My Bash Based Hook
|
||||
description: This is a hook that uses grep to validate some stuff
|
||||
entry: ./my_grep_based_hook.sh
|
||||
language: script
|
||||
expected_return_value: 1
|
||||
|
||||
@@ -6,6 +6,7 @@ import sys
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit.clientlib.validate_base import get_validator
|
||||
from pre_commit.languages.all import all_languages
|
||||
from pre_commit.util import entry
|
||||
|
||||
|
||||
@@ -25,7 +26,7 @@ MANIFEST_JSON_SCHEMA = {
|
||||
'language': {'type': 'string'},
|
||||
'expected_return_value': {'type': 'number'},
|
||||
},
|
||||
'required': ['id', 'name', 'entry'],
|
||||
'required': ['id', 'name', 'entry', 'language'],
|
||||
},
|
||||
}
|
||||
|
||||
@@ -35,13 +36,13 @@ def additional_manifest_check(obj):
|
||||
language = hook_config.get('language')
|
||||
|
||||
if language is not None and not any(
|
||||
language.startswith(lang) for lang in C.SUPPORTED_LANGUAGES
|
||||
language.startswith(lang) for lang in all_languages
|
||||
):
|
||||
raise InvalidManifestError(
|
||||
'Expected language {0} for {1} to start with one of {2!r}'.format(
|
||||
hook_config['id'],
|
||||
hook_config['language'],
|
||||
C.SUPPORTED_LANGUAGES,
|
||||
all_languages,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -5,13 +5,6 @@ HOOKS_WORKSPACE = '.pre-commit-files'
|
||||
|
||||
MANIFEST_FILE = 'hooks.yaml'
|
||||
|
||||
SUPPORTED_LANGUAGES = set([
|
||||
'python',
|
||||
'ruby',
|
||||
'node',
|
||||
])
|
||||
|
||||
|
||||
YAML_DUMP_KWARGS = {
|
||||
'default_flow_style': False,
|
||||
'indent': 4,
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
from pre_commit.languages import node
|
||||
from pre_commit.languages import python
|
||||
from pre_commit.languages import ruby
|
||||
from pre_commit.languages import script
|
||||
from pre_commit.languages import system
|
||||
|
||||
# A language implements the following two functions in its module:
|
||||
#
|
||||
@@ -29,4 +31,9 @@ languages = {
|
||||
'node': node,
|
||||
'python': python,
|
||||
'ruby': ruby,
|
||||
'script': script,
|
||||
'system': system,
|
||||
}
|
||||
|
||||
|
||||
all_languages = languages.keys()
|
||||
|
||||
13
pre_commit/languages/script.py
Normal file
13
pre_commit/languages/script.py
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
def install_environment(repo_cmd_runner):
|
||||
"""Installation for script type is a noop."""
|
||||
pass
|
||||
|
||||
|
||||
def run_hook(repo_cmd_runner, hook, file_args):
|
||||
return repo_cmd_runner.run(
|
||||
['xargs', '{{prefix}}{0}'.format(hook['entry'])] + hook.get('args', []),
|
||||
# TODO: this is duplicated in pre_commit/languages/helpers.py
|
||||
stdin='\n'.join(list(file_args) + ['']),
|
||||
retcode=None,
|
||||
)
|
||||
13
pre_commit/languages/system.py
Normal file
13
pre_commit/languages/system.py
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
def install_environment(repo_cmd_runner):
|
||||
"""Installation for system type is a noop."""
|
||||
pass
|
||||
|
||||
|
||||
def run_hook(repo_cmd_runner, hook, file_args):
|
||||
return repo_cmd_runner.run(
|
||||
['xargs', hook['entry']] + hook.get('args', []),
|
||||
# TODO: this is duplicated in pre_commit/languages/helpers.py
|
||||
stdin='\n'.join(list(file_args) + ['']),
|
||||
retcode=None,
|
||||
)
|
||||
@@ -82,9 +82,8 @@ class Repository(object):
|
||||
"""
|
||||
self.require_created()
|
||||
repo_cmd_runner = self.get_cmd_runner(cmd_runner)
|
||||
for language in C.SUPPORTED_LANGUAGES:
|
||||
if language in self.languages:
|
||||
languages[language].install_environment(repo_cmd_runner)
|
||||
for language in self.languages:
|
||||
languages[language].install_environment(repo_cmd_runner)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_checkout(self):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- id: prints_cwd
|
||||
name: Prints Cwd
|
||||
entry: prints_cwd
|
||||
language: python
|
||||
entry: pwd
|
||||
language: system
|
||||
|
||||
4
testing/resources/script_hooks_repo/bin/hook.sh
Executable file
4
testing/resources/script_hooks_repo/bin/hook.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo $@
|
||||
echo 'Hello World'
|
||||
4
testing/resources/script_hooks_repo/hooks.yaml
Normal file
4
testing/resources/script_hooks_repo/hooks.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
- id: bash_hook
|
||||
name: Bash hook
|
||||
entry: bin/hook.sh
|
||||
language: script
|
||||
@@ -45,7 +45,7 @@ def is_valid_according_to_schema(obj, schema):
|
||||
|
||||
@pytest.mark.parametrize(('manifest_obj', 'expected'), (
|
||||
([], False),
|
||||
([{'id': 'a', 'name': 'b', 'entry': 'c'}], True),
|
||||
([{'id': 'a', 'name': 'b', 'entry': 'c', 'language': 'python'}], True),
|
||||
(
|
||||
[{
|
||||
'id': 'a',
|
||||
|
||||
@@ -59,45 +59,36 @@ def prints_cwd_repo(dummy_git_repo):
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
def config_for_node_hooks_repo(node_hooks_repo):
|
||||
def script_hooks_repo(dummy_git_repo):
|
||||
yield _make_repo(dummy_git_repo, 'script_hooks_repo')
|
||||
|
||||
|
||||
def _make_config(path, hook_id, file_regex):
|
||||
config = {
|
||||
'repo': node_hooks_repo,
|
||||
'sha': git.get_head_sha(node_hooks_repo),
|
||||
'hooks': [{
|
||||
'id': 'foo',
|
||||
'files': '\.js$',
|
||||
}],
|
||||
'repo': path,
|
||||
'sha': git.get_head_sha(path),
|
||||
'hooks': [{'id': hook_id, 'files': file_regex}],
|
||||
}
|
||||
jsonschema.validate([config], CONFIG_JSON_SCHEMA)
|
||||
validate_config_extra([config])
|
||||
yield config
|
||||
return config
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
def config_for_node_hooks_repo(node_hooks_repo):
|
||||
yield _make_config(node_hooks_repo, 'foo', '\.js$')
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
def config_for_python_hooks_repo(python_hooks_repo):
|
||||
config = {
|
||||
'repo': python_hooks_repo,
|
||||
'sha': git.get_head_sha(python_hooks_repo),
|
||||
'hooks': [{
|
||||
'id': 'foo',
|
||||
'files': '\.py$',
|
||||
}],
|
||||
}
|
||||
jsonschema.validate([config], CONFIG_JSON_SCHEMA)
|
||||
validate_config_extra([config])
|
||||
yield config
|
||||
yield _make_config(python_hooks_repo, 'foo', '\.py$')
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
def config_for_prints_cwd_repo(prints_cwd_repo):
|
||||
config = {
|
||||
'repo': prints_cwd_repo,
|
||||
'sha': git.get_head_sha(prints_cwd_repo),
|
||||
'hooks': [{
|
||||
'id': 'prints_cwd',
|
||||
'files': '\.py$',
|
||||
}],
|
||||
}
|
||||
jsonschema.validate([config], CONFIG_JSON_SCHEMA)
|
||||
validate_config_extra([config])
|
||||
yield config
|
||||
yield _make_config(prints_cwd_repo, 'prints_cwd', '^$')
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
def config_for_script_hooks_repo(script_hooks_repo):
|
||||
yield _make_config(script_hooks_repo, 'bash_hook', '^$')
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
|
||||
import pytest
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit.languages.all import all_languages
|
||||
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)
|
||||
@pytest.mark.parametrize('language', all_languages)
|
||||
def test_all_languages_support_interface(language):
|
||||
assert hasattr(languages[language], 'install_environment')
|
||||
assert hasattr(languages[language], 'run_hook')
|
||||
|
||||
@@ -67,6 +67,7 @@ def test_run_a_hook_lots_of_files(config_for_python_hooks_repo):
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_cwd_of_hook(config_for_prints_cwd_repo):
|
||||
# Note: this doubles as a test for `system` hooks
|
||||
repo = Repository(config_for_prints_cwd_repo)
|
||||
ret = repo.run_hook(
|
||||
PrefixedCommandRunner(C.HOOKS_WORKSPACE), 'prints_cwd', [],
|
||||
@@ -89,6 +90,17 @@ def test_run_a_node_hook(config_for_node_hooks_repo):
|
||||
assert ret[1] == 'Hello World\n'
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_run_a_script_hook(config_for_script_hooks_repo):
|
||||
repo = Repository(config_for_script_hooks_repo)
|
||||
ret = repo.run_hook(
|
||||
PrefixedCommandRunner(C.HOOKS_WORKSPACE), 'bash_hook', ['bar'],
|
||||
)
|
||||
|
||||
assert ret[0] == 0
|
||||
assert ret[1] == 'bar\nHello World\n'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_repo_config():
|
||||
config = {
|
||||
|
||||
Reference in New Issue
Block a user