81 lines
2.7 KiB
Python
81 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
import argparse
|
|
import hashlib
|
|
import re
|
|
import sys
|
|
import urllib.request
|
|
from pathlib import Path
|
|
|
|
REDIST_URL = "https://aka.ms/vs/17/release/vc_redist.x64.exe"
|
|
BEGIN = "; >>> VC_REDIST_INSTALL >>>"
|
|
END = "; <<< VC_REDIST_INSTALL <<<"
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
DEFAULT_CARGO_TOML = REPO_ROOT / "packages" / "oneclient_app" / "Cargo.toml"
|
|
DEFAULT_REDIST = REPO_ROOT / "target" / "vcredist" / "vc_redist.x64.exe"
|
|
|
|
BLOCK = """ {begin}
|
|
; Generated by distribution/windows/bundle-vcredist.py -- do not edit by hand.
|
|
DetailPrint "Installing Microsoft Visual C++ Redistributable (x64)..."
|
|
InitPluginsDir
|
|
File "/oname=$PLUGINSDIR\\\\vc_redist.x64.exe" "{redist}"
|
|
ExecWait '"$PLUGINSDIR\\\\vc_redist.x64.exe" /quiet /norestart' $R3
|
|
${{If}} $R3 == 3010
|
|
SetRebootFlag true
|
|
${{EndIf}}
|
|
{end}"""
|
|
|
|
REGION = re.compile(
|
|
r"^[ \t]*" + re.escape(BEGIN) + r".*?^[ \t]*" + re.escape(END) + r"[ \t]*$",
|
|
re.DOTALL | re.MULTILINE,
|
|
)
|
|
|
|
|
|
def download(dest: Path) -> None:
|
|
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
print(f"downloading {REDIST_URL} -> {dest}")
|
|
with urllib.request.urlopen(REDIST_URL) as resp, dest.open("wb") as out:
|
|
while chunk := resp.read(1 << 20):
|
|
out.write(chunk)
|
|
|
|
data = dest.read_bytes()
|
|
if data[:2] != b"MZ":
|
|
sys.exit(f"error: {dest} is not a PE image (no MZ header)")
|
|
if len(data) < 10 * 1024 * 1024:
|
|
sys.exit(f"error: {dest} is only {len(data)} bytes, expected >10MB")
|
|
print(f" {len(data)} bytes, sha256={hashlib.sha256(data).hexdigest()}")
|
|
|
|
|
|
def patch(cargo_toml: Path, redist: Path) -> None:
|
|
text = cargo_toml.read_text(encoding="utf-8")
|
|
if not REGION.search(text):
|
|
sys.exit(f"error: {BEGIN} .. {END} region not found in {cargo_toml}")
|
|
|
|
block = BLOCK.format(begin=BEGIN, end=END, redist=str(redist).replace("\\", "\\\\"))
|
|
cargo_toml.write_text(REGION.sub(lambda _: block, text, count=1), encoding="utf-8")
|
|
print(f"patched {cargo_toml} to embed {redist}")
|
|
|
|
|
|
def main() -> None:
|
|
ap = argparse.ArgumentParser(description=__doc__)
|
|
ap.add_argument("--cargo-toml", type=Path, default=DEFAULT_CARGO_TOML)
|
|
ap.add_argument("--redist", type=Path, default=DEFAULT_REDIST)
|
|
ap.add_argument(
|
|
"--skip-download",
|
|
action="store_true",
|
|
help="reuse an already-downloaded --redist instead of fetching it",
|
|
)
|
|
args = ap.parse_args()
|
|
|
|
redist = args.redist.resolve()
|
|
if args.skip_download:
|
|
if not redist.is_file():
|
|
sys.exit(f"error: --skip-download given but {redist} does not exist")
|
|
else:
|
|
download(redist)
|
|
|
|
patch(args.cargo_toml.resolve(), redist)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|