From 57ace11114c5f1b06679aab8c2652b3d12f3ac28 Mon Sep 17 00:00:00 2001 From: phobos665 Date: Fri, 10 Apr 2026 15:13:18 +0100 Subject: [PATCH] fix(): convert to py scripts --- .github/workflows/update-fexcore.yml | 88 ++------------------- tools/check-latest-fexcore.py | 112 +++++++++++++++++++++++++++ tools/update-arrays-xml.py | 46 +++++++++++ 3 files changed, 163 insertions(+), 83 deletions(-) create mode 100644 tools/check-latest-fexcore.py create mode 100644 tools/update-arrays-xml.py diff --git a/.github/workflows/update-fexcore.yml b/.github/workflows/update-fexcore.yml index f10b7c8f3a..71dcfc3686 100644 --- a/.github/workflows/update-fexcore.yml +++ b/.github/workflows/update-fexcore.yml @@ -22,57 +22,8 @@ jobs: - name: Find latest FEXCore .wcp id: check env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Fetch the file listing from the upstream repo via the GitHub API. - # Authenticate to avoid anonymous rate-limit (60 req/hr). - RESPONSE=$(curl -sf \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: Bearer $GH_TOKEN" \ - "https://api.github.com/repos/StevenMXZ/Winlator-Contents/contents/FEXCore") - - # Pick the file with the highest YYMM version. - # Only considers files whose names start with 4 digits (e.g. 2604.wcp, 2508.1.wcp). - LATEST=$(echo "$RESPONSE" | python3 - <<'EOF' -import sys, json, re - -data = json.loads(sys.stdin.read()) -files = [f["name"] for f in data if f["type"] == "file" and f["name"].endswith(".wcp")] - -best = None -best_ver = (-1, -1) -for name in files: - m = re.match(r'^(\d{4})(?:\.(\d+))?\.wcp$', name) - if m: - ver = (int(m.group(1)), int(m.group(2) or 0)) - if ver > best_ver: - best_ver = ver - best = name - -print(best or "") -EOF -) - - if [[ -z "$LATEST" ]]; then - echo "Could not determine latest .wcp file." >&2 - exit 1 - fi - - # Extract the YYMM version (first four digits) for the output filename. - VERSION=$(echo "$LATEST" | grep -oP '^\d{4}') - TZST_PATH="app/src/main/assets/fexcore/fexcore-${VERSION}.tzst" - - echo "LATEST_FILE=$LATEST" >> "$GITHUB_OUTPUT" - echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT" - echo "TZST_PATH=$TZST_PATH" >> "$GITHUB_OUTPUT" - - if [[ -f "$TZST_PATH" ]]; then - echo "ALREADY_EXISTS=true" >> "$GITHUB_OUTPUT" - echo "fexcore-${VERSION}.tzst already present — nothing to do." - else - echo "ALREADY_EXISTS=false" >> "$GITHUB_OUTPUT" - echo "New release found: $LATEST → $TZST_PATH" - fi + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: python3 tools/check-latest-fexcore.py - name: Download ${{ steps.check.outputs.LATEST_FILE }} if: steps.check.outputs.ALREADY_EXISTS == 'false' @@ -89,38 +40,9 @@ EOF - name: Update arrays.xml if: steps.check.outputs.ALREADY_EXISTS == 'false' run: | - VERSION="${{ steps.check.outputs.VERSION }}" - ARRAYS_XML="app/src/main/res/values/arrays.xml" - - # Check if this version is already listed in arrays.xml. - if grep -qF "${VERSION}" "$ARRAYS_XML"; then - echo "Version $VERSION already present in arrays.xml — skipping XML update." - else - # Insert the new version as the last of fexcore_version_entries. - # We find the closing that follows the fexcore_version_entries - # block and insert directly before it. - python3 - "$ARRAYS_XML" "$VERSION" <<'PYEOF' - import sys, re - - path, version = sys.argv[1], sys.argv[2] - with open(path, "r", encoding="utf-8") as f: - content = f.read() - - # Find the fexcore_version_entries block and append the new item before its closing tag. - pattern = r'(name="fexcore_version_entries".*?)()' - replacement = r'\g<1> ' + version + r'\n \g<2>' - new_content, count = re.subn(pattern, replacement, content, count=1, flags=re.DOTALL) - - if count == 0: - print("ERROR: fexcore_version_entries array not found in arrays.xml", file=sys.stderr) - sys.exit(1) - - with open(path, "w", encoding="utf-8") as f: - f.write(new_content) - - print(f"Appended {version} to fexcore_version_entries.") - PYEOF - fi + python3 tools/update-arrays-xml.py \ + app/src/main/res/values/arrays.xml \ + "${{ steps.check.outputs.VERSION }}" - name: Create PR branch, commit, and open PR if: steps.check.outputs.ALREADY_EXISTS == 'false' diff --git a/tools/check-latest-fexcore.py b/tools/check-latest-fexcore.py new file mode 100644 index 0000000000..ced25a63f7 --- /dev/null +++ b/tools/check-latest-fexcore.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +""" +check-latest-fexcore.py +Queries the StevenMXZ/Winlator-Contents FEXCore directory and prints the +latest .wcp filename (by YYMM version number). + +Usage: + python3 tools/check-latest-fexcore.py [--token ] + +A token is optional but recommended to avoid the 60 req/hr anonymous rate limit. +It can also be supplied via the GITHUB_TOKEN environment variable. +""" + +import argparse +import json +import os +import re +import subprocess +import sys + +API_URL = "https://api.github.com/repos/StevenMXZ/Winlator-Contents/contents/FEXCore" + + +def fetch_listing(token: str | None) -> list[dict]: + cmd = [ + "curl", "-sf", + "-H", "Accept: application/vnd.github.v3+json", + ] + if token: + cmd += ["-H", f"Authorization: Bearer {token}"] + cmd.append(API_URL) + + result = subprocess.run(cmd, capture_output=True, text=True) + if result.returncode != 0: + print(f"curl error: {result.stderr.strip()}", file=sys.stderr) + sys.exit(1) + return json.loads(result.stdout) + + +def pick_latest(entries: list[dict]) -> tuple[str | None, tuple[int, int]]: + best_name = None + best_ver: tuple[int, int] = (-1, -1) + for entry in entries: + if entry.get("type") != "file": + continue + name = entry["name"] + if not name.endswith(".wcp"): + continue + m = re.match(r"^(\d{4})(?:\.(\d+))?\.wcp$", name) + if m: + ver = (int(m.group(1)), int(m.group(2) or 0)) + if ver > best_ver: + best_ver = ver + best_name = name + return best_name, best_ver + + +def main() -> None: + parser = argparse.ArgumentParser(description="Find the latest FEXCore .wcp release.") + parser.add_argument("--token", default=os.environ.get("GITHUB_TOKEN"), help="GitHub token (or set GITHUB_TOKEN)") + parser.add_argument( + "--gha-output", + metavar="FILE", + default=os.environ.get("GITHUB_OUTPUT"), + help="Append key=value pairs to this file (GitHub Actions $GITHUB_OUTPUT). " + "Automatically set when GITHUB_OUTPUT env var is present.", + ) + args = parser.parse_args() + + if not args.gha_output: + # Human-readable mode + print(f"Querying {API_URL} ...") + + entries = fetch_listing(args.token) + + all_wcp = [e["name"] for e in entries if e.get("type") == "file" and e["name"].endswith(".wcp")] + + latest, ver = pick_latest(entries) + if not latest: + print("ERROR: Could not determine latest versioned .wcp file.", file=sys.stderr) + sys.exit(1) + + version = latest[:4] # first four digits = YYMM + tzst_path = f"app/src/main/assets/fexcore/fexcore-{version}.tzst" + download_url = f"https://raw.githubusercontent.com/StevenMXZ/Winlator-Contents/main/FEXCore/{latest}" + already_exists = os.path.isfile(tzst_path) + + if args.gha_output: + # GitHub Actions mode: write outputs, print minimal log to stdout + with open(args.gha_output, "a", encoding="utf-8") as f: + f.write(f"LATEST_FILE={latest}\n") + f.write(f"VERSION={version}\n") + f.write(f"TZST_PATH={tzst_path}\n") + f.write(f"ALREADY_EXISTS={'true' if already_exists else 'false'}\n") + if already_exists: + print(f"fexcore-{version}.tzst already present — nothing to do.") + else: + print(f"New release found: {latest} → {tzst_path}") + else: + # Human-readable mode + print(f"\nAll .wcp files found ({len(all_wcp)}):") + for name in sorted(all_wcp): + print(f" {name}") + print(f"\nLatest : {latest} (parsed version {ver[0]}.{ver[1]})") + print(f"VERSION: {version}") + print(f"Output : {tzst_path}") + print(f"Already exists: {already_exists}") + print(f"Download URL: {download_url}") + + +if __name__ == "__main__": + main() diff --git a/tools/update-arrays-xml.py b/tools/update-arrays-xml.py new file mode 100644 index 0000000000..5454fa4c5e --- /dev/null +++ b/tools/update-arrays-xml.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +""" +update-arrays-xml.py +Appends a new version entry to the fexcore_version_entries array in arrays.xml. + +Usage: + python3 tools/update-arrays-xml.py + e.g. python3 tools/update-arrays-xml.py app/src/main/res/values/arrays.xml 2604 +""" + +import re +import sys + + +def main() -> None: + if len(sys.argv) != 3: + print(f"Usage: {sys.argv[0]} ", file=sys.stderr) + sys.exit(1) + + path, version = sys.argv[1], sys.argv[2] + + with open(path, "r", encoding="utf-8") as f: + content = f.read() + + # Idempotency check + if f"{version}" in content: + print(f"Version {version} already present in arrays.xml — nothing to do.") + sys.exit(0) + + # Find the fexcore_version_entries block and append the new item before its closing tag. + pattern = r'(name="fexcore_version_entries".*?)()' + replacement = r'\g<1> ' + version + r'\n \g<2>' + new_content, count = re.subn(pattern, replacement, content, count=1, flags=re.DOTALL) + + if count == 0: + print("ERROR: fexcore_version_entries array not found in arrays.xml", file=sys.stderr) + sys.exit(1) + + with open(path, "w", encoding="utf-8") as f: + f.write(new_content) + + print(f"Appended {version} to fexcore_version_entries.") + + +if __name__ == "__main__": + main()