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