diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8134a7b90f0..ea5caef5a32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,6 +35,7 @@ jobs: python tools/ci/check_line_endings.py python tools/ci/check_file_names.py python tools/ci/unticked_files.py ${GITHUB_WORKSPACE} + python tools/ci/illegal_dme_files.py ${GITHUB_WORKSPACE} python -m tools.maplint.source --github ~/dreamchecker > ${GITHUB_WORKSPACE}/output-annotations.txt 2>&1 - name: Annotate Lints diff --git a/tools/ci/illegal_dme_files.py b/tools/ci/illegal_dme_files.py new file mode 100644 index 00000000000..bbc9ac67291 --- /dev/null +++ b/tools/ci/illegal_dme_files.py @@ -0,0 +1,51 @@ +# Naive search for illegal files. Has no semantic knowledge, just a lexical +# search for specific endings in a .dme +# +# Illegal files are files that are allowed in the .dme by byond's standards, +# but will cause actual issues on runtime. For example, dmm files are illegal +# because they will mess with the map rotation system and z-levels in unexpected ways +# +# This is basically a slightly edited verison of unticked_files.py. +# Look there for precise documentation on the methods used here. +from pathlib import Path, PureWindowsPath +import argparse +import sys + +INCLUDED_FILES = [ + 'paradise.dme' +] + +ILLEGAL_FILES = ( # Use a tuple here + '.dmm', +) + +def get_illegal_files(root: Path): + illegal_file_count = 0 + for includer in INCLUDED_FILES: + illegal_files = set() + with open(root / includer, 'r') as f: + # I've tried to optimize this, but this was the best I could get. Try placing the strips elsewhere if you dare + lines = [line for line in f.readlines() if line.rstrip('\r\n').strip('"').endswith(ILLEGAL_FILES)] + included = [line.replace('#include ', '').rstrip('\r\n').strip('"') for line in lines] + illegal_files.update([root / Path(includer).parent / Path(PureWindowsPath(i)) for i in included]) + + if len(illegal_files) >= 1: + illegal_file_count += len(illegal_files) + print(f'Found {len(illegal_files)} illegal files in {root / includer}:') + print('\n'.join(str(x) for x in sorted(illegal_files)), '\n') + + return illegal_file_count + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("root", help="project root directory") + args = parser.parse_args() + + # Windows quoting behavior for directories adds trailing double-quote + illegal_files = get_illegal_files(Path(args.root.strip('"'))) + if illegal_files: + print(f'Found {illegal_files} total illegal files.') + print('Illegal files are not allowed to be included in dme files.') + sys.exit(1) + else: + print('Found no illegal includes in main .dme.')