mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-20 01:24:42 +04:00
Merge pull request #151 from pre-commit/dont_dict_pre_commit_config
Allow multiple hooks with same id in .pre-commit-config.yaml
This commit is contained in:
commit
ed86307dc4
6 changed files with 43 additions and 23 deletions
|
|
@ -7,6 +7,8 @@ omit =
|
||||||
/usr/*
|
/usr/*
|
||||||
*/tmp*
|
*/tmp*
|
||||||
setup.py
|
setup.py
|
||||||
|
# Don't complain if non-runnable code isn't run
|
||||||
|
*/__main__.py
|
||||||
|
|
||||||
[report]
|
[report]
|
||||||
exclude_lines =
|
exclude_lines =
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ def _update_repository(repo_config, runner):
|
||||||
new_repo = Repository.create(new_config, runner.store)
|
new_repo = Repository.create(new_config, runner.store)
|
||||||
|
|
||||||
# See if any of our hooks were deleted with the new commits
|
# 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()))
|
hooks_missing = hooks - (hooks & set(new_repo.manifest.hooks.keys()))
|
||||||
if hooks_missing:
|
if hooks_missing:
|
||||||
raise RepositoryCannotBeUpdatedError(
|
raise RepositoryCannotBeUpdatedError(
|
||||||
|
|
|
||||||
|
|
@ -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:
|
if args.all_files:
|
||||||
get_filenames = git.get_all_files_matching
|
get_filenames = git.get_all_files_matching
|
||||||
elif git.is_in_merge_conflict():
|
elif git.is_in_merge_conflict():
|
||||||
|
|
@ -55,10 +55,8 @@ def _run_single_hook(runner, repository, hook_id, args, write, skips=set()):
|
||||||
else:
|
else:
|
||||||
get_filenames = git.get_staged_files_matching
|
get_filenames = git.get_staged_files_matching
|
||||||
|
|
||||||
hook = repository.hooks[hook_id]
|
|
||||||
|
|
||||||
filenames = get_filenames(hook['files'], hook['exclude'])
|
filenames = get_filenames(hook['files'], hook['exclude'])
|
||||||
if hook_id in skips:
|
if hook['id'] in skips:
|
||||||
_print_user_skipped(hook, write, args)
|
_print_user_skipped(hook, write, args)
|
||||||
return 0
|
return 0
|
||||||
elif not filenames:
|
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))
|
write(get_hook_message(_hook_msg_start(hook, args.verbose), end_len=6))
|
||||||
sys.stdout.flush()
|
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
|
retcode = 1
|
||||||
print_color = color.RED
|
print_color = color.RED
|
||||||
pass_fail = 'Failed'
|
pass_fail = 'Failed'
|
||||||
|
|
@ -101,9 +99,9 @@ def _run_hooks(runner, args, write, environ):
|
||||||
skips = _get_skips(environ)
|
skips = _get_skips(environ)
|
||||||
|
|
||||||
for repo in runner.repositories:
|
for repo in runner.repositories:
|
||||||
for hook_id in repo.hooks:
|
for _, hook in repo.hooks:
|
||||||
retval |= _run_single_hook(
|
retval |= _run_single_hook(
|
||||||
runner, repo, hook_id, args, write, skips=skips,
|
runner, repo, hook, args, write, skips=skips,
|
||||||
)
|
)
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
|
@ -112,8 +110,11 @@ def _run_hooks(runner, args, write, environ):
|
||||||
def _run_hook(runner, args, write):
|
def _run_hook(runner, args, write):
|
||||||
hook_id = args.hook
|
hook_id = args.hook
|
||||||
for repo in runner.repositories:
|
for repo in runner.repositories:
|
||||||
if hook_id in repo.hooks:
|
for hook_id_in_repo, hook in repo.hooks:
|
||||||
return _run_single_hook(runner, repo, hook_id, args, write=write)
|
if hook_id == hook_id_in_repo:
|
||||||
|
return _run_single_hook(
|
||||||
|
runner, repo, hook, args, write=write,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
write('No hook with id `{0}`\n'.format(hook_id))
|
write('No hook with id `{0}`\n'.format(hook_id))
|
||||||
return 1
|
return 1
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from cached_property import cached_property
|
||||||
|
|
||||||
from pre_commit.languages.all import languages
|
from pre_commit.languages.all import languages
|
||||||
from pre_commit.manifest import Manifest
|
from pre_commit.manifest import Manifest
|
||||||
from pre_commit.ordereddict import OrderedDict
|
|
||||||
from pre_commit.prefixed_command_runner import PrefixedCommandRunner
|
from pre_commit.prefixed_command_runner import PrefixedCommandRunner
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -33,13 +32,13 @@ class Repository(object):
|
||||||
def languages(self):
|
def languages(self):
|
||||||
return set(
|
return set(
|
||||||
(hook['language'], hook['language_version'])
|
(hook['language'], hook['language_version'])
|
||||||
for hook in self.hooks.values()
|
for _, hook in self.hooks
|
||||||
)
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def hooks(self):
|
def hooks(self):
|
||||||
# TODO: merging in manifest dicts is a smell imo
|
# TODO: merging in manifest dicts is a smell imo
|
||||||
return OrderedDict(
|
return tuple(
|
||||||
(hook['id'], dict(self.manifest.hooks[hook['id']], **hook))
|
(hook['id'], dict(self.manifest.hooks[hook['id']], **hook))
|
||||||
for hook in self.repo_config['hooks']
|
for hook in self.repo_config['hooks']
|
||||||
)
|
)
|
||||||
|
|
@ -71,15 +70,14 @@ class Repository(object):
|
||||||
continue
|
continue
|
||||||
language.install_environment(self.cmd_runner, language_version)
|
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.
|
"""Run a hook.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
hook_id - Id of the hook
|
hook - Hook dictionary
|
||||||
file_args - List of files to run
|
file_args - List of files to run
|
||||||
"""
|
"""
|
||||||
self.require_installed()
|
self.require_installed()
|
||||||
hook = self.hooks[hook_id]
|
|
||||||
return languages[hook['language']].run_hook(
|
return languages[hook['language']].run_hook(
|
||||||
self.cmd_runner, hook, file_args,
|
self.cmd_runner, hook, file_args,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import io
|
||||||
import mock
|
import mock
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
|
@ -205,7 +206,22 @@ def test_hook_id_not_in_non_verbose_output(
|
||||||
|
|
||||||
|
|
||||||
def test_hook_id_in_verbose_output(
|
def test_hook_id_in_verbose_output(
|
||||||
repo_with_passing_hook, mock_out_store_directory
|
repo_with_passing_hook, mock_out_store_directory,
|
||||||
):
|
):
|
||||||
ret, printed = _do_run(repo_with_passing_hook, _get_opts(verbose=True))
|
ret, printed = _do_run(repo_with_passing_hook, _get_opts(verbose=True))
|
||||||
assert '[bash_hook] Bash hook' in printed
|
assert '[bash_hook] Bash hook' in printed
|
||||||
|
|
||||||
|
|
||||||
|
def test_multiple_hooks_same_id(
|
||||||
|
repo_with_passing_hook, mock_out_store_directory,
|
||||||
|
):
|
||||||
|
with local.cwd(repo_with_passing_hook):
|
||||||
|
# Add bash hook on there again
|
||||||
|
with io.open('.pre-commit-config.yaml', 'a+') as config_file:
|
||||||
|
config_file.write(' - id: bash_hook\n')
|
||||||
|
local['git']('add', '.pre-commit-config.yaml')
|
||||||
|
stage_a_file()
|
||||||
|
|
||||||
|
ret, output = _do_run(repo_with_passing_hook, _get_opts())
|
||||||
|
assert ret == 0
|
||||||
|
assert output.count('Bash hook') == 2
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,10 @@ def _test_hook_repo(
|
||||||
path = make_repo(tmpdir_factory, repo_path)
|
path = make_repo(tmpdir_factory, repo_path)
|
||||||
config = make_config_from_repo(path)
|
config = make_config_from_repo(path)
|
||||||
repo = Repository.create(config, store)
|
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[0] == expected_return_code
|
||||||
assert ret[1] == expected
|
assert ret[1] == expected
|
||||||
|
|
||||||
|
|
@ -261,11 +264,11 @@ def test_config_overrides_repo_specifics(tmpdir_factory, store):
|
||||||
config = make_config_from_repo(path)
|
config = make_config_from_repo(path)
|
||||||
|
|
||||||
repo = Repository.create(config, store)
|
repo = Repository.create(config, store)
|
||||||
assert repo.hooks['bash_hook']['files'] == ''
|
assert repo.hooks[0][1]['files'] == ''
|
||||||
# Set the file regex to something else
|
# Set the file regex to something else
|
||||||
config['hooks'][0]['files'] = '\\.sh$'
|
config['hooks'][0]['files'] = '\\.sh$'
|
||||||
repo = Repository.create(config, store)
|
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):
|
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(
|
repo_1 = Repository.create(
|
||||||
make_config_from_repo(git_dir_1, sha=tag), store,
|
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[0] == 0
|
||||||
assert ret[1].strip() == in_tmpdir
|
assert ret[1].strip() == in_tmpdir
|
||||||
|
|
||||||
repo_2 = Repository.create(
|
repo_2 = Repository.create(
|
||||||
make_config_from_repo(git_dir_2, sha=tag), store,
|
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[0] == 0
|
||||||
assert ret[1] == 'bar\nHello World\n'
|
assert ret[1] == 'bar\nHello World\n'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue