| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,6 +6,7 @@ | |||
| 6 | 6 | import shlex | |
| 7 | 7 | import sys | |
| 8 | 8 | from typing import Any | |
| 9 | + from typing import NamedTuple | ||
| 9 | 10 | from typing import Sequence | |
| 10 | 11 | ||
| 11 | 12 | import cfgv | |
@@ -20,6 +21,20 @@ | |||
| 20 | 21 | ||
| 21 | 22 | check_string_regex = cfgv.check_and(cfgv.check_string, cfgv.check_regex) | |
| 22 | 23 | ||
| 24 | + HOOK_TYPES = ( | ||
| 25 | + 'commit-msg', | ||
| 26 | + 'post-checkout', | ||
| 27 | + 'post-commit', | ||
| 28 | + 'post-merge', | ||
| 29 | + 'post-rewrite', | ||
| 30 | + 'pre-commit', | ||
| 31 | + 'pre-merge-commit', | ||
| 32 | + 'pre-push', | ||
| 33 | + 'prepare-commit-msg', | ||
| 34 | + ) | ||
| 35 | + # `manual` is not invoked by any installed git hook. See #719 | ||
| 36 | + STAGES = (*HOOK_TYPES, 'manual') | ||
| 37 | + | ||
| 23 | 38 | ||
| 24 | 39 | def check_type_tag(tag: str) -> None: | |
| 25 | 40 | if tag not in ALL_TAGS: | |
@@ -43,6 +58,46 @@ def check_min_version(version: str) -> None: | |||
| 43 | 58 | ) | |
| 44 | 59 | ||
| 45 | 60 | ||
| 61 | + _STAGES = { | ||
| 62 | + 'commit': 'pre-commit', | ||
| 63 | + 'merge-commit': 'pre-merge-commit', | ||
| 64 | + 'push': 'pre-push', | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + | ||
| 68 | + def transform_stage(stage: str) -> str: | ||
| 69 | + return _STAGES.get(stage, stage) | ||
| 70 | + | ||
| 71 | + | ||
| 72 | + class StagesMigrationNoDefault(NamedTuple): | ||
| 73 | + key: str | ||
| 74 | + default: Sequence[str] | ||
| 75 | + | ||
| 76 | + def check(self, dct: dict[str, Any]) -> None: | ||
| 77 | + if self.key not in dct: | ||
| 78 | + return | ||
| 79 | + | ||
| 80 | + val = dct[self.key] | ||
| 81 | + cfgv.check_array(cfgv.check_any)(val) | ||
| 82 | + | ||
| 83 | + val = [transform_stage(v) for v in val] | ||
| 84 | + cfgv.check_array(cfgv.check_one_of(STAGES))(val) | ||
| 85 | + | ||
| 86 | + def apply_default(self, dct: dict[str, Any]) -> None: | ||
| 87 | + if self.key not in dct: | ||
| 88 | + return | ||
| 89 | + dct[self.key] = [transform_stage(v) for v in dct[self.key]] | ||
| 90 | + | ||
| 91 | + def remove_default(self, dct: dict[str, Any]) -> None: | ||
| 92 | + raise NotImplementedError | ||
| 93 | + | ||
| 94 | + | ||
| 95 | + class StagesMigration(StagesMigrationNoDefault): | ||
| 96 | + def apply_default(self, dct: dict[str, Any]) -> None: | ||
| 97 | + dct.setdefault(self.key, self.default) | ||
| 98 | + super().apply_default(dct) | ||
| 99 | + | ||
| 100 | + | ||
| 46 | 101 | MANIFEST_HOOK_DICT = cfgv.Map( | |
| 47 | 102 | 'Hook', 'id', | |
| 48 | 103 | ||
@@ -70,7 +125,7 @@ def check_min_version(version: str) -> None: | |||
| 70 | 125 | cfgv.Optional('log_file', cfgv.check_string, ''), | |
| 71 | 126 | cfgv.Optional('minimum_pre_commit_version', cfgv.check_string, '0'), | |
| 72 | 127 | cfgv.Optional('require_serial', cfgv.check_bool, False), | |
| 73 | - cfgv.Optional('stages', cfgv.check_array(cfgv.check_one_of(C.STAGES)), []), | ||
| 128 | + StagesMigration('stages', []), | ||
| 74 | 129 | cfgv.Optional('verbose', cfgv.check_bool, False), | |
| 75 | 130 | ) | |
| 76 | 131 | MANIFEST_SCHEMA = cfgv.Array(MANIFEST_HOOK_DICT) | |
@@ -241,7 +296,9 @@ def check(self, dct: dict[str, Any]) -> None: | |||
| 241 | 296 | cfgv.OptionalNoDefault(item.key, item.check_fn) | |
| 242 | 297 | for item in MANIFEST_HOOK_DICT.items | |
| 243 | 298 | if item.key != 'id' | |
| 299 | + if item.key != 'stages' | ||
| 244 | 300 | ), | |
| 301 | + StagesMigrationNoDefault('stages', []), | ||
| 245 | 302 | OptionalSensibleRegexAtHook('files', cfgv.check_string), | |
| 246 | 303 | OptionalSensibleRegexAtHook('exclude', cfgv.check_string), | |
| 247 | 304 | ) | |
@@ -290,17 +347,13 @@ def check(self, dct: dict[str, Any]) -> None: | |||
| 290 | 347 | cfgv.RequiredRecurse('repos', cfgv.Array(CONFIG_REPO_DICT)), | |
| 291 | 348 | cfgv.Optional( | |
| 292 | 349 | 'default_install_hook_types', | |
| 293 | - cfgv.check_array(cfgv.check_one_of(C.HOOK_TYPES)), | ||
| 350 | + cfgv.check_array(cfgv.check_one_of(HOOK_TYPES)), | ||
| 294 | 351 | ['pre-commit'], | |
| 295 | 352 | ), | |
| 296 | 353 | cfgv.OptionalRecurse( | |
| 297 | 354 | 'default_language_version', DEFAULT_LANGUAGE_VERSION, {}, | |
| 298 | 355 | ), | |
| 299 | - cfgv.Optional( | ||
| 300 | - 'default_stages', | ||
| 301 | - cfgv.check_array(cfgv.check_one_of(C.STAGES)), | ||
| 302 | - C.STAGES, | ||
| 303 | - ), | ||
| 356 | + StagesMigration('default_stages', STAGES), | ||
| 304 | 357 | cfgv.Optional('files', check_string_regex, ''), | |
| 305 | 358 | cfgv.Optional('exclude', check_string_regex, '^$'), | |
| 306 | 359 | cfgv.Optional('fail_fast', cfgv.check_bool, False), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -84,7 +84,7 @@ def _ns( | |||
| 84 | 84 | ) -> argparse.Namespace: | |
| 85 | 85 | return argparse.Namespace( | |
| 86 | 86 | color=color, | |
| 87 | - hook_stage=hook_type.replace('pre-', ''), | ||
| 87 | + hook_stage=hook_type, | ||
| 88 | 88 | remote_branch=remote_branch, | |
| 89 | 89 | local_branch=local_branch, | |
| 90 | 90 | from_ref=from_ref, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,17 +10,4 @@ | |||
| 10 | 10 | ||
| 11 | 11 | VERSION = importlib.metadata.version('pre_commit') | |
| 12 | 12 | ||
| 13 | - # `manual` is not invoked by any installed git hook. See #719 | ||
| 14 | - STAGES = ( | ||
| 15 | - 'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg', | ||
| 16 | - 'post-commit', 'manual', 'post-checkout', 'push', 'post-merge', | ||
| 17 | - 'post-rewrite', | ||
| 18 | - ) | ||
| 19 | - | ||
| 20 | - HOOK_TYPES = ( | ||
| 21 | - 'pre-commit', 'pre-merge-commit', 'pre-push', 'prepare-commit-msg', | ||
| 22 | - 'commit-msg', 'post-commit', 'post-checkout', 'post-merge', | ||
| 23 | - 'post-rewrite', | ||
| 24 | - ) | ||
| 25 | - | ||
| 26 | 13 | DEFAULT = 'default' | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,6 +7,7 @@ | |||
| 7 | 7 | from typing import Sequence | |
| 8 | 8 | ||
| 9 | 9 | import pre_commit.constants as C | |
| 10 | + from pre_commit import clientlib | ||
| 10 | 11 | from pre_commit import git | |
| 11 | 12 | from pre_commit.color import add_color_option | |
| 12 | 13 | from pre_commit.commands.autoupdate import autoupdate | |
@@ -52,7 +53,7 @@ def _add_config_option(parser: argparse.ArgumentParser) -> None: | |||
| 52 | 53 | def _add_hook_type_option(parser: argparse.ArgumentParser) -> None: | |
| 53 | 54 | parser.add_argument( | |
| 54 | 55 | '-t', '--hook-type', | |
| 55 | - choices=C.HOOK_TYPES, action='append', dest='hook_types', | ||
| 56 | + choices=clientlib.HOOK_TYPES, action='append', dest='hook_types', | ||
| 56 | 57 | ) | |
| 57 | 58 | ||
| 58 | 59 | ||
@@ -73,7 +74,10 @@ def _add_run_options(parser: argparse.ArgumentParser) -> None: | |||
| 73 | 74 | help='When hooks fail, run `git diff` directly afterward.', | |
| 74 | 75 | ) | |
| 75 | 76 | parser.add_argument( | |
| 76 | - '--hook-stage', choices=C.STAGES, default='commit', | ||
| 77 | + '--hook-stage', | ||
| 78 | + choices=clientlib.STAGES, | ||
| 79 | + type=clientlib.transform_stage, | ||
| 80 | + default='pre-commit', | ||
| 77 | 81 | help='The stage during which the hook is fired. One of %(choices)s', | |
| 78 | 82 | ) | |
| 79 | 83 | parser.add_argument( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -46,7 +46,7 @@ def run_opts( | |||
| 46 | 46 | to_ref='', | |
| 47 | 47 | remote_name='', | |
| 48 | 48 | remote_url='', | |
| 49 | - hook_stage='commit', | ||
| 49 | + hook_stage='pre-commit', | ||
| 50 | 50 | show_diff_on_failure=False, | |
| 51 | 51 | commit_msg_filename='', | |
| 52 | 52 | prepare_commit_message_source='', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,6 +12,7 @@ | |||
| 12 | 12 | from pre_commit.clientlib import CONFIG_REPO_DICT | |
| 13 | 13 | from pre_commit.clientlib import CONFIG_SCHEMA | |
| 14 | 14 | from pre_commit.clientlib import DEFAULT_LANGUAGE_VERSION | |
| 15 | + from pre_commit.clientlib import MANIFEST_HOOK_DICT | ||
| 15 | 16 | from pre_commit.clientlib import MANIFEST_SCHEMA | |
| 16 | 17 | from pre_commit.clientlib import META_HOOK_DICT | |
| 17 | 18 | from pre_commit.clientlib import OptionalSensibleRegexAtHook | |
@@ -416,3 +417,50 @@ def test_warn_additional(schema): | |||
| 416 | 417 | x for x in schema.items if isinstance(x, cfgv.WarnAdditionalKeys) | |
| 417 | 418 | ) | |
| 418 | 419 | assert allowed_keys == set(warn_additional.keys) | |
| 420 | + | ||
| 421 | + | ||
| 422 | + def test_stages_migration_for_default_stages(): | ||
| 423 | + cfg = { | ||
| 424 | + 'default_stages': ['commit-msg', 'push', 'commit', 'merge-commit'], | ||
| 425 | + 'repos': [], | ||
| 426 | + } | ||
| 427 | + cfgv.validate(cfg, CONFIG_SCHEMA) | ||
| 428 | + cfg = cfgv.apply_defaults(cfg, CONFIG_SCHEMA) | ||
| 429 | + assert cfg['default_stages'] == [ | ||
| 430 | + 'commit-msg', 'pre-push', 'pre-commit', 'pre-merge-commit', | ||
| 431 | + ] | ||
| 432 | + | ||
| 433 | + | ||
| 434 | + def test_manifest_stages_defaulting(): | ||
| 435 | + dct = { | ||
| 436 | + 'id': 'fake-hook', | ||
| 437 | + 'name': 'fake-hook', | ||
| 438 | + 'entry': 'fake-hook', | ||
| 439 | + 'language': 'system', | ||
| 440 | + 'stages': ['commit-msg', 'push', 'commit', 'merge-commit'], | ||
| 441 | + } | ||
| 442 | + cfgv.validate(dct, MANIFEST_HOOK_DICT) | ||
| 443 | + dct = cfgv.apply_defaults(dct, MANIFEST_HOOK_DICT) | ||
| 444 | + assert dct['stages'] == [ | ||
| 445 | + 'commit-msg', 'pre-push', 'pre-commit', 'pre-merge-commit', | ||
| 446 | + ] | ||
| 447 | + | ||
| 448 | + | ||
| 449 | + def test_config_hook_stages_defaulting_missing(): | ||
| 450 | + dct = {'id': 'fake-hook'} | ||
| 451 | + cfgv.validate(dct, CONFIG_HOOK_DICT) | ||
| 452 | + dct = cfgv.apply_defaults(dct, CONFIG_HOOK_DICT) | ||
| 453 | + assert dct == {'id': 'fake-hook'} | ||
| 454 | + | ||
| 455 | + | ||
| 456 | + def test_config_hook_stages_defaulting(): | ||
| 457 | + dct = { | ||
| 458 | + 'id': 'fake-hook', | ||
| 459 | + 'stages': ['commit-msg', 'push', 'commit', 'merge-commit'], | ||
| 460 | + } | ||
| 461 | + cfgv.validate(dct, CONFIG_HOOK_DICT) | ||
| 462 | + dct = cfgv.apply_defaults(dct, CONFIG_HOOK_DICT) | ||
| 463 | + assert dct == { | ||
| 464 | + 'id': 'fake-hook', | ||
| 465 | + 'stages': ['commit-msg', 'pre-push', 'pre-commit', 'pre-merge-commit'], | ||
| 466 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -142,7 +142,7 @@ def test_check_args_length_prepare_commit_msg_error(): | |||
| 142 | 142 | def test_run_ns_pre_commit(): | |
| 143 | 143 | ns = hook_impl._run_ns('pre-commit', True, (), b'') | |
| 144 | 144 | assert ns is not None | |
| 145 | - assert ns.hook_stage == 'commit' | ||
| 145 | + assert ns.hook_stage == 'pre-commit' | ||
| 146 | 146 | assert ns.color is True | |
| 147 | 147 | ||
| 148 | 148 | ||
@@ -245,7 +245,7 @@ def test_run_ns_pre_push_updating_branch(push_example): | |||
| 245 | 245 | ns = hook_impl._run_ns('pre-push', False, args, stdin) | |
| 246 | 246 | ||
| 247 | 247 | assert ns is not None | |
| 248 | - assert ns.hook_stage == 'push' | ||
| 248 | + assert ns.hook_stage == 'pre-push' | ||
| 249 | 249 | assert ns.color is False | |
| 250 | 250 | assert ns.remote_name == 'origin' | |
| 251 | 251 | assert ns.remote_url == src | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -354,13 +354,13 @@ def test_show_diff_on_failure( | |||
| 354 | 354 | ({'hook': 'bash_hook'}, (b'Bash hook', b'Passed'), 0, True), | |
| 355 | 355 | ( | |
| 356 | 356 | {'hook': 'nope'}, | |
| 357 | - (b'No hook with id `nope` in stage `commit`',), | ||
| 357 | + (b'No hook with id `nope` in stage `pre-commit`',), | ||
| 358 | 358 | 1, | |
| 359 | 359 | True, | |
| 360 | 360 | ), | |
| 361 | 361 | ( | |
| 362 | - {'hook': 'nope', 'hook_stage': 'push'}, | ||
| 363 | - (b'No hook with id `nope` in stage `push`',), | ||
| 362 | + {'hook': 'nope', 'hook_stage': 'pre-push'}, | ||
| 363 | + (b'No hook with id `nope` in stage `pre-push`',), | ||
| 364 | 364 | 1, | |
| 365 | 365 | True, | |
| 366 | 366 | ), | |
@@ -818,7 +818,7 @@ def test_stages(cap_out, store, repo_with_passing_hook): | |||
| 818 | 818 | 'language': 'pygrep', | |
| 819 | 819 | 'stages': [stage], | |
| 820 | 820 | } | |
| 821 | - for i, stage in enumerate(('commit', 'push', 'manual'), 1) | ||
| 821 | + for i, stage in enumerate(('pre-commit', 'pre-push', 'manual'), 1) | ||
| 822 | 822 | ], | |
| 823 | 823 | } | |
| 824 | 824 | add_config_to_repo(repo_with_passing_hook, config) | |
@@ -833,8 +833,8 @@ def _run_for_stage(stage): | |||
| 833 | 833 | assert printed.count(b'hook ') == 1 | |
| 834 | 834 | return printed | |
| 835 | 835 | ||
| 836 | - assert _run_for_stage('commit').startswith(b'hook 1...') | ||
| 837 | - assert _run_for_stage('push').startswith(b'hook 2...') | ||
| 836 | + assert _run_for_stage('pre-commit').startswith(b'hook 1...') | ||
| 837 | + assert _run_for_stage('pre-push').startswith(b'hook 2...') | ||
| 838 | 838 | assert _run_for_stage('manual').startswith(b'hook 3...') | |
| 839 | 839 | ||
| 840 | 840 | ||
@@ -1173,7 +1173,7 @@ def test_args_hook_only(cap_out, store, repo_with_passing_hook): | |||
| 1173 | 1173 | ), | |
| 1174 | 1174 | 'language': 'system', | |
| 1175 | 1175 | 'files': r'\.py$', | |
| 1176 | - 'stages': ['commit'], | ||
| 1176 | + 'stages': ['pre-commit'], | ||
| 1177 | 1177 | }, | |
| 1178 | 1178 | { | |
| 1179 | 1179 | 'id': 'do_not_commit', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -216,3 +216,9 @@ def test_expected_fatal_error_no_git_repo(in_tmpdir, cap_out, mock_store_dir): | |||
| 216 | 216 | 'Is it installed, and are you in a Git repository directory?' | |
| 217 | 217 | ) | |
| 218 | 218 | assert cap_out_lines[-1] == f'Check the log at {log_file}' | |
| 219 | + | ||
| 220 | + | ||
| 221 | + def test_hook_stage_migration(mock_store_dir): | ||
| 222 | + with mock.patch.object(main, 'run') as mck: | ||
| 223 | + main.main(('run', '--hook-stage', 'commit')) | ||
| 224 | + assert mck.call_args[0][2].hook_stage == 'pre-commit' | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -417,7 +417,7 @@ def test_local_python_repo(store, local_python_config): | |||
| 417 | 417 | def test_default_language_version(store, local_python_config): | |
| 418 | 418 | config: dict[str, Any] = { | |
| 419 | 419 | 'default_language_version': {'python': 'fake'}, | |
| 420 | - 'default_stages': ['commit'], | ||
| 420 | + 'default_stages': ['pre-commit'], | ||
| 421 | 421 | 'repos': [local_python_config], | |
| 422 | 422 | } | |
| 423 | 423 | ||
@@ -434,18 +434,18 @@ def test_default_language_version(store, local_python_config): | |||
| 434 | 434 | def test_default_stages(store, local_python_config): | |
| 435 | 435 | config: dict[str, Any] = { | |
| 436 | 436 | 'default_language_version': {'python': C.DEFAULT}, | |
| 437 | - 'default_stages': ['commit'], | ||
| 437 | + 'default_stages': ['pre-commit'], | ||
| 438 | 438 | 'repos': [local_python_config], | |
| 439 | 439 | } | |
| 440 | 440 | ||
| 441 | 441 | # `stages` was not set, should default | |
| 442 | 442 | hook, = all_hooks(config, store) | |
| 443 | - assert hook.stages == ['commit'] | ||
| 443 | + assert hook.stages == ['pre-commit'] | ||
| 444 | 444 | ||
| 445 | 445 | # `stages` is set, should not default | |
| 446 | - config['repos'][0]['hooks'][0]['stages'] = ['push'] | ||
| 446 | + config['repos'][0]['hooks'][0]['stages'] = ['pre-push'] | ||
| 447 | 447 | hook, = all_hooks(config, store) | |
| 448 | - assert hook.stages == ['push'] | ||
| 448 | + assert hook.stages == ['pre-push'] | ||
| 449 | 449 | ||
| 450 | 450 | ||
| 451 | 451 | def test_hook_id_not_present(tempdir_factory, store, caplog): | |
@@ -513,11 +513,18 @@ def test_manifest_hooks(tempdir_factory, store): | |||
| 513 | 513 | name='Bash hook', | |
| 514 | 514 | pass_filenames=True, | |
| 515 | 515 | require_serial=False, | |
| 516 | - stages=( | ||
| 517 | - 'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg', | ||
| 518 | - 'post-commit', 'manual', 'post-checkout', 'push', 'post-merge', | ||
| 516 | + stages=[ | ||
| 517 | + 'commit-msg', | ||
| 518 | + 'post-checkout', | ||
| 519 | + 'post-commit', | ||
| 520 | + 'post-merge', | ||
| 519 | 521 | 'post-rewrite', | |
| 520 | - ), | ||
| 522 | + 'pre-commit', | ||
| 523 | + 'pre-merge-commit', | ||
| 524 | + 'pre-push', | ||
| 525 | + 'prepare-commit-msg', | ||
| 526 | + 'manual', | ||
| 527 | + ], | ||
| 521 | 528 | types=['file'], | |
| 522 | 529 | types_or=[], | |
| 523 | 530 | verbose=False, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments