From 50620d2a2d6324ca0e8e34329d13626f064ceee4 Mon Sep 17 00:00:00 2001 From: Kenny Cheng Date: Mon, 2 Jun 2025 21:55:04 +0800 Subject: [PATCH] sync: support post-sync hook in Add support for a new hook type "post-sync" declared in the manifest using . This allows executing a script automatically after a successful `repo sync`. This is useful for initializing developer environments, installing project-wide Git hooks, generating configs, and other post-sync automation tasks. Example manifest usage: The hook script must be named `post-sync.py` and located at the root of the hook project. The post-sync hook does not block `repo sync`; if the script fails, the sync still completes successfully with a warning. Test: Added `post-sync.py` in hook project and verified it runs after `repo sync` Change-Id: I69f3158f0fc319d73a85028d6e90fea02c1dc8c8 Signed-off-by: Kenny Cheng --- docs/repo-hooks.md | 27 +++++++++++++++++++++++++++ subcmds/sync.py | 26 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/docs/repo-hooks.md b/docs/repo-hooks.md index cbb1aac7c..b6a2e98f8 100644 --- a/docs/repo-hooks.md +++ b/docs/repo-hooks.md @@ -133,3 +133,30 @@ def main(project_list, worktree_list=None, **kwargs): kwargs: Leave this here for forward-compatibility. """ ``` + +### Hook: post-sync + +The `post-sync` hook allows you to execute a script automatically after a +successful `repo sync`. This is useful for post-processing tasks such as +setting up git hooks, bootstrapping configuration files, or running project +initialization logic. + +The hook is defined using the existing `` manifest block and is +optional. If the hook script fails or is missing, `repo sync` will still +complete successfully, and the error will be printed as a warning. + +Example: + +```xml + + + + +``` + +The `post-sync.py` file should be defined like: + +```py +def main(**kwargs): + print("Running post-sync tasks...") +``` diff --git a/subcmds/sync.py b/subcmds/sync.py index 3a4151dfe..d3b91ae59 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py @@ -79,6 +79,7 @@ from repo_logging import RepoLogger from repo_trace import Trace import ssh from wrapper import Wrapper +from hooks import RepoHook _ONE_DAY_S = 24 * 60 * 60 @@ -1736,11 +1737,36 @@ later is required to fix a server side protocol bug. errors = [] try: self._ExecuteHelper(opt, args, errors) + self._RunPostSyncHook(opt) + except (RepoExitError, RepoChangedException): raise except (KeyboardInterrupt, Exception) as e: raise RepoUnhandledExceptionError(e, aggregate_errors=errors) + def _RunPostSyncHook(self, opt): + """Run post-sync hook if configured in manifest .""" + + # Inject required flags into opt if missing + for attr in ("bypass_hooks", "allow_all_hooks", "ignore_hooks"): + if not hasattr(opt, attr): + if attr == "bypass_hooks": + setattr(opt, attr, False) + else: + setattr(opt, attr, True) + + try: + post_sync_hook = RepoHook.FromSubcmd( + hook_type="post-sync", + manifest=self.manifest, + opt=opt, + abort_if_user_denies=False, + ) + post_sync_hook.Run() + + except Exception as e: + print(f"Warning: post-sync hook failed: {e}") + def _ExecuteHelper(self, opt, args, errors): manifest = self.outer_manifest if not opt.outer_manifest: