mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
122 lines
4.5 KiB
Python
122 lines
4.5 KiB
Python
import os
|
|
import sys
|
|
import pygit2
|
|
|
|
from tools.mapmerge2 import frontend
|
|
from .dmm import *
|
|
from .mapmerge import merge_map
|
|
|
|
def green(text):
|
|
return "\033[32m" + str(text) + "\033[0m"
|
|
|
|
def red(text):
|
|
return "\033[31m" + str(text) + "\033[0m"
|
|
|
|
def has_tgm_header(fname):
|
|
with open(fname, 'r', encoding=ENCODING) as f:
|
|
data = f.read(len(TGM_HEADER))
|
|
return data.startswith(TGM_HEADER)
|
|
|
|
class LintException(Exception):
|
|
pass
|
|
|
|
def _self_test():
|
|
repo = pygit2.Repository(pygit2.discover_repository(os.getcwd()))
|
|
|
|
# Read the HEAD and ancestor commits
|
|
# Assumption: origin on the runner is what we'd normally call upstream
|
|
head = repo.head.target
|
|
initial_head_commit = repo[head]
|
|
upstream = repo.revparse_single("refs/remotes/origin/master").id
|
|
ancestor = repo.merge_base(head, upstream)
|
|
ancestor_commit = None
|
|
if len(initial_head_commit.parent_ids) != 1: # if HEAD is a merge commit:
|
|
for parent in initial_head_commit.parent_ids:
|
|
if parent == upstream:
|
|
continue
|
|
head = parent
|
|
ancestor = repo.merge_base(head, upstream)
|
|
|
|
if not ancestor:
|
|
print("Unable to determine merge base!")
|
|
else:
|
|
ancestor_commit = repo[ancestor]
|
|
print("Determined ancestor commit SHA to be:", ancestor)
|
|
|
|
# Figure out what maps have been modified
|
|
modified_maps = []
|
|
diff = repo.diff(head, ancestor)
|
|
for delta in diff.deltas:
|
|
cur_path = delta.new_file.path
|
|
if cur_path.endswith('.dmm'):
|
|
modified_maps.append(cur_path)
|
|
|
|
# Actually perform the testing
|
|
count = 0
|
|
failed = 0
|
|
for dirpath, dirnames, filenames in os.walk(frontend.read_settings().map_folder):
|
|
if '.git' in dirnames:
|
|
dirnames.remove('.git')
|
|
for filename in filenames:
|
|
if filename.endswith('.dmm'):
|
|
fullpath = os.path.join(dirpath, filename)
|
|
path = fullpath.replace("\\", "/").removeprefix("./")
|
|
try:
|
|
# test: can we load every DMM
|
|
index_data = DMM.from_file_bytes(fullpath)
|
|
index_map = DMM.from_bytes(index_data)
|
|
|
|
# test: is every DMM in TGM format
|
|
if not has_tgm_header(fullpath):
|
|
raise LintException('Map is not in TGM format! Please run `/tools/mapmerge2/I Forgot To Map Merge.bat`')
|
|
|
|
# test: does every DMM convert cleanly
|
|
if ancestor_commit and (path in modified_maps):
|
|
try:
|
|
ancestor_blob = ancestor_commit.tree[path]
|
|
except KeyError:
|
|
# New map, no entry in ancestor
|
|
print("New map? Could not find ancestor version of", path)
|
|
merged_map = merge_map(index_map, index_map) # basically only tests unused keys
|
|
merged_bytes = merged_map.to_bytes()
|
|
if index_data != merged_bytes:
|
|
raise LintException('New map is pending updates! Please run `/tools/mapmerge2/I Forgot To Map Merge.bat`')
|
|
else:
|
|
# Entry in ancestor, merge the index over it
|
|
ancestor_map = DMM.from_bytes(ancestor_blob.read_raw())
|
|
merged_map = merge_map(index_map, ancestor_map)
|
|
merged_bytes = merged_map.to_bytes()
|
|
if index_data != merged_bytes:
|
|
raise LintException('Map is pending updates! Please run `/tools/mapmerge2/I Forgot To Map Merge.bat`')
|
|
except LintException as error:
|
|
failed += 1
|
|
print(red(f'Failed on: {path}'))
|
|
print(error)
|
|
except Exception:
|
|
failed += 1
|
|
print(red(f'Failed on: {path}'))
|
|
raise
|
|
count += 1
|
|
|
|
print(f"{os.path.relpath(__file__)}: {green(f'successfully parsed {count-failed} .dmm files ({len(modified_maps)} modified)')}")
|
|
if failed > 0:
|
|
print(f"{os.path.relpath(__file__)}: {red(f'failed to parse {failed} .dmm files')}")
|
|
exit(1)
|
|
|
|
|
|
def _usage():
|
|
print(f"Usage:")
|
|
print(f" tools{os.sep}bootstrap{os.sep}python -m {__spec__.name}")
|
|
exit(1)
|
|
|
|
|
|
def _main():
|
|
if len(sys.argv) == 1:
|
|
return _self_test()
|
|
|
|
return _usage()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
_main()
|