Path: blob/trunk/scripts/update_multitool_binaries.py
1856 views
#!/usr/bin/env python12"""3This script updates the version of tool binaries defined in a Bazel rules_multitool lockfile.4If the tool has binaries hosted in a public GitHub repo's Release assets, it will update the5lockfile's URL and hash to the latest versions, otherwise it will skip it.67See: https://github.com/theoremlp/rules_multitool89-----------------------------------------------------------------------------------------------------------10usage: update_multitool_binaries.py [-h] [--file LOCKFILE_PATH]1112options:13-h, --help show this help message and exit14--file LOCKFILE_PATH path to multitool lockfile (defaults to 'multitool.lock.json' in current directory)15-----------------------------------------------------------------------------------------------------------16"""1718import argparse19import json20import os21import re22import urllib.request232425def run(lockfile_path):26with open(lockfile_path) as f:27data = json.load(f)2829for tool in [tool for tool in data if tool != "$schema"]:30match = re.search(f"download/(.*?)/{tool}", data[tool]["binaries"][0]["url"])31if match:32version = match[1]33else:34continue35match = re.search("github.com/(.*?)/releases", data[tool]["binaries"][0]["url"])36if match:37releases_url = f"https://api.github.com/repos/{match[1]}/releases/latest"38else:39continue40try:41with urllib.request.urlopen(releases_url) as response:42json_resp = json.loads(response.read())43new_version = json_resp["tag_name"]44assets = json_resp["assets"]45except Exception:46continue47if new_version != version:48print(f"found new version of '{tool}': {new_version}")49urls = [asset.get("browser_download_url") for asset in assets]50hashes = [asset.get("digest").split(":")[1] for asset in assets]51for binary in data[tool]["binaries"]:52new_url = binary["url"].replace(version, new_version)53new_hash = hashes[urls.index(new_url)]54binary["url"] = new_url55binary["sha256"] = new_hash5657with open(lockfile_path, "w") as f:58json.dump(data, f, indent=2)5960print(f"\ngenerated new '{lockfile_path}' with updated urls and hashes")616263def main():64parser = argparse.ArgumentParser()65parser.add_argument(66"--file",67dest="lockfile_path",68default=os.path.join(os.getcwd(), "multitool.lock.json"),69help="path to multitool lockfile (defaults to 'multitool.lock.json' in current directory)",70)71args = parser.parse_args()72run(args.lockfile_path)737475if __name__ == "__main__":76main()777879