summaryrefslogtreecommitdiffstats
path: root/release/update-hooks
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2024-04-23 12:17:13 -0400
committerLUCI <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com>2024-04-23 18:31:51 +0000
commit5591d99ee239be9116f4879bfea4a538b0b89e9c (patch)
tree282752df0312e75204026badcc72acc9901e3222 /release/update-hooks
parent9d865454aaf0ea41927332768e55b5b2f56e2533 (diff)
downloadgit-repo-5591d99ee239be9116f4879bfea4a538b0b89e9c.tar.gz
release: update-hooks: helper for automatically syncing hooks
These hooks are maintained in other projects. Add a script to automate their import so people don't send us changes directly, and we can try to steer them to the correct place. Change-Id: Iac0bdb3aae84dda43a1600e73107555b513ce82b Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/422177 Commit-Queue: Mike Frysinger <vapier@google.com> Tested-by: Mike Frysinger <vapier@google.com> Reviewed-by: Josip Sokcevic <sokcevic@google.com>
Diffstat (limited to 'release/update-hooks')
-rwxr-xr-xrelease/update-hooks143
1 files changed, 143 insertions, 0 deletions
diff --git a/release/update-hooks b/release/update-hooks
new file mode 100755
index 00000000..def4bba9
--- /dev/null
+++ b/release/update-hooks
@@ -0,0 +1,143 @@
1#!/usr/bin/env python3
2# Copyright (C) 2024 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16"""Helper tool for updating hooks from their various upstreams."""
17
18import argparse
19import base64
20import json
21from pathlib import Path
22import sys
23from typing import List, Optional
24import urllib.request
25
26
27assert sys.version_info >= (3, 8), "Python 3.8+ required"
28
29
30TOPDIR = Path(__file__).resolve().parent.parent
31HOOKS_DIR = TOPDIR / "hooks"
32
33
34def update_hook_commit_msg() -> None:
35 """Update commit-msg hook from Gerrit."""
36 hook = HOOKS_DIR / "commit-msg"
37 print(
38 f"{hook.name}: Updating from https://gerrit.googlesource.com/gerrit/"
39 "+/HEAD/resources/com/google/gerrit/server/tools/root/hooks/commit-msg"
40 )
41
42 # Get the current commit.
43 url = "https://gerrit.googlesource.com/gerrit/+/HEAD?format=JSON"
44 with urllib.request.urlopen(url) as fp:
45 data = fp.read()
46 # Discard the xss protection.
47 data = data.split(b"\n", 1)[1]
48 data = json.loads(data)
49 commit = data["commit"]
50
51 # Fetch the data for that commit.
52 url = (
53 f"https://gerrit.googlesource.com/gerrit/+/{commit}/"
54 "resources/com/google/gerrit/server/tools/root/hooks/commit-msg"
55 )
56 with urllib.request.urlopen(f"{url}?format=TEXT") as fp:
57 data = fp.read()
58
59 # gitiles base64 encodes text data.
60 data = base64.b64decode(data)
61
62 # Inject header into the hook.
63 lines = data.split(b"\n")
64 lines = (
65 lines[:1]
66 + [
67 b"# DO NOT EDIT THIS FILE",
68 (
69 b"# All updates should be sent upstream: "
70 b"https://gerrit.googlesource.com/gerrit/"
71 ),
72 f"# This is synced from commit: {commit}".encode("utf-8"),
73 b"# DO NOT EDIT THIS FILE",
74 ]
75 + lines[1:]
76 )
77 data = b"\n".join(lines)
78
79 # Update the hook.
80 hook.write_bytes(data)
81 hook.chmod(0o755)
82
83
84def update_hook_pre_auto_gc() -> None:
85 """Update pre-auto-gc hook from git."""
86 hook = HOOKS_DIR / "pre-auto-gc"
87 print(
88 f"{hook.name}: Updating from https://github.com/git/git/"
89 "HEAD/contrib/hooks/pre-auto-gc-battery"
90 )
91
92 # Get the current commit.
93 headers = {
94 "Accept": "application/vnd.github+json",
95 "X-GitHub-Api-Version": "2022-11-28",
96 }
97 url = "https://api.github.com/repos/git/git/git/refs/heads/master"
98 req = urllib.request.Request(url, headers=headers)
99 with urllib.request.urlopen(req) as fp:
100 data = fp.read()
101 data = json.loads(data)
102
103 # Fetch the data for that commit.
104 commit = data["object"]["sha"]
105 url = (
106 f"https://raw.githubusercontent.com/git/git/{commit}/"
107 "contrib/hooks/pre-auto-gc-battery"
108 )
109 with urllib.request.urlopen(url) as fp:
110 data = fp.read()
111
112 # Inject header into the hook.
113 lines = data.split(b"\n")
114 lines = (
115 lines[:1]
116 + [
117 b"# DO NOT EDIT THIS FILE",
118 (
119 b"# All updates should be sent upstream: "
120 b"https://github.com/git/git/"
121 ),
122 f"# This is synced from commit: {commit}".encode("utf-8"),
123 b"# DO NOT EDIT THIS FILE",
124 ]
125 + lines[1:]
126 )
127 data = b"\n".join(lines)
128
129 # Update the hook.
130 hook.write_bytes(data)
131 hook.chmod(0o755)
132
133
134def main(argv: Optional[List[str]] = None) -> Optional[int]:
135 parser = argparse.ArgumentParser(description=__doc__)
136 parser.parse_args(argv)
137
138 update_hook_commit_msg()
139 update_hook_pre_auto_gc()
140
141
142if __name__ == "__main__":
143 sys.exit(main(sys.argv[1:]))