diff --git a/example_pre-commit-config.yaml b/example_pre-commit-config.yaml index 06aa4f12..bb921c6a 100644 --- a/example_pre-commit-config.yaml +++ b/example_pre-commit-config.yaml @@ -5,10 +5,10 @@ hooks: - id: pyflakes - files: '*.py' + files: '\.py$' - id: jslint - files: '*.js' + files: '\.js$' - id: trim_trailing_whitespace - files: '*.py' \ No newline at end of file + files: '\.py$' diff --git a/pre_commit/clientlib/validate_config.py b/pre_commit/clientlib/validate_config.py index 2938c7f4..f77d10f5 100644 --- a/pre_commit/clientlib/validate_config.py +++ b/pre_commit/clientlib/validate_config.py @@ -2,6 +2,7 @@ from __future__ import print_function import argparse +import re import pre_commit.constants as C from pre_commit.clientlib.validate_base import get_validator @@ -41,10 +42,24 @@ CONFIG_JSON_SCHEMA = { } +def validate_config_extra(config): + for repo in config: + for hook in repo['hooks']: + try: + re.compile(hook['files']) + except re.error: + raise InvalidConfigError( + 'Invalid file regex at {0}, {1}: {2}'.format( + repo['repo'], hook['id'], hook['files'], + ) + ) + + validate_config = get_validator( C.CONFIG_FILE, CONFIG_JSON_SCHEMA, InvalidConfigError, + additional_validation_strategy=validate_config_extra, ) @@ -69,4 +84,4 @@ def run(argv): print(str(e.args[1])) return 1 - return 0 \ No newline at end of file + return 0 diff --git a/tests/clientlib/validate_config_test.py b/tests/clientlib/validate_config_test.py index 7f8baf16..bf80793f 100644 --- a/tests/clientlib/validate_config_test.py +++ b/tests/clientlib/validate_config_test.py @@ -4,7 +4,9 @@ import jsonschema.exceptions import pytest from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA +from pre_commit.clientlib.validate_config import InvalidConfigError from pre_commit.clientlib.validate_config import run +from pre_commit.clientlib.validate_config import validate_config_extra def test_returns_0_for_valid_config(): @@ -18,6 +20,7 @@ def test_returns_0_for_out_manifest(): def test_returns_1_for_failing(): assert run(['tests/data/valid_yaml_but_invalid_config.yaml']) == 1 + def is_valid_according_to_schema(obj, schema): try: jsonschema.validate(obj, schema) @@ -58,4 +61,18 @@ def is_valid_according_to_schema(obj, schema): )) def test_is_valid_according_to_schema(manifest_obj, expected): ret = is_valid_according_to_schema(manifest_obj, CONFIG_JSON_SCHEMA) - assert ret is expected \ No newline at end of file + assert ret is expected + + +def test_config_with_failing_regexes_fails(): + with pytest.raises(InvalidConfigError): + # Note the regex '(' is invalid (unbalanced parens) + validate_config_extra( + [{'repo': 'foo', 'hooks': [{'id': 'hook_id', 'files': '('}]}] + ) + + +def test_config_with_ok_regexes_passes(): + validate_config_extra( + [{'repo': 'foo', 'hooks': [{'id': 'hook_id', 'files': '\.py$'}]}] + )