From 8a0dd01c7e985970e62d3ff57841b0b0c485b8a3 Mon Sep 17 00:00:00 2001 From: Paul Hooijenga Date: Wed, 25 Oct 2017 09:35:39 +0200 Subject: [PATCH] Implement check-files-matches-any meta hook --- .../meta_hooks/check_files_matches_any.py | 36 +++++++++++++++++++ pre_commit/repository.py | 7 ++++ tests/commands/run_test.py | 33 +++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 pre_commit/meta_hooks/check_files_matches_any.py diff --git a/pre_commit/meta_hooks/check_files_matches_any.py b/pre_commit/meta_hooks/check_files_matches_any.py new file mode 100644 index 00000000..88b4806f --- /dev/null +++ b/pre_commit/meta_hooks/check_files_matches_any.py @@ -0,0 +1,36 @@ +import re +import sys + +import pre_commit.constants as C +from pre_commit.clientlib import load_config +from pre_commit.git import get_all_files + + +def files_matches_any(filenames, include): + include_re = re.compile(include) + for filename in filenames: + if include_re.search(filename): + return True + return False + + +def check_files_matches_any(config_file=None): + config = load_config(config_file or C.CONFIG_FILE) + files = get_all_files() + files_not_matched = False + + for repo in config['repos']: + for hook in repo['hooks']: + include = hook.get('files', '') + if include and not files_matches_any(files, include): + print( + 'The files pattern for {} does not match any files' + .format(hook['id']) + ) + files_not_matched = True + + return files_not_matched + + +if __name__ == '__main__': + sys.exit(check_files_matches_any()) diff --git a/pre_commit/repository.py b/pre_commit/repository.py index cb53fc85..45389cb4 100644 --- a/pre_commit/repository.py +++ b/pre_commit/repository.py @@ -259,6 +259,13 @@ class MetaRepository(LocalRepository): 'entry': pipes.quote(sys.executable), 'args': ['-m', 'pre_commit.meta_hooks.check_useless_excludes'], }, + 'check-files-matches-any': { + 'name': 'Check hooks match any files', + 'files': '.pre-commit-config.yaml', + 'language': 'system', + 'entry': pipes.quote(sys.executable), + 'args': ['-m', 'pre_commit.meta_hooks.check_files_matches_any'], + }, } @cached_property diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py index 27fa9eea..24771d22 100644 --- a/tests/commands/run_test.py +++ b/tests/commands/run_test.py @@ -735,6 +735,39 @@ def test_useless_exclude_for_hook( ) +def test_files_match_any( + cap_out, repo_with_passing_hook, mock_out_store_directory, +): + config = OrderedDict(( + ('repo', 'meta'), + ( + 'hooks', ( + OrderedDict(( + ('id', 'check-files-matches-any'), + )), + OrderedDict(( + ('id', 'check-useless-excludes'), + ('files', 'foo'), + )), + ), + ), + )) + add_config_to_repo(repo_with_passing_hook, config) + + _test_run( + cap_out, + repo_with_passing_hook, + opts={'all_files': True}, + expected_outputs=[ + b'Check hooks match any files', + b'The files pattern for check-useless-excludes ' + b'does not match any files', + ], + expected_ret=1, + stage=False, + ) + + @pytest.yield_fixture def modified_config_repo(repo_with_passing_hook): with modify_config(repo_with_passing_hook, commit=False) as config: