From c699e255a166bcb785e511faf1f0c4701cfef6ba Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 6 Nov 2019 19:13:12 -0800 Subject: [PATCH] support pre-merge-commit --- pre_commit/constants.py | 5 ++++- pre_commit/main.py | 3 ++- pre_commit/resources/hook-tmpl | 1 + testing/util.py | 5 ++--- tests/commands/install_uninstall_test.py | 28 ++++++++++++++++++++++++ tests/repository_test.py | 3 ++- 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/pre_commit/constants.py b/pre_commit/constants.py index 7dd447c0..3aa452c4 100644 --- a/pre_commit/constants.py +++ b/pre_commit/constants.py @@ -26,6 +26,9 @@ LOCAL_REPO_VERSION = '1' VERSION = importlib_metadata.version('pre_commit') # `manual` is not invoked by any installed git hook. See #719 -STAGES = ('commit', 'prepare-commit-msg', 'commit-msg', 'manual', 'push') +STAGES = ( + 'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg', 'manual', + 'push', +) DEFAULT = 'default' diff --git a/pre_commit/main.py b/pre_commit/main.py index 686ddc4c..fe1beafd 100644 --- a/pre_commit/main.py +++ b/pre_commit/main.py @@ -70,7 +70,8 @@ class AppendReplaceDefault(argparse.Action): def _add_hook_type_option(parser): parser.add_argument( '-t', '--hook-type', choices=( - 'pre-commit', 'pre-push', 'prepare-commit-msg', 'commit-msg', + 'pre-commit', 'pre-merge-commit', 'pre-push', + 'prepare-commit-msg', 'commit-msg', ), action=AppendReplaceDefault, default=['pre-commit'], diff --git a/pre_commit/resources/hook-tmpl b/pre_commit/resources/hook-tmpl index a145c8ee..81ffc955 100755 --- a/pre_commit/resources/hook-tmpl +++ b/pre_commit/resources/hook-tmpl @@ -163,6 +163,7 @@ def _opts(stdin): fns = { 'prepare-commit-msg': lambda _: ('--commit-msg-filename', sys.argv[1]), 'commit-msg': lambda _: ('--commit-msg-filename', sys.argv[1]), + 'pre-merge-commit': lambda _: (), 'pre-commit': lambda _: (), 'pre-push': _pre_push, } diff --git a/testing/util.py b/testing/util.py index dde0c4d0..600f1c59 100644 --- a/testing/util.py +++ b/testing/util.py @@ -36,16 +36,15 @@ skipif_cant_run_docker = pytest.mark.skipif( os.name == 'nt' or not docker_is_running(), reason="Docker isn't running or can't be accessed", ) - skipif_cant_run_swift = pytest.mark.skipif( parse_shebang.find_executable('swift') is None, - reason='swift isn\'t installed or can\'t be found', + reason="swift isn't installed or can't be found", ) - xfailif_windows_no_ruby = pytest.mark.xfail( os.name == 'nt', reason='Ruby support not yet implemented on windows.', ) +xfailif_windows = pytest.mark.xfail(os.name == 'nt', reason='windows') def broken_deep_listdir(): # pragma: no cover (platform specific) diff --git a/tests/commands/install_uninstall_test.py b/tests/commands/install_uninstall_test.py index ba626517..f0e17097 100644 --- a/tests/commands/install_uninstall_test.py +++ b/tests/commands/install_uninstall_test.py @@ -29,6 +29,7 @@ from testing.util import cmd_output_mocked_pre_commit_home from testing.util import cwd from testing.util import git_commit from testing.util import xfailif_no_symlink +from testing.util import xfailif_windows def test_is_not_script(): @@ -742,6 +743,33 @@ def test_prepare_commit_msg_legacy( assert 'Signed off by: ' in f.read() +@xfailif_windows # pragma: windows no cover (once AP has git 2.24) +def test_pre_merge_commit_integration(tempdir_factory, store): + expected = re.compile( + r'^\[INFO\] Initializing environment for .+\n' + r'Bash hook\.+Passed\n' + r"Merge made by the 'recursive' strategy.\n" + r' foo \| 0\n' + r' 1 file changed, 0 insertions\(\+\), 0 deletions\(-\)\n' + r' create mode 100644 foo\n$', + ) + + path = make_consuming_repo(tempdir_factory, 'script_hooks_repo') + with cwd(path): + ret = install(C.CONFIG_FILE, store, hook_types=['pre-merge-commit']) + assert ret == 0 + + cmd_output('git', 'checkout', 'master', '-b', 'feature') + _get_commit_output(tempdir_factory) + cmd_output('git', 'checkout', 'master') + ret, output, _ = cmd_output_mocked_pre_commit_home( + 'git', 'merge', '--no-ff', '--no-edit', 'feature', + tempdir_factory=tempdir_factory, + ) + assert ret == 0 + assert expected.match(output) + + def test_install_disallow_missing_config(tempdir_factory, store): path = make_consuming_repo(tempdir_factory, 'script_hooks_repo') with cwd(path): diff --git a/tests/repository_test.py b/tests/repository_test.py index 8f001384..a468e707 100644 --- a/tests/repository_test.py +++ b/tests/repository_test.py @@ -895,7 +895,8 @@ def test_manifest_hooks(tempdir_factory, store): pass_filenames=True, require_serial=False, stages=( - 'commit', 'prepare-commit-msg', 'commit-msg', 'manual', 'push', + 'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg', + 'manual', 'push', ), types=['file'], verbose=False,