summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/repo-hooks.md105
1 files changed, 105 insertions, 0 deletions
diff --git a/docs/repo-hooks.md b/docs/repo-hooks.md
new file mode 100644
index 00000000..c8eb945f
--- /dev/null
+++ b/docs/repo-hooks.md
@@ -0,0 +1,105 @@
1# repo hooks
2
3[TOC]
4
5Repo provides a mechanism to hook specific stages of the runtime with custom
6python modules. All the hooks live in one git project which is checked out by
7the manifest (specified during `repo init`), and the manifest itself defines
8which hooks are registered.
9
10These are useful to run linters, check formatting, and run quick unittests
11before allowing a step to proceed (e.g. before uploading a commit to Gerrit).
12
13A complete example can be found in the Android project. It can be easily
14re-used by any repo based project and is not specific to Android.<br>
15https://android.googlesource.com/platform/tools/repohooks
16
17## Approvals
18
19When a hook is processed the first time, the user is prompted for approval.
20We don't want to execute arbitrary code without explicit consent. For manifests
21fetched via secure protocols (e.g. https://), the user is prompted once. For
22insecure protocols (e.g. http://), the user is prompted whenever the registered
23repohooks project is updated and a hook is triggered.
24
25## Manifest Settings
26
27For the full syntax, see the [repo manifest format](./manifest-format.txt).
28
29Here's a short example from
30[Android](https://android.googlesource.com/platform/manifest/+/master/default.xml).
31The `<project>` line checks out the repohooks git repo to the local
32`tools/repohooks/` path. The `<repo-hooks>` line says to look in the project
33with the name `platform/tools/repohooks` for hooks to run during the
34`pre-upload` phase.
35
36```xml
37<project path="tools/repohooks" name="platform/tools/repohooks" />
38<repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" />
39```
40
41## Source Layout
42
43The repohooks git repo should have a python file with the same name as the hook.
44So if you want to support the `pre-upload` hook, you'll need to create a file
45named `pre-upload.py`. Repo will dynamically load that module when processing
46the hook and then call the `main` function in it.
47
48Hooks should have their `main` accept `**kwargs` for future compatibility.
49
50## Runtime
51
52Hook return values are ignored.
53
54Any uncaught exceptions from the hook will cause the step to fail. This is
55intended as a fallback safety check though rather than the normal flow. If
56you want your hook to trigger a failure, it should call `sys.exit()` (after
57displaying relevant diagnostics).
58
59Output (stdout & stderr) are not filtered in any way. Hooks should generally
60not be too verbose. A short summary is nice, and some status information when
61long running operations occur, but long/verbose output should be used only if
62the hook ultimately fails.
63
64The hook runs from the top level of the git repo where the operation is started.
65e.g. If you're in the git repo `src/foo/`, that is where the hook runs, even if
66the `repo` command was started from a subdir like `src/foo/bar/`.
67
68Python's `sys.path` is modified so that the top of repohooks directory comes
69first. This should help simplify the hook logic to easily allow importing of
70local modules.
71
72Repo does not modify the state of the git checkout. This means that the hooks
73might be running in a dirty git repo with many commits and checked out to the
74latest one. If the hook wants to operate on specific git commits, it needs to
75manually discover the list of pending commits, extract the diff/commit, and
76then check it directly. Hooks should not normally modify the active git repo
77(such as checking out a specific commit to run checks) without first prompting
78the user. Although user interaction is discouraged in the common case, it can
79be useful when deploying automatic fixes.
80
81## Hooks
82
83Here are all the points available for hooking.
84
85### pre-upload
86
87This hook runs when people run `repo upload`.
88
89The `pre-upload.py` file should be defined like:
90
91```py
92def main(project_list, worktree_list=None, **kwargs):
93 """Main function invoked directly by repo.
94
95 We must use the name "main" as that is what repo requires.
96
97 Args:
98 project_list: List of projects to run on.
99 worktree_list: A list of directories. It should be the same length as
100 project_list, so that each entry in project_list matches with a
101 directory in worktree_list. If None, we will attempt to calculate
102 the directories automatically.
103 kwargs: Leave this here for forward-compatibility.
104 """
105```