tools/mkdist.py: tester-distribution zip builder
Packages the player bats (zip root), BOTH exes (build\ pod fallback + build-glass\ preferred -- the bats auto-select glass = clickable cockpit / trigger config / bindings.txt keymap), the runtime DLLs next to each exe (OpenAL32.dll -- the first clean-extract boot test failed without it), and the git-TRACKED content/ files only (the working tree carries dev junk that must not ship). Output: dist/BT411-<date>-<hash>.zip (dist/ gitignored). Verified: clean-extract boot test -- glass exe boots the GLASS profile and simulates; pod exe boots as fallback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
3b17b60c19
commit
f7e674d9cb
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python3
|
||||
"""mkdist.py -- build the tester-distribution zip.
|
||||
|
||||
Layout (matches what the player bats expect):
|
||||
BT411-<date>-<hash>/
|
||||
play_solo.bat join.bat join_lan.bat (from players/)
|
||||
build/Release/btl4.exe (pod build -- fallback)
|
||||
build-glass/Release/btl4.exe (preferred: clickable cockpit)
|
||||
content/... (git-TRACKED files only --
|
||||
the working tree carries dev
|
||||
junk that must not ship)
|
||||
|
||||
The bats prefer build-glass when present and set BT_PLATFORM=glass with it,
|
||||
so testers boot the glass experience (PadRIO clicks, trigger config,
|
||||
bindings.txt keymap) with the pod build as fallback.
|
||||
|
||||
Usage: python tools/mkdist.py [outdir] (default outdir = dist/)
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import zipfile
|
||||
|
||||
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
def main():
|
||||
os.chdir(REPO)
|
||||
outdir = sys.argv[1] if len(sys.argv) > 1 else os.path.join(REPO, "dist")
|
||||
os.makedirs(outdir, exist_ok=True)
|
||||
|
||||
githash = subprocess.check_output(
|
||||
["git", "rev-parse", "--short", "HEAD"]).decode().strip()
|
||||
stamp = time.strftime("%Y-%m-%d")
|
||||
name = "BT411-%s-%s" % (stamp, githash)
|
||||
zpath = os.path.join(outdir, name + ".zip")
|
||||
|
||||
tracked = subprocess.check_output(
|
||||
["git", "ls-files", "-z", "content/"]).decode().split("\0")
|
||||
tracked = [t for t in tracked if t]
|
||||
|
||||
exes = ["build/Release/btl4.exe", "build-glass/Release/btl4.exe"]
|
||||
bats = ["players/play_solo.bat", "players/join.bat", "players/join_lan.bat"]
|
||||
for p in exes + bats:
|
||||
if not os.path.exists(p):
|
||||
sys.exit("MISSING: %s -- build/refresh it first" % p)
|
||||
|
||||
# Runtime DLLs living next to each exe (OpenAL32.dll etc.) -- the exe
|
||||
# fails to load without them (caught by the clean-extract boot test).
|
||||
for exe in list(exes):
|
||||
d = os.path.dirname(exe)
|
||||
for f in sorted(os.listdir(d)):
|
||||
if f.lower().endswith(".dll"):
|
||||
exes.append(d + "/" + f)
|
||||
|
||||
total = 0
|
||||
with zipfile.ZipFile(zpath, "w", zipfile.ZIP_DEFLATED, compresslevel=6) as z:
|
||||
for p in bats: # bats at the zip ROOT (next to
|
||||
arc = os.path.basename(p) # content\ + build\, per the guard)
|
||||
z.write(p, name + "/" + arc)
|
||||
total += os.path.getsize(p)
|
||||
for p in exes:
|
||||
z.write(p, name + "/" + p)
|
||||
total += os.path.getsize(p)
|
||||
for p in tracked:
|
||||
if not os.path.exists(p):
|
||||
print(" (skipping tracked-but-absent: %s)" % p)
|
||||
continue
|
||||
z.write(p, name + "/" + p)
|
||||
total += os.path.getsize(p)
|
||||
|
||||
zsz = os.path.getsize(zpath)
|
||||
print("wrote %s" % zpath)
|
||||
print(" %d files, %.1f MB raw -> %.1f MB zipped"
|
||||
% (len(bats) + len(exes) + len(tracked), total / 1048576.0,
|
||||
zsz / 1048576.0))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user