two-torial-sp2xpatcher/checks.py
2024-07-11 13:48:15 +02:00

146 lines
5.4 KiB
Python

import os
import re
import json
import subprocess
import sys
from datetime import datetime, timezone
from copy import deepcopy
# Regular expression pattern to match the lines in SUPPORTED.md
regex = re.compile(r"\| ([^|]*) \| ([^|]*) \| ([^|]*) \| \[.*?\]\((.*?)\) \|")
# Get a list of files for a given git command
def git_files(command):
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
files = result.stdout.decode('utf-8').splitlines()
return [file for file in files if file.endswith('.json')]
# Get a list of changes json files using git
def get_changed_jsons():
commands = [
['git', 'diff', '--name-only'], # changed files
['git', 'diff', '--cached', '--name-only'], # staged files
['git', 'log', 'origin/main..HEAD', '--name-only', '--pretty=format:'] # comitted files
]
changed_files = set()
for command in commands:
changed_files.update(git_files(command))
return list(changed_files)
# Update header for a given json file
def update_header(json_path, date_code):
try:
with open(json_path, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
if isinstance(data, list) and data:
if "name" not in data[0]:
data.pop(0)
if data:
first_entry = data[0]
game_code = first_entry.get("gameCode", "")
last_updated = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
new_entry = {
"gameCode": game_code,
"version": date_code,
"lastUpdated": last_updated,
"source": 'https://sp2x.two-torial.xyz/',
}
data.insert(0, new_entry)
for entry in data[1:]:
entry.pop("dateCode", None)
with open(json_path, "w", encoding="utf-8") as json_file:
json.dump(data, json_file, indent=4, ensure_ascii=False)
print(f"'{os.path.relpath(json_path, 'patches/')}' - Updated header")
except Exception as e:
exit(e)
# Cleanup all json files by batch-running jobs
def clean_json_files():
json_files = []
for filename in os.listdir("patches/"):
if filename.endswith('.json'):
filepath = os.path.join("patches/", filename)
with open(filepath, "r", encoding="utf-8") as json_file:
json_data = json.load(json_file)
# Remove redundance union entries
new_json_data = deepcopy(json_data)
for item in new_json_data:
if "type" in item:
if item["type"] == "union":
for patch in item["patches"]:
if "type" in patch:
del patch["type"]
if json_data != new_json_data:
# Only save changes and print if something was done
with open(filepath, "w", encoding="utf-8") as json_file:
json.dump(new_json_data, json_file, indent=4)
print(f"'{filename}' - Cleaned up")
json_files.append(filepath)
return json_files
# Run checks for json_files if specified, otherwise all changes files
def check(json_files=None):
# if json_files is none: run clean_json_files and set json_files to its return value
json_files = json_files or clean_json_files()
# if there are still no json files, get changed jsons instead
if not json_files:
json_files = get_changed_jsons()
# exit if there's no changed files
if not json_files:
exit("Nothing to do")
count = 0
try:
# Open SUPPORTED.md
with open("SUPPORTED.md", "r", encoding="utf-8") as file:
# For each line
for line in file:
match = regex.search(line)
# If it matches a game info line
if match:
# Get the last group of the regex (json path)
json_path = match.group(4).strip()
# For each path in json_files check if it matches the current line's json path
if any(j_path in json_path for j_path in json_files):
# if that's the case update its header and add 1 to count
variant = match.group(1).strip()
date_code = match.group(3).strip()
# Add variant (ex 010) to datecode if present, otherwise keep datecode as is
if "-" in variant:
date_code = f"{date_code} ({variant.split('-')[1]})"
update_header(json_path, date_code)
count += 1
# If nothing was done, exit early
if count == 0:
exit("Nothing to do")
return count
except Exception as e:
exit(f"Error processing files: {e}")
if __name__ == "__main__":
if not os.path.exists('./SUPPORTED.md'):
exit("File 'SUPPORTED.md' not found")
if not os.path.exists('patches/'):
exit("Folder 'patches' not found")
len_args = len(sys.argv)
if len_args == 1:
count = check()
elif len_args == 2:
filepath = sys.argv[1]
if not os.path.exists(filepath):
exit(f"Invalid path '{filepath}'")
count = check([filepath])
else:
exit("Usage: python checks.py <(optional)json_name>")
print(f"\nUpdated {count} file(s)")