From 5591d99ee239be9116f4879bfea4a538b0b89e9c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 23 Apr 2024 12:17:13 -0400 Subject: 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 Tested-by: Mike Frysinger Reviewed-by: Josip Sokcevic --- release/update-hooks | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100755 release/update-hooks (limited to 'release') 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 @@ +#!/usr/bin/env python3 +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Helper tool for updating hooks from their various upstreams.""" + +import argparse +import base64 +import json +from pathlib import Path +import sys +from typing import List, Optional +import urllib.request + + +assert sys.version_info >= (3, 8), "Python 3.8+ required" + + +TOPDIR = Path(__file__).resolve().parent.parent +HOOKS_DIR = TOPDIR / "hooks" + + +def update_hook_commit_msg() -> None: + """Update commit-msg hook from Gerrit.""" + hook = HOOKS_DIR / "commit-msg" + print( + f"{hook.name}: Updating from https://gerrit.googlesource.com/gerrit/" + "+/HEAD/resources/com/google/gerrit/server/tools/root/hooks/commit-msg" + ) + + # Get the current commit. + url = "https://gerrit.googlesource.com/gerrit/+/HEAD?format=JSON" + with urllib.request.urlopen(url) as fp: + data = fp.read() + # Discard the xss protection. + data = data.split(b"\n", 1)[1] + data = json.loads(data) + commit = data["commit"] + + # Fetch the data for that commit. + url = ( + f"https://gerrit.googlesource.com/gerrit/+/{commit}/" + "resources/com/google/gerrit/server/tools/root/hooks/commit-msg" + ) + with urllib.request.urlopen(f"{url}?format=TEXT") as fp: + data = fp.read() + + # gitiles base64 encodes text data. + data = base64.b64decode(data) + + # Inject header into the hook. + lines = data.split(b"\n") + lines = ( + lines[:1] + + [ + b"# DO NOT EDIT THIS FILE", + ( + b"# All updates should be sent upstream: " + b"https://gerrit.googlesource.com/gerrit/" + ), + f"# This is synced from commit: {commit}".encode("utf-8"), + b"# DO NOT EDIT THIS FILE", + ] + + lines[1:] + ) + data = b"\n".join(lines) + + # Update the hook. + hook.write_bytes(data) + hook.chmod(0o755) + + +def update_hook_pre_auto_gc() -> None: + """Update pre-auto-gc hook from git.""" + hook = HOOKS_DIR / "pre-auto-gc" + print( + f"{hook.name}: Updating from https://github.com/git/git/" + "HEAD/contrib/hooks/pre-auto-gc-battery" + ) + + # Get the current commit. + headers = { + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + } + url = "https://api.github.com/repos/git/git/git/refs/heads/master" + req = urllib.request.Request(url, headers=headers) + with urllib.request.urlopen(req) as fp: + data = fp.read() + data = json.loads(data) + + # Fetch the data for that commit. + commit = data["object"]["sha"] + url = ( + f"https://raw.githubusercontent.com/git/git/{commit}/" + "contrib/hooks/pre-auto-gc-battery" + ) + with urllib.request.urlopen(url) as fp: + data = fp.read() + + # Inject header into the hook. + lines = data.split(b"\n") + lines = ( + lines[:1] + + [ + b"# DO NOT EDIT THIS FILE", + ( + b"# All updates should be sent upstream: " + b"https://github.com/git/git/" + ), + f"# This is synced from commit: {commit}".encode("utf-8"), + b"# DO NOT EDIT THIS FILE", + ] + + lines[1:] + ) + data = b"\n".join(lines) + + # Update the hook. + hook.write_bytes(data) + hook.chmod(0o755) + + +def main(argv: Optional[List[str]] = None) -> Optional[int]: + parser = argparse.ArgumentParser(description=__doc__) + parser.parse_args(argv) + + update_hook_commit_msg() + update_hook_pre_auto_gc() + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) -- cgit v1.2.3-54-g00ecf