From 57cc814b8ba56ff067803da82ec62a1521a62eed Mon Sep 17 00:00:00 2001 From: David Martinez Barreiro Date: Thu, 16 Jan 2020 18:01:26 +0100 Subject: [PATCH 1/2] Push remote env var details --- pre_commit/commands/run.py | 4 ++++ pre_commit/main.py | 6 ++++++ pre_commit/resources/hook-tmpl | 10 +++++++--- testing/util.py | 4 ++++ tests/commands/run_test.py | 29 +++++++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 3 deletions(-) diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py index 6690bdd4..89a5bef6 100644 --- a/pre_commit/commands/run.py +++ b/pre_commit/commands/run.py @@ -312,6 +312,10 @@ def run( environ['PRE_COMMIT_ORIGIN'] = args.origin environ['PRE_COMMIT_SOURCE'] = args.source + if args.push_remote_name and args.push_remote_url: + environ['PRE_COMMIT_REMOTE_NAME'] = args.push_remote_name + environ['PRE_COMMIT_REMOTE_URL'] = args.push_remote_url + with contextlib.ExitStack() as exit_stack: if stash: exit_stack.enter_context(staged_files_only(store.directory)) diff --git a/pre_commit/main.py b/pre_commit/main.py index d96b35fb..ac2f4166 100644 --- a/pre_commit/main.py +++ b/pre_commit/main.py @@ -101,6 +101,12 @@ def _add_run_options(parser: argparse.ArgumentParser) -> None: '--commit-msg-filename', help='Filename to check when running during `commit-msg`', ) + parser.add_argument( + '--push-remote-name', help='Remote name used by `git push`.', + ) + parser.add_argument( + '--push-remote-url', help='Remote url used by `git push`.', + ) parser.add_argument( '--hook-stage', choices=C.STAGES, default='commit', help='The stage during which the hook is fired. One of %(choices)s', diff --git a/pre_commit/resources/hook-tmpl b/pre_commit/resources/hook-tmpl index 213d16ee..b405aad4 100755 --- a/pre_commit/resources/hook-tmpl +++ b/pre_commit/resources/hook-tmpl @@ -120,7 +120,8 @@ def _rev_exists(rev: str) -> bool: def _pre_push(stdin: bytes) -> Tuple[str, ...]: - remote = sys.argv[1] + remote_name = sys.argv[1] + remote_url = sys.argv[2] opts: Tuple[str, ...] = () for line in stdin.decode().splitlines(): @@ -133,7 +134,7 @@ def _pre_push(stdin: bytes) -> Tuple[str, ...]: # ancestors not found in remote ancestors = subprocess.check_output(( 'git', 'rev-list', local_sha, '--topo-order', '--reverse', - '--not', f'--remotes={remote}', + '--not', f'--remotes={remote_name}', )).decode().strip() if not ancestors: continue @@ -150,7 +151,10 @@ def _pre_push(stdin: bytes) -> Tuple[str, ...]: opts = ('--origin', local_sha, '--source', source) if opts: - return opts + remote_opts = ( + '--push-remote-name', remote_name, '--push-remote-url', remote_url, + ) + return opts + remote_opts else: # An attempt to push an empty changeset raise EarlyExit() diff --git a/testing/util.py b/testing/util.py index 0c2cc6a8..f5caa5e3 100644 --- a/testing/util.py +++ b/testing/util.py @@ -67,6 +67,8 @@ def run_opts( hook=None, origin='', source='', + push_remote_name='', + push_remote_url='', hook_stage='commit', show_diff_on_failure=False, commit_msg_filename='', @@ -81,6 +83,8 @@ def run_opts( hook=hook, origin=origin, source=source, + push_remote_name=push_remote_name, + push_remote_url=push_remote_url, hook_stage=hook_stage, show_diff_on_failure=show_diff_on_failure, commit_msg_filename=commit_msg_filename, diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py index d2e2f236..e56f5390 100644 --- a/tests/commands/run_test.py +++ b/tests/commands/run_test.py @@ -687,6 +687,35 @@ def test_stages(cap_out, store, repo_with_passing_hook): assert _run_for_stage('commit-msg').startswith(b'hook 5...') +def test_push_remote_environment(cap_out, store, repo_with_passing_hook): + config = { + 'repo': 'local', + 'hooks': [ + { + 'id': 'print-push-remote', + 'name': 'Print push remote name', + 'entry': 'entry: bash -c \'echo "$PRE_COMMIT_REMOTE_NAME"\'', + 'language': 'system', + 'verbose': bool(1), + }, + ], + } + add_config_to_repo(repo_with_passing_hook, config) + + _test_run( + cap_out, + store, + repo_with_passing_hook, + opts={ + 'push_remote_name': 'origin', + 'push_remote_url': 'https://github.com/pre-commit/pre-commit', + }, + expected_outputs=[b'Print push remote name', b'Passed'], + expected_ret=0, + stage=['push'], + ) + + def test_commit_msg_hook(cap_out, store, commit_msg_repo): filename = '.git/COMMIT_EDITMSG' with open(filename, 'w') as f: From 0bb8a8fabe9d9ac46266039fd164509c21e53cf5 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 16 Jan 2020 09:55:46 -0800 Subject: [PATCH 2/2] Move test to install_uninstall test so environment variables apply --- pre_commit/commands/run.py | 6 ++-- pre_commit/main.py | 6 ++-- pre_commit/resources/hook-tmpl | 5 ++-- testing/util.py | 8 +++--- tests/commands/install_uninstall_test.py | 32 +++++++++++++++++++-- tests/commands/run_test.py | 36 ++++-------------------- 6 files changed, 46 insertions(+), 47 deletions(-) diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py index 89a5bef6..95f8ab41 100644 --- a/pre_commit/commands/run.py +++ b/pre_commit/commands/run.py @@ -312,9 +312,9 @@ def run( environ['PRE_COMMIT_ORIGIN'] = args.origin environ['PRE_COMMIT_SOURCE'] = args.source - if args.push_remote_name and args.push_remote_url: - environ['PRE_COMMIT_REMOTE_NAME'] = args.push_remote_name - environ['PRE_COMMIT_REMOTE_URL'] = args.push_remote_url + if args.remote_name and args.remote_url: + environ['PRE_COMMIT_REMOTE_NAME'] = args.remote_name + environ['PRE_COMMIT_REMOTE_URL'] = args.remote_url with contextlib.ExitStack() as exit_stack: if stash: diff --git a/pre_commit/main.py b/pre_commit/main.py index ac2f4166..e65d8ae8 100644 --- a/pre_commit/main.py +++ b/pre_commit/main.py @@ -102,11 +102,9 @@ def _add_run_options(parser: argparse.ArgumentParser) -> None: help='Filename to check when running during `commit-msg`', ) parser.add_argument( - '--push-remote-name', help='Remote name used by `git push`.', - ) - parser.add_argument( - '--push-remote-url', help='Remote url used by `git push`.', + '--remote-name', help='Remote name used by `git push`.', ) + parser.add_argument('--remote-url', help='Remote url used by `git push`.') parser.add_argument( '--hook-stage', choices=C.STAGES, default='commit', help='The stage during which the hook is fired. One of %(choices)s', diff --git a/pre_commit/resources/hook-tmpl b/pre_commit/resources/hook-tmpl index b405aad4..573335a9 100755 --- a/pre_commit/resources/hook-tmpl +++ b/pre_commit/resources/hook-tmpl @@ -151,10 +151,9 @@ def _pre_push(stdin: bytes) -> Tuple[str, ...]: opts = ('--origin', local_sha, '--source', source) if opts: - remote_opts = ( - '--push-remote-name', remote_name, '--push-remote-url', remote_url, + return ( + *opts, '--remote-name', remote_name, '--remote-url', remote_url, ) - return opts + remote_opts else: # An attempt to push an empty changeset raise EarlyExit() diff --git a/testing/util.py b/testing/util.py index f5caa5e3..ce3206eb 100644 --- a/testing/util.py +++ b/testing/util.py @@ -67,8 +67,8 @@ def run_opts( hook=None, origin='', source='', - push_remote_name='', - push_remote_url='', + remote_name='', + remote_url='', hook_stage='commit', show_diff_on_failure=False, commit_msg_filename='', @@ -83,8 +83,8 @@ def run_opts( hook=hook, origin=origin, source=source, - push_remote_name=push_remote_name, - push_remote_url=push_remote_url, + remote_name=remote_name, + remote_url=remote_url, hook_stage=hook_stage, show_diff_on_failure=show_diff_on_failure, commit_msg_filename=commit_msg_filename, diff --git a/tests/commands/install_uninstall_test.py b/tests/commands/install_uninstall_test.py index 562293db..984ae74a 100644 --- a/tests/commands/install_uninstall_test.py +++ b/tests/commands/install_uninstall_test.py @@ -15,6 +15,7 @@ from pre_commit.parse_shebang import find_executable from pre_commit.util import cmd_output from pre_commit.util import make_executable from pre_commit.util import resource_text +from testing.fixtures import add_config_to_repo from testing.fixtures import git_dir from testing.fixtures import make_consuming_repo from testing.fixtures import remove_config_from_repo @@ -512,9 +513,9 @@ def test_installed_from_venv(tempdir_factory, store): assert NORMAL_PRE_COMMIT_RUN.match(output) -def _get_push_output(tempdir_factory, opts=()): +def _get_push_output(tempdir_factory, remote='origin', opts=()): return cmd_output_mocked_pre_commit_home( - 'git', 'push', 'origin', 'HEAD:new_branch', *opts, + 'git', 'push', remote, 'HEAD:new_branch', *opts, tempdir_factory=tempdir_factory, retcode=None, )[:2] @@ -589,6 +590,33 @@ def test_pre_push_new_upstream(tempdir_factory, store): assert 'Passed' in output +def test_pre_push_environment_variables(tempdir_factory, store): + config = { + 'repo': 'local', + 'hooks': [ + { + 'id': 'print-remote-info', + 'name': 'print remote info', + 'entry': 'bash -c "echo remote: $PRE_COMMIT_REMOTE_NAME"', + 'language': 'system', + 'verbose': True, + }, + ], + } + + upstream = git_dir(tempdir_factory) + clone = tempdir_factory.get() + cmd_output('git', 'clone', upstream, clone) + add_config_to_repo(clone, config) + with cwd(clone): + install(C.CONFIG_FILE, store, hook_types=['pre-push']) + + cmd_output('git', 'remote', 'rename', 'origin', 'origin2') + retc, output = _get_push_output(tempdir_factory, remote='origin2') + assert retc == 0 + assert '\nremote: origin2\n' in output + + def test_pre_push_integration_empty_push(tempdir_factory, store): upstream = make_consuming_repo(tempdir_factory, 'script_hooks_repo') path = tempdir_factory.get() diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py index e56f5390..87eef2ec 100644 --- a/tests/commands/run_test.py +++ b/tests/commands/run_test.py @@ -456,8 +456,11 @@ def test_origin_source_error_msg_error( assert b'Specify both --origin and --source.' in printed -def test_origin_source_both_ok(cap_out, store, repo_with_passing_hook): - args = run_opts(origin='master', source='master') +def test_all_push_options_ok(cap_out, store, repo_with_passing_hook): + args = run_opts( + origin='master', source='master', + remote_name='origin', remote_url='https://example.com/repo', + ) ret, printed = _do_run(cap_out, store, repo_with_passing_hook, args) assert ret == 0 assert b'Specify both --origin and --source.' not in printed @@ -687,35 +690,6 @@ def test_stages(cap_out, store, repo_with_passing_hook): assert _run_for_stage('commit-msg').startswith(b'hook 5...') -def test_push_remote_environment(cap_out, store, repo_with_passing_hook): - config = { - 'repo': 'local', - 'hooks': [ - { - 'id': 'print-push-remote', - 'name': 'Print push remote name', - 'entry': 'entry: bash -c \'echo "$PRE_COMMIT_REMOTE_NAME"\'', - 'language': 'system', - 'verbose': bool(1), - }, - ], - } - add_config_to_repo(repo_with_passing_hook, config) - - _test_run( - cap_out, - store, - repo_with_passing_hook, - opts={ - 'push_remote_name': 'origin', - 'push_remote_url': 'https://github.com/pre-commit/pre-commit', - }, - expected_outputs=[b'Print push remote name', b'Passed'], - expected_ret=0, - stage=['push'], - ) - - def test_commit_msg_hook(cap_out, store, commit_msg_repo): filename = '.git/COMMIT_EDITMSG' with open(filename, 'w') as f: