Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/scripts/update_multitool_binaries.py
8296 views
1
#!/usr/bin/env python
2
"""Update tool binaries in a Bazel rules_multitool lockfile.
3
4
This script updates the version of tool binaries defined in a Bazel rules_multitool lockfile.
5
If the tool has binaries hosted in a public GitHub repo's Release assets, it will update the
6
lockfile's URL and hash to the latest versions, otherwise it will skip it.
7
8
See: https://github.com/theoremlp/rules_multitool
9
10
-----------------------------------------------------------------------------------------------------------
11
usage: update_multitool_binaries.py [-h] [--file LOCKFILE_PATH]
12
13
options:
14
-h, --help show this help message and exit
15
--file LOCKFILE_PATH path to multitool lockfile (defaults to 'multitool.lock.json' in workspace directory)
16
-----------------------------------------------------------------------------------------------------------
17
"""
18
19
import argparse
20
import json
21
import os
22
import re
23
import urllib.request
24
25
26
def run(lockfile_path):
27
with open(lockfile_path) as f:
28
data = json.load(f)
29
30
for tool in [tool for tool in data if tool != "$schema"]:
31
match = re.search(f"download/(.*?)/{tool}", data[tool]["binaries"][0]["url"])
32
if match:
33
version = match[1]
34
else:
35
continue
36
match = re.search("github.com/(.*?)/releases", data[tool]["binaries"][0]["url"])
37
if match:
38
releases_url = f"https://api.github.com/repos/{match[1]}/releases/latest"
39
else:
40
continue
41
try:
42
with urllib.request.urlopen(releases_url) as response:
43
json_resp = json.loads(response.read())
44
new_version = json_resp["tag_name"]
45
assets = json_resp["assets"]
46
except Exception:
47
continue
48
if new_version != version:
49
print(f"found new version of '{tool}': {new_version}")
50
urls = [asset.get("browser_download_url") for asset in assets]
51
hashes = [asset.get("digest").split(":")[1] for asset in assets]
52
bare_version = version.lstrip("v")
53
bare_new = new_version.lstrip("v")
54
for binary in data[tool]["binaries"]:
55
new_url = binary["url"].replace(version, new_version)
56
new_file = binary["file"].replace(version, new_version)
57
if bare_version != version:
58
new_url = new_url.replace(bare_version, bare_new)
59
new_file = new_file.replace(bare_version, bare_new)
60
new_hash = hashes[urls.index(new_url)]
61
binary["url"] = new_url
62
binary["file"] = new_file
63
binary["sha256"] = new_hash
64
65
with open(lockfile_path, "w") as f:
66
json.dump(data, f, indent=2)
67
f.write("\n")
68
69
print(f"\ngenerated new '{lockfile_path}' with updated urls and hashes")
70
71
72
def main():
73
parser = argparse.ArgumentParser()
74
workspace_dir = os.environ.get("BUILD_WORKSPACE_DIRECTORY", os.getcwd())
75
parser.add_argument(
76
"--file",
77
dest="lockfile_path",
78
default=os.path.join(workspace_dir, "multitool.lock.json"),
79
help="path to multitool lockfile (defaults to 'multitool.lock.json' in workspace directory)",
80
)
81
args = parser.parse_args()
82
run(args.lockfile_path)
83
84
85
if __name__ == "__main__":
86
main()
87
88