From 6d22fc01d0cede003b718925b61d45d53eabafcb Mon Sep 17 00:00:00 2001 From: George Ogden Date: Mon, 6 Oct 2025 18:19:04 +0200 Subject: [PATCH] Add --hook-args option to try-repo --- pre_commit/commands/try_repo.py | 10 ++++++++- pre_commit/main.py | 10 +++++++++ tests/commands/try_repo_test.py | 36 +++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/pre_commit/commands/try_repo.py b/pre_commit/commands/try_repo.py index 539ed3c2..3a2ef7dd 100644 --- a/pre_commit/commands/try_repo.py +++ b/pre_commit/commands/try_repo.py @@ -4,6 +4,7 @@ import argparse import logging import os.path import tempfile +import warnings import pre_commit.constants as C from pre_commit import git @@ -54,8 +55,15 @@ def try_repo(args: argparse.Namespace) -> int: store = Store(tempdir) if args.hook: - hooks = [{'id': args.hook}] + hook = {'id': args.hook} + if args.hook_args is not None: + hook['args'] = args.hook_args + hooks = [hook] else: + if args.hook_args is not None: + warnings.warn( + "Unused flag '--hook-args' as 'hook' is not specified.", + ) repo_path = store.clone(repo, ref) manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE)) manifest = sorted(manifest, key=lambda hook: hook['id']) diff --git a/pre_commit/main.py b/pre_commit/main.py index c33fbfda..e17cb2a2 100644 --- a/pre_commit/main.py +++ b/pre_commit/main.py @@ -3,6 +3,7 @@ from __future__ import annotations import argparse import logging import os +import shlex import sys from collections.abc import Sequence @@ -171,6 +172,14 @@ def _add_run_options(parser: argparse.ArgumentParser) -> None: ) +def _add_hook_flags_option(parser: argparse.ArgumentParser) -> None: + parser.add_argument( + '--hook-args', + type=shlex.split, + help='Raw string with flags to pass into the hook (if specified).', + ) + + def _adjust_args_and_chdir(args: argparse.Namespace) -> None: # `--config` was specified relative to the non-root working directory if os.path.exists(args.config): @@ -324,6 +333,7 @@ def main(argv: Sequence[str] | None = None) -> int: ), ) _add_run_options(try_repo_parser) + _add_hook_flags_option(try_repo_parser) uninstall_parser = _add_cmd( 'uninstall', help='Uninstall the pre-commit script.', diff --git a/tests/commands/try_repo_test.py b/tests/commands/try_repo_test.py index c5f891ea..9075b4be 100644 --- a/tests/commands/try_repo_test.py +++ b/tests/commands/try_repo_test.py @@ -19,8 +19,13 @@ from testing.util import git_commit from testing.util import run_opts -def try_repo_opts(repo, ref=None, **kwargs): - return auto_namedtuple(repo=repo, ref=ref, **run_opts(**kwargs)._asdict()) +def try_repo_opts(repo, ref=None, hook_args=None, **kwargs): + return auto_namedtuple( + repo=repo, + ref=ref, + hook_args=hook_args, + **run_opts(**kwargs)._asdict(), + ) def _get_out(cap_out): @@ -89,6 +94,33 @@ Bash hook............................................(no files to check)Skipped ''' +def test_try_repo_with_specific_hook_and_args(cap_out, tempdir_factory): + _run_try_repo( + tempdir_factory, + hook='bash_hook', + hook_args=['pwd', '&&', 'ls'], + verbose=True, + ) + start, config, rest = _get_out(cap_out) + assert start == '' + config_pattern = re_assert.Matches( + '^repos:\n' + '- repo: .+\n' + ' rev: .+\n' + ' hooks:\n' + ' - id: bash_hook\n' + ' args:\n' + ' - pwd\n' + ' - \'&&\'\n' + ' - ls\n$', + ) + config_pattern.assert_matches(config) + assert rest == '''\ +Bash hook............................................(no files to check)Skipped +- hook id: bash_hook +''' + + def test_try_repo_relative_path(cap_out, tempdir_factory): repo = make_repo(tempdir_factory, 'modified_file_returns_zero_repo') with cwd(git_dir(tempdir_factory)):