diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py index d30b4472..b52ab39d 100644 --- a/pre_commit/commands/run.py +++ b/pre_commit/commands/run.py @@ -6,18 +6,24 @@ import os import subprocess import sys +from identify.identify import tags_from_path + from pre_commit import color from pre_commit import git from pre_commit import output from pre_commit.output import get_hook_message from pre_commit.staged_files_only import staged_files_only from pre_commit.util import cmd_output +from pre_commit.util import memoize_by_cwd from pre_commit.util import noop_context logger = logging.getLogger('pre_commit') +tags_from_path = memoize_by_cwd(tags_from_path) + + def _get_skips(environ): skips = environ.get('SKIP', '') return {skip.strip() for skip in skips.split(',') if skip.strip()} @@ -37,6 +43,14 @@ def get_changed_files(new, old): )[1].splitlines() +def filter_filenames_by_types(filenames, types): + types = frozenset(types) + return tuple( + filename for filename in filenames + if tags_from_path(filename) >= types + ) + + def get_filenames(args, include_expr, exclude_expr): if args.origin and args.source: getter = git.get_files_matching( @@ -59,6 +73,7 @@ NO_FILES = '(no files to check)' def _run_single_hook(hook, repo, args, skips, cols): filenames = get_filenames(args, hook['files'], hook['exclude']) + filenames = filter_filenames_by_types(filenames, hook['types']) if hook['id'] in skips: output.write(get_hook_message( _hook_msg_start(hook, args.verbose), diff --git a/testing/resources/types_repo/.pre-commit-hooks.yaml b/testing/resources/types_repo/.pre-commit-hooks.yaml new file mode 100644 index 00000000..2e5e4a6c --- /dev/null +++ b/testing/resources/types_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: python-files + name: Python files + entry: bin/hook.sh + language: script + types: [python] diff --git a/testing/resources/types_repo/bin/hook.sh b/testing/resources/types_repo/bin/hook.sh new file mode 100755 index 00000000..bdade513 --- /dev/null +++ b/testing/resources/types_repo/bin/hook.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +echo $@ +exit 1 diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py index d8522da4..87031419 100644 --- a/tests/commands/run_test.py +++ b/tests/commands/run_test.py @@ -153,6 +153,19 @@ def test_hook_that_modifies_but_returns_zero( ) +def test_types_hook_repository( + cap_out, tempdir_factory, mock_out_store_directory, +): + git_path = make_consuming_repo(tempdir_factory, 'types_repo') + with cwd(git_path): + stage_a_file('bar.py') + stage_a_file('bar.notpy') + ret, printed = _do_run(cap_out, git_path, _get_opts()) + assert ret == 1 + assert b'bar.py' in printed + assert b'bar.notpy' not in printed + + def test_show_diff_on_failure( capfd, cap_out, tempdir_factory, mock_out_store_directory, ):