diff options
| author | Mike Frysinger <vapier@google.com> | 2025-06-05 16:53:40 -0400 |
|---|---|---|
| committer | LUCI <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2025-06-06 11:12:13 -0700 |
| commit | 044e52e23655167877f693a7f0ce934a054d38af (patch) | |
| tree | d7e9dcb0b5a34c3076a9bebf5af0e97823b1bb7d | |
| parent | 0cb88a8d791486d7c9bc86b6fdfdd26f64a37006 (diff) | |
| download | git-repo-044e52e23655167877f693a7f0ce934a054d38af.tar.gz | |
hooks: add internal check for external hook API
Add an internal check to make sure we always follow the API we've
documented for external authors. Since the internal call is a bit
ad-hoc, it can be easy to miss a call site.
Change-Id: Ie8cd298d1fc34f10f3c5eb353512a3e881f42252
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/481721
Reviewed-by: Nasser Grainawi <nasser.grainawi@oss.qualcomm.com>
Reviewed-by: Gavin Mak <gavinmak@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
Commit-Queue: Mike Frysinger <vapier@google.com>
| -rw-r--r-- | hooks.py | 24 |
1 files changed, 24 insertions, 0 deletions
| @@ -22,6 +22,12 @@ from error import HookError | |||
| 22 | from git_refs import HEAD | 22 | from git_refs import HEAD |
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | # The API we've documented to hook authors. Keep in sync with repo-hooks.md. | ||
| 26 | _API_ARGS = { | ||
| 27 | "pre-upload": {"project_list", "worktree_list"}, | ||
| 28 | } | ||
| 29 | |||
| 30 | |||
| 25 | class RepoHook: | 31 | class RepoHook: |
| 26 | """A RepoHook contains information about a script to run as a hook. | 32 | """A RepoHook contains information about a script to run as a hook. |
| 27 | 33 | ||
| @@ -56,6 +62,7 @@ class RepoHook: | |||
| 56 | hooks_project, | 62 | hooks_project, |
| 57 | repo_topdir, | 63 | repo_topdir, |
| 58 | manifest_url, | 64 | manifest_url, |
| 65 | bug_url=None, | ||
| 59 | bypass_hooks=False, | 66 | bypass_hooks=False, |
| 60 | allow_all_hooks=False, | 67 | allow_all_hooks=False, |
| 61 | ignore_hooks=False, | 68 | ignore_hooks=False, |
| @@ -75,6 +82,7 @@ class RepoHook: | |||
| 75 | run with CWD as this directory. | 82 | run with CWD as this directory. |
| 76 | If you have a manifest, this is manifest.topdir. | 83 | If you have a manifest, this is manifest.topdir. |
| 77 | manifest_url: The URL to the manifest git repo. | 84 | manifest_url: The URL to the manifest git repo. |
| 85 | bug_url: The URL to report issues. | ||
| 78 | bypass_hooks: If True, then 'Do not run the hook'. | 86 | bypass_hooks: If True, then 'Do not run the hook'. |
| 79 | allow_all_hooks: If True, then 'Run the hook without prompting'. | 87 | allow_all_hooks: If True, then 'Run the hook without prompting'. |
| 80 | ignore_hooks: If True, then 'Do not abort action if hooks fail'. | 88 | ignore_hooks: If True, then 'Do not abort action if hooks fail'. |
| @@ -85,6 +93,7 @@ class RepoHook: | |||
| 85 | self._hooks_project = hooks_project | 93 | self._hooks_project = hooks_project |
| 86 | self._repo_topdir = repo_topdir | 94 | self._repo_topdir = repo_topdir |
| 87 | self._manifest_url = manifest_url | 95 | self._manifest_url = manifest_url |
| 96 | self._bug_url = bug_url | ||
| 88 | self._bypass_hooks = bypass_hooks | 97 | self._bypass_hooks = bypass_hooks |
| 89 | self._allow_all_hooks = allow_all_hooks | 98 | self._allow_all_hooks = allow_all_hooks |
| 90 | self._ignore_hooks = ignore_hooks | 99 | self._ignore_hooks = ignore_hooks |
| @@ -414,6 +423,20 @@ class RepoHook: | |||
| 414 | ignore the result through the option combinations as listed in | 423 | ignore the result through the option combinations as listed in |
| 415 | AddHookOptionGroup(). | 424 | AddHookOptionGroup(). |
| 416 | """ | 425 | """ |
| 426 | # Make sure our own callers use the documented API. | ||
| 427 | exp_kwargs = _API_ARGS.get(self._hook_type, set()) | ||
| 428 | got_kwargs = set(kwargs.keys()) | ||
| 429 | if exp_kwargs != got_kwargs: | ||
| 430 | print( | ||
| 431 | "repo internal error: " | ||
| 432 | f"hook '{self._hook_type}' called incorrectly\n" | ||
| 433 | f" got: {sorted(got_kwargs)}\n" | ||
| 434 | f" expected: {sorted(exp_kwargs)}\n" | ||
| 435 | f"Please file a bug: {self._bug_url}", | ||
| 436 | file=sys.stderr, | ||
| 437 | ) | ||
| 438 | return False | ||
| 439 | |||
| 417 | # Do not do anything in case bypass_hooks is set, or | 440 | # Do not do anything in case bypass_hooks is set, or |
| 418 | # no-op if there is no hooks project or if hook is disabled. | 441 | # no-op if there is no hooks project or if hook is disabled. |
| 419 | if ( | 442 | if ( |
| @@ -472,6 +495,7 @@ class RepoHook: | |||
| 472 | "manifest_url": manifest.manifestProject.GetRemote( | 495 | "manifest_url": manifest.manifestProject.GetRemote( |
| 473 | "origin" | 496 | "origin" |
| 474 | ).url, | 497 | ).url, |
| 498 | "bug_url": manifest.contactinfo.bugurl, | ||
| 475 | } | 499 | } |
| 476 | ) | 500 | ) |
| 477 | return cls(*args, **kwargs) | 501 | return cls(*args, **kwargs) |
