marioparty4/tools/download_tool.py
2024-11-20 13:02:55 -05:00

127 lines
3.4 KiB
Python

#!/usr/bin/env python3
###
# Downloads various tools from GitHub releases.
#
# Usage:
# python3 tools/download_tool.py wibo build/tools/wibo --tag 1.0.0
#
# If changes are made, please submit a PR to
# https://github.com/encounter/dtk-template
###
import argparse
import io
import os
import platform
import shutil
import stat
import urllib.request
import zipfile
from typing import Callable, Dict
from pathlib import Path
import certifi
import ssl
def binutils_url(tag):
uname = platform.uname()
system = uname.system.lower()
arch = uname.machine.lower()
if system == "darwin":
system = "macos"
arch = "universal"
elif arch == "amd64":
arch = "x86_64"
repo = "https://github.com/encounter/gc-wii-binutils"
return f"{repo}/releases/download/{tag}/{system}-{arch}.zip"
def compilers_url(tag: str) -> str:
return f"https://files.decomp.dev/compilers_{tag}.zip"
def dtk_url(tag: str) -> str:
uname = platform.uname()
suffix = ""
system = uname.system.lower()
if system == "darwin":
system = "macos"
elif system == "windows":
suffix = ".exe"
arch = uname.machine.lower()
if arch == "amd64":
arch = "x86_64"
repo = "https://github.com/encounter/decomp-toolkit"
return f"{repo}/releases/download/{tag}/dtk-{system}-{arch}{suffix}"
def objdiff_cli_url(tag: str) -> str:
uname = platform.uname()
suffix = ""
system = uname.system.lower()
if system == "darwin":
system = "macos"
elif system == "windows":
suffix = ".exe"
arch = uname.machine.lower()
if arch == "amd64":
arch = "x86_64"
repo = "https://github.com/encounter/objdiff"
return f"{repo}/releases/download/{tag}/objdiff-cli-{system}-{arch}{suffix}"
def sjiswrap_url(tag: str) -> str:
repo = "https://github.com/encounter/sjiswrap"
return f"{repo}/releases/download/{tag}/sjiswrap-windows-x86.exe"
def wibo_url(tag: str) -> str:
repo = "https://github.com/decompals/wibo"
return f"{repo}/releases/download/{tag}/wibo"
TOOLS: Dict[str, Callable[[str], str]] = {
"binutils": binutils_url,
"compilers": compilers_url,
"dtk": dtk_url,
"objdiff-cli": objdiff_cli_url,
"sjiswrap": sjiswrap_url,
"wibo": wibo_url,
}
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("tool", help="Tool name")
parser.add_argument("output", type=Path, help="output file path")
parser.add_argument("--tag", help="GitHub tag", required=True)
args = parser.parse_args()
url = TOOLS[args.tool](args.tag)
output = Path(args.output)
print(f"Downloading {url} to {output}")
req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
with urllib.request.urlopen(req, context=ssl.create_default_context(cafile=certifi.where())) as response:
if url.endswith(".zip"):
data = io.BytesIO(response.read())
with zipfile.ZipFile(data) as f:
f.extractall(output)
# Make all files executable
for root, _, files in os.walk(output):
for name in files:
os.chmod(os.path.join(root, name), 0o755)
output.touch(mode=0o755) # Update dir modtime
else:
with open(output, "wb") as f:
shutil.copyfileobj(response, f)
st = os.stat(output)
os.chmod(output, st.st_mode | stat.S_IEXEC)
if __name__ == "__main__":
main()