Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add post-checkout #1339

Merged
merged 1 commit into from
Feb 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions pre_commit/commands/hook_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def _ns(
remote_name: Optional[str] = None,
remote_url: Optional[str] = None,
commit_msg_filename: Optional[str] = None,
checkout_type: Optional[str] = None,
) -> argparse.Namespace:
return argparse.Namespace(
color=color,
Expand All @@ -84,6 +85,7 @@ def _ns(
remote_url=remote_url,
commit_msg_filename=commit_msg_filename,
all_files=all_files,
checkout_type=checkout_type,
files=(),
hook=None,
verbose=False,
Expand Down Expand Up @@ -157,6 +159,11 @@ def _run_ns(
return _ns(hook_type, color, commit_msg_filename=args[0])
elif hook_type in {'pre-merge-commit', 'pre-commit'}:
return _ns(hook_type, color)
elif hook_type == 'post-checkout':
return _ns(
hook_type, color, source=args[0], origin=args[1],
checkout_type=args[2],
)
else:
raise AssertionError(f'unexpected hook type: {hook_type}')

Expand Down
3 changes: 3 additions & 0 deletions pre_commit/commands/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,9 @@ def run(
environ['PRE_COMMIT_REMOTE_NAME'] = args.remote_name
environ['PRE_COMMIT_REMOTE_URL'] = args.remote_url

if args.checkout_type:
environ['PRE_COMMIT_CHECKOUT_TYPE'] = args.checkout_type

with contextlib.ExitStack() as exit_stack:
if stash:
exit_stack.enter_context(staged_files_only(store.directory))
Expand Down
2 changes: 1 addition & 1 deletion pre_commit/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# `manual` is not invoked by any installed git hook. See #719
STAGES = (
'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg', 'manual',
'push',
'post-checkout', 'push',
)

DEFAULT = 'default'
20 changes: 17 additions & 3 deletions pre_commit/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def _add_hook_type_option(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
'-t', '--hook-type', choices=(
'pre-commit', 'pre-merge-commit', 'pre-push',
'prepare-commit-msg', 'commit-msg',
'prepare-commit-msg', 'commit-msg', 'post-checkout',
),
action=AppendReplaceDefault,
default=['pre-commit'],
Expand All @@ -92,11 +92,17 @@ def _add_run_options(parser: argparse.ArgumentParser) -> None:
parser.add_argument('--verbose', '-v', action='store_true', default=False)
parser.add_argument(
'--origin', '-o',
help="The origin branch's commit_id when using `git push`.",
help=(
"The origin branch's commit_id when using `git push`. "
'The ref of the previous HEAD when using `git checkout`.'
),
)
parser.add_argument(
'--source', '-s',
help="The remote branch's commit_id when using `git push`.",
help=(
"The remote branch's commit_id when using `git push`. "
'The ref of the new HEAD when using `git checkout`.'
),
)
parser.add_argument(
'--commit-msg-filename',
Expand All @@ -123,6 +129,14 @@ def _add_run_options(parser: argparse.ArgumentParser) -> None:
'--files', nargs='*', default=[],
help='Specific filenames to run hooks on.',
)
parser.add_argument(
'--checkout-type',
help=(
'Indicates whether the checkout was a branch checkout '
'(changing branches, flag=1) or a file checkout (retrieving a '
'file from the index, flag=0).'
),
)


def _adjust_args_and_chdir(args: argparse.Namespace) -> None:
Expand Down
2 changes: 2 additions & 0 deletions testing/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def run_opts(
hook_stage='commit',
show_diff_on_failure=False,
commit_msg_filename='',
checkout_type='',
):
# These are mutually exclusive
assert not (all_files and files)
Expand All @@ -88,6 +89,7 @@ def run_opts(
hook_stage=hook_stage,
show_diff_on_failure=show_diff_on_failure,
commit_msg_filename=commit_msg_filename,
checkout_type=checkout_type,
)


Expand Down
10 changes: 10 additions & 0 deletions tests/commands/hook_impl_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,16 @@ def test_run_ns_commit_msg():
assert ns.commit_msg_filename == '.git/COMMIT_MSG'


def test_run_ns_post_checkout():
ns = hook_impl._run_ns('post-checkout', True, ('a', 'b', 'c'), b'')
assert ns is not None
assert ns.hook_stage == 'post-checkout'
assert ns.color is True
assert ns.source == 'a'
assert ns.origin == 'b'
assert ns.checkout_type == 'c'


@pytest.fixture
def push_example(tempdir_factory):
src = git_dir(tempdir_factory)
Expand Down
26 changes: 26 additions & 0 deletions tests/commands/install_uninstall_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from testing.fixtures import git_dir
from testing.fixtures import make_consuming_repo
from testing.fixtures import remove_config_from_repo
from testing.fixtures import write_config
from testing.util import cmd_output_mocked_pre_commit_home
from testing.util import cwd
from testing.util import git_commit
Expand Down Expand Up @@ -725,6 +726,31 @@ def test_commit_msg_legacy(commit_msg_repo, tempdir_factory, store):
assert second_line.startswith('Must have "Signed off by:"...')


def test_post_checkout_integration(tempdir_factory, store):
path = git_dir(tempdir_factory)
config = {
'repo': 'local',
'hooks': [{
'id': 'post-checkout',
'name': 'Post checkout',
'entry': 'bash -c "echo ${PRE_COMMIT_ORIGIN}"',
'language': 'system',
'always_run': True,
'verbose': True,
'stages': ['post-checkout'],
}],
}
write_config(path, config)
with cwd(path):
cmd_output('git', 'add', '.')
git_commit()
install(C.CONFIG_FILE, store, hook_types=['post-checkout'])
retc, _, stderr = cmd_output('git', 'checkout', '-b', 'feature')
assert retc == 0
_, head, _ = cmd_output('git', 'rev-parse', 'HEAD')
assert head in str(stderr)


def test_prepare_commit_msg_integration_failing(
failing_prepare_commit_msg_repo, tempdir_factory, store,
):
Expand Down
10 changes: 10 additions & 0 deletions tests/commands/run_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from pre_commit.commands.run import filter_by_include_exclude
from pre_commit.commands.run import run
from pre_commit.util import cmd_output
from pre_commit.util import EnvironT
from pre_commit.util import make_executable
from testing.auto_namedtuple import auto_namedtuple
from testing.fixtures import add_config_to_repo
Expand Down Expand Up @@ -466,6 +467,15 @@ def test_all_push_options_ok(cap_out, store, repo_with_passing_hook):
assert b'Specify both --origin and --source.' not in printed


def test_checkout_type(cap_out, store, repo_with_passing_hook):
args = run_opts(origin='', source='', checkout_type='1')
environ: EnvironT = {}
ret, printed = _do_run(
cap_out, store, repo_with_passing_hook, args, environ,
)
assert environ['PRE_COMMIT_CHECKOUT_TYPE'] == '1'


def test_has_unmerged_paths(in_merge_conflict):
assert _has_unmerged_paths() is True
cmd_output('git', 'add', '.')
Expand Down
2 changes: 1 addition & 1 deletion tests/repository_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ def test_manifest_hooks(tempdir_factory, store):
require_serial=False,
stages=(
'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg',
'manual', 'push',
'manual', 'post-checkout', 'push',
),
types=['file'],
verbose=False,
Expand Down