From 62f13aea5614b972b5b548c385891301f986f740 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 31 Jul 2014 08:37:37 -0700 Subject: [PATCH] Allow multiple hooks with same id in .pre-commit-config.yaml --- .coveragerc | 2 ++ pre_commit/commands/autoupdate.py | 2 +- pre_commit/commands/run.py | 21 +++++++++++---------- pre_commit/repository.py | 10 ++++------ tests/repository_test.py | 13 ++++++++----- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/.coveragerc b/.coveragerc index 97e92775..7c462b3c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -7,6 +7,8 @@ omit = /usr/* */tmp* setup.py + # Don't complain if non-runnable code isn't run + */__main__.py [report] exclude_lines = diff --git a/pre_commit/commands/autoupdate.py b/pre_commit/commands/autoupdate.py index ffea0a2f..b2973270 100644 --- a/pre_commit/commands/autoupdate.py +++ b/pre_commit/commands/autoupdate.py @@ -43,7 +43,7 @@ def _update_repository(repo_config, runner): new_repo = Repository.create(new_config, runner.store) # See if any of our hooks were deleted with the new commits - hooks = set(repo.hooks.keys()) + hooks = set(hook_id for hook_id, _ in repo.hooks) hooks_missing = hooks - (hooks & set(new_repo.manifest.hooks.keys())) if hooks_missing: raise RepositoryCannotBeUpdatedError( diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py index eee6fcfe..180e88dc 100644 --- a/pre_commit/commands/run.py +++ b/pre_commit/commands/run.py @@ -47,7 +47,7 @@ def _print_user_skipped(hook, write, args): )) -def _run_single_hook(runner, repository, hook_id, args, write, skips=set()): +def _run_single_hook(runner, repository, hook, args, write, skips=set()): if args.all_files: get_filenames = git.get_all_files_matching elif git.is_in_merge_conflict(): @@ -55,10 +55,8 @@ def _run_single_hook(runner, repository, hook_id, args, write, skips=set()): else: get_filenames = git.get_staged_files_matching - hook = repository.hooks[hook_id] - filenames = get_filenames(hook['files'], hook['exclude']) - if hook_id in skips: + if hook['id'] in skips: _print_user_skipped(hook, write, args) return 0 elif not filenames: @@ -70,9 +68,9 @@ def _run_single_hook(runner, repository, hook_id, args, write, skips=set()): write(get_hook_message(_hook_msg_start(hook, args.verbose), end_len=6)) sys.stdout.flush() - retcode, stdout, stderr = repository.run_hook(hook_id, filenames) + retcode, stdout, stderr = repository.run_hook(hook, filenames) - if retcode != repository.hooks[hook_id]['expected_return_value']: + if retcode != hook['expected_return_value']: retcode = 1 print_color = color.RED pass_fail = 'Failed' @@ -101,9 +99,9 @@ def _run_hooks(runner, args, write, environ): skips = _get_skips(environ) for repo in runner.repositories: - for hook_id in repo.hooks: + for _, hook in repo.hooks: retval |= _run_single_hook( - runner, repo, hook_id, args, write, skips=skips, + runner, repo, hook, args, write, skips=skips, ) return retval @@ -112,8 +110,11 @@ def _run_hooks(runner, args, write, environ): def _run_hook(runner, args, write): hook_id = args.hook for repo in runner.repositories: - if hook_id in repo.hooks: - return _run_single_hook(runner, repo, hook_id, args, write=write) + for hook_id_in_repo, hook in repo.hooks: + if hook_id == hook_id_in_repo: + return _run_single_hook( + runner, repo, hook, args, write=write, + ) else: write('No hook with id `{0}`\n'.format(hook_id)) return 1 diff --git a/pre_commit/repository.py b/pre_commit/repository.py index 1bc951a6..0e8a928a 100644 --- a/pre_commit/repository.py +++ b/pre_commit/repository.py @@ -4,7 +4,6 @@ from cached_property import cached_property from pre_commit.languages.all import languages from pre_commit.manifest import Manifest -from pre_commit.ordereddict import OrderedDict from pre_commit.prefixed_command_runner import PrefixedCommandRunner @@ -33,13 +32,13 @@ class Repository(object): def languages(self): return set( (hook['language'], hook['language_version']) - for hook in self.hooks.values() + for _, hook in self.hooks ) @cached_property def hooks(self): # TODO: merging in manifest dicts is a smell imo - return OrderedDict( + return tuple( (hook['id'], dict(self.manifest.hooks[hook['id']], **hook)) for hook in self.repo_config['hooks'] ) @@ -71,15 +70,14 @@ class Repository(object): continue language.install_environment(self.cmd_runner, language_version) - def run_hook(self, hook_id, file_args): + def run_hook(self, hook, file_args): """Run a hook. Args: - hook_id - Id of the hook + hook - Hook dictionary file_args - List of files to run """ self.require_installed() - hook = self.hooks[hook_id] return languages[hook['language']].run_hook( self.cmd_runner, hook, file_args, ) diff --git a/tests/repository_test.py b/tests/repository_test.py index 451054d9..93fe461a 100644 --- a/tests/repository_test.py +++ b/tests/repository_test.py @@ -29,7 +29,10 @@ def _test_hook_repo( path = make_repo(tmpdir_factory, repo_path) config = make_config_from_repo(path) repo = Repository.create(config, store) - ret = repo.run_hook(hook_id, args) + hook_dict = [ + hook for repo_hook_id, hook in repo.hooks if repo_hook_id == hook_id + ][0] + ret = repo.run_hook(hook_dict, args) assert ret[0] == expected_return_code assert ret[1] == expected @@ -261,11 +264,11 @@ def test_config_overrides_repo_specifics(tmpdir_factory, store): config = make_config_from_repo(path) repo = Repository.create(config, store) - assert repo.hooks['bash_hook']['files'] == '' + assert repo.hooks[0][1]['files'] == '' # Set the file regex to something else config['hooks'][0]['files'] = '\\.sh$' repo = Repository.create(config, store) - assert repo.hooks['bash_hook']['files'] == '\\.sh$' + assert repo.hooks[0][1]['files'] == '\\.sh$' def _create_repo_with_tags(tmpdir_factory, src, tag): @@ -286,13 +289,13 @@ def test_tags_on_repositories(in_tmpdir, tmpdir_factory, store): repo_1 = Repository.create( make_config_from_repo(git_dir_1, sha=tag), store, ) - ret = repo_1.run_hook('prints_cwd', ['-L']) + ret = repo_1.run_hook(repo_1.hooks[0][1], ['-L']) assert ret[0] == 0 assert ret[1].strip() == in_tmpdir repo_2 = Repository.create( make_config_from_repo(git_dir_2, sha=tag), store, ) - ret = repo_2.run_hook('bash_hook', ['bar']) + ret = repo_2.run_hook(repo_2.hooks[0][1], ['bar']) assert ret[0] == 0 assert ret[1] == 'bar\nHello World\n'