121 lines
3.4 KiB
Python
Executable file
121 lines
3.4 KiB
Python
Executable file
#!/usr/bin/env nix-shell
|
|
#!nix-shell -p nix -p python3 -p git -i python
|
|
# USAGE - just run the script: ./update.py
|
|
# When editing this file, make also sure it passes the mypy typecheck
|
|
# and is formatted with black.
|
|
import fileinput
|
|
import json
|
|
import xml.etree.ElementTree as ET
|
|
from urllib.parse import urlparse
|
|
import re
|
|
import subprocess
|
|
import tempfile
|
|
import urllib.request
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Dict
|
|
|
|
SCRIPT_DIR = Path(__file__).parent.resolve()
|
|
|
|
|
|
def sh(*args: str) -> str:
|
|
out = subprocess.check_output(list(args))
|
|
return out.strip().decode("utf-8")
|
|
|
|
|
|
def prefetch_github(owner: str, repo: str, ref: str) -> str:
|
|
return sh(
|
|
"nix-prefetch-url",
|
|
"--unpack",
|
|
f"https://github.com/{owner}/{repo}/archive/{ref}.tar.gz",
|
|
)
|
|
|
|
|
|
def get_radare2_rev() -> str:
|
|
feed_url = "https://github.com/radareorg/radare2/releases.atom"
|
|
with urllib.request.urlopen(feed_url) as resp:
|
|
tree = ET.fromstring(resp.read())
|
|
releases = tree.findall(".//{http://www.w3.org/2005/Atom}entry")
|
|
for release in releases:
|
|
link = release.find("{http://www.w3.org/2005/Atom}link")
|
|
assert link is not None
|
|
url = urlparse(link.attrib["href"])
|
|
tag = url.path.split("/")[-1]
|
|
if re.match(r"[0-9.]+", tag):
|
|
return tag
|
|
else:
|
|
print(f"ignore {tag}")
|
|
raise RuntimeError(f"No release found at {feed_url}")
|
|
|
|
|
|
def git(dirname: str, *args: str) -> str:
|
|
return sh("git", "-C", dirname, *args)
|
|
|
|
|
|
def get_repo_info(dirname: str, rev: str) -> Dict[str, str]:
|
|
sha256 = prefetch_github("radare", "radare2", rev)
|
|
|
|
cs_ver = None
|
|
with open(Path(dirname).joinpath("shlr", "Makefile")) as makefile:
|
|
for l in makefile:
|
|
match = re.match("CS_VER=(\S+)", l)
|
|
if match:
|
|
cs_ver = match.group(1)
|
|
assert cs_ver is not None
|
|
|
|
cs_sha256 = prefetch_github("aquynh", "capstone", cs_ver)
|
|
|
|
return dict(
|
|
rev=rev,
|
|
sha256=sha256,
|
|
version_commit=git(dirname, "rev-list", "--all", "--count"),
|
|
gittap=git(dirname, "describe", "--tags", "--match", "[0-9]*"),
|
|
gittip=git(dirname, "rev-parse", "HEAD"),
|
|
cs_ver=cs_ver,
|
|
cs_sha256=cs_sha256,
|
|
)
|
|
|
|
|
|
def main() -> None:
|
|
version = get_radare2_rev()
|
|
|
|
with tempfile.TemporaryDirectory() as dirname:
|
|
git(
|
|
dirname,
|
|
"clone",
|
|
"--branch",
|
|
version,
|
|
"https://github.com/radare/radare2",
|
|
".",
|
|
)
|
|
nix_file = str(SCRIPT_DIR.joinpath("default.nix"))
|
|
|
|
info = get_repo_info(dirname, version)
|
|
|
|
timestamp = git(dirname, "log", "-n1", "--format=%at")
|
|
|
|
in_block = False
|
|
with fileinput.FileInput(nix_file, inplace=True) as f:
|
|
for l in f:
|
|
if "#<generated>" in l:
|
|
in_block = True
|
|
print(
|
|
f""" #<generated>
|
|
# DO NOT EDIT! Automatically generated by ./update.py
|
|
gittap = "{info["gittap"]}";
|
|
gittip = "{info["gittip"]}";
|
|
rev = "{info["rev"]}";
|
|
version = "{version}";
|
|
sha256 = "{info["sha256"]}";
|
|
cs_ver = "{info["cs_ver"]}";
|
|
cs_sha256 = "{info["cs_sha256"]}";
|
|
#</generated>"""
|
|
)
|
|
elif "#</generated>" in l:
|
|
in_block = False
|
|
elif not in_block:
|
|
print(l, end="")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|