Add ability to skip hooks by branches

This commit is contained in:
Ivan Studinsky 2023-04-29 18:28:03 +07:00
parent 8656797c78
commit ff5fd29479
4 changed files with 30 additions and 1 deletions

View file

@ -110,6 +110,8 @@ MANIFEST_HOOK_DICT = cfgv.Map(
cfgv.Optional('files', check_string_regex, ''), cfgv.Optional('files', check_string_regex, ''),
cfgv.Optional('exclude', check_string_regex, '^$'), cfgv.Optional('exclude', check_string_regex, '^$'),
cfgv.Optional('branches', check_string_regex, ''),
cfgv.Optional('exclude_branches', check_string_regex, '^$'),
cfgv.Optional('types', cfgv.check_array(check_type_tag), ['file']), cfgv.Optional('types', cfgv.check_array(check_type_tag), ['file']),
cfgv.Optional('types_or', cfgv.check_array(check_type_tag), []), cfgv.Optional('types_or', cfgv.check_array(check_type_tag), []),
cfgv.Optional('exclude_types', cfgv.check_array(check_type_tag), []), cfgv.Optional('exclude_types', cfgv.check_array(check_type_tag), []),

View file

@ -26,6 +26,7 @@ from pre_commit.repository import all_hooks
from pre_commit.repository import install_hook_envs from pre_commit.repository import install_hook_envs
from pre_commit.staged_files_only import staged_files_only from pre_commit.staged_files_only import staged_files_only
from pre_commit.store import Store from pre_commit.store import Store
from pre_commit.util import cmd_output
from pre_commit.util import cmd_output_b from pre_commit.util import cmd_output_b
@ -131,6 +132,28 @@ def _get_skips(environ: MutableMapping[str, str]) -> set[str]:
return {skip.strip() for skip in skips.split(',') if skip.strip()} return {skip.strip() for skip in skips.split(',') if skip.strip()}
def _get_branch_name() -> str:
_, name, _ = cmd_output('git', 'branch', '--show-current')
return name
def _get_branch_skips(config: dict[str, Any], store: Store) -> set[str]:
current_branch = _get_branch_name()
to_skip = set()
for hook in all_hooks(config, store):
include_re = re.compile(hook.branches)
exclude_re = re.compile(hook.exclude_branches)
if (
not include_re.search(current_branch) or
exclude_re.search(current_branch)
):
to_skip.add(hook.name)
return to_skip
SKIPPED = 'Skipped' SKIPPED = 'Skipped'
NO_FILES = '(no files to check)' NO_FILES = '(no files to check)'
@ -433,7 +456,7 @@ def run(
) )
return 1 return 1
skips = _get_skips(environ) skips = _get_skips(environ) | _get_branch_skips(config, store)
to_install = [ to_install = [
hook hook
for hook in hooks for hook in hooks

View file

@ -35,6 +35,8 @@ class Hook(NamedTuple):
require_serial: bool require_serial: bool
stages: Sequence[str] stages: Sequence[str]
verbose: bool verbose: bool
branches: str
exclude_branches: str
@property @property
def install_key(self) -> tuple[Prefix, str, str, tuple[str, ...]]: def install_key(self) -> tuple[Prefix, str, str, tuple[str, ...]]:

View file

@ -475,6 +475,8 @@ def test_manifest_hooks(tempdir_factory, store):
entry='bin/hook.sh', entry='bin/hook.sh',
exclude='^$', exclude='^$',
exclude_types=[], exclude_types=[],
branches='',
exclude_branches='^$',
files='', files='',
id='bash_hook', id='bash_hook',
language='script', language='script',