mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 20:20:30 +00:00
895bc7721a
This adds SPDX license headers to all source code files, following the REUSE[1] specification. This does not include any asset files (such as generated JSON files, or textures). While REUSE does support doing so with ".license" files, for now we define these licences using the .reuse/dep5 file. [1]: https://reuse.software/
154 lines
4.4 KiB
Python
Executable File
154 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
|
|
#
|
|
# SPDX-License-Identifier: MPL-2.0
|
|
|
|
"""
|
|
Parse reports generated by Gradle and convert them into GitHub annotations.
|
|
|
|
See https://github.com/actions/toolkit/blob/master/docs/problem-matchers.md and
|
|
https://github.com/actions/toolkit/blob/master/docs/commands.md.
|
|
"""
|
|
|
|
import os.path
|
|
import pathlib
|
|
import re
|
|
import xml.etree.ElementTree as ET
|
|
from typing import Optional, Tuple
|
|
|
|
LUA_ERROR_LOCATION = re.compile(r"^\s+(/[\w./-]+):(\d+):", re.MULTILINE)
|
|
JAVA_LUA_ERROR_LOCATION = re.compile(r"^java.lang.IllegalStateException: (/[\w./-]+):(\d+):")
|
|
JAVA_ERROR_LOCATION = re.compile(r"^\tat ([\w.]+)\.[\w]+\([\w.]+:(\d+)\)$", re.MULTILINE)
|
|
ERROR_MESSAGE = re.compile(r"(.*)\nstack traceback:", re.DOTALL)
|
|
|
|
SPACES = re.compile(r"\s+")
|
|
|
|
SOURCE_LOCATIONS = [
|
|
"src/main/java",
|
|
"src/main/resources/data/computercraft/lua",
|
|
"src/test/java",
|
|
"src/test/resources",
|
|
]
|
|
|
|
PROJECT_LOCATIONS = [
|
|
"projects/core-api",
|
|
"projects/core",
|
|
"projects/common-api",
|
|
"projects/common",
|
|
"projects/fabric-api",
|
|
"projects/fabric",
|
|
"projects/forge-api",
|
|
"projects/forge",
|
|
]
|
|
|
|
TEST_REPORTS = []
|
|
|
|
|
|
def find_file(path: str) -> Optional[str]:
|
|
while len(path) > 0 and path[0] == "/":
|
|
path = path[1:]
|
|
|
|
for project in PROJECT_LOCATIONS:
|
|
for source_dir in SOURCE_LOCATIONS:
|
|
child_path = os.path.join(project, source_dir, path)
|
|
if os.path.exists(child_path):
|
|
return child_path
|
|
|
|
return None
|
|
|
|
|
|
def find_location(message: str) -> Optional[Tuple[str, str]]:
|
|
location = LUA_ERROR_LOCATION.search(message)
|
|
if location:
|
|
file = find_file(location[1])
|
|
if file:
|
|
return file, location[2]
|
|
|
|
location = JAVA_LUA_ERROR_LOCATION.search(message)
|
|
if location:
|
|
file = find_file(location[1])
|
|
if file:
|
|
return file, location[2]
|
|
|
|
for location in JAVA_ERROR_LOCATION.findall(message):
|
|
file = find_file(location[0].replace(".", "/") + ".java")
|
|
if file:
|
|
return file, location[1]
|
|
|
|
return None
|
|
|
|
|
|
def _parse_junit_file(path: pathlib.Path):
|
|
for testcase in ET.parse(path).findall(".//testcase"):
|
|
for result in testcase:
|
|
if result.tag == "skipped":
|
|
continue
|
|
|
|
name = f'{testcase.attrib["classname"]}.{testcase.attrib["name"]}'
|
|
message = result.attrib.get("message")
|
|
full_message = result.text or message
|
|
|
|
location = find_location(full_message)
|
|
error = ERROR_MESSAGE.match(message)
|
|
if error:
|
|
error = error[1]
|
|
else:
|
|
error = message
|
|
|
|
if location:
|
|
print(f'## {location[0]}:{location[1]}: {name} failed: {SPACES.sub(" ", error)}')
|
|
else:
|
|
print(f"::error::{name} failed")
|
|
|
|
print("::group::Full error message")
|
|
print(full_message)
|
|
print("::endgroup::")
|
|
|
|
|
|
def parse_junit() -> None:
|
|
"""
|
|
Scrape JUnit test reports for errors. We determine the location from the Lua
|
|
or Java stacktrace.
|
|
"""
|
|
print("::add-matcher::.github/matchers/junit.json")
|
|
|
|
for project in PROJECT_LOCATIONS:
|
|
for path in pathlib.Path(os.path.join(project, "build/test-results/test")).glob("TEST-*.xml"):
|
|
_parse_junit_file(path)
|
|
|
|
for path in pathlib.Path(os.path.join(project, "build/test-results")).glob("run*.xml"):
|
|
_parse_junit_file(path)
|
|
|
|
print("::remove-matcher owner=junit::")
|
|
|
|
|
|
def _parse_checkstyle(path: pathlib.Path):
|
|
for file in ET.parse(path).getroot():
|
|
for error in file:
|
|
filename = os.path.relpath(file.attrib["name"])
|
|
|
|
attrib = error.attrib
|
|
print(
|
|
f'{attrib["severity"]} {filename}:{attrib["line"]}:{attrib.get("column", 1)}: {SPACES.sub(" ", attrib["message"])}'
|
|
)
|
|
|
|
|
|
def parse_checkstyle() -> None:
|
|
"""
|
|
Scrape JUnit test reports for errors. We determine the location from the Lua
|
|
or Java stacktrace.
|
|
"""
|
|
print("::add-matcher::.github/matchers/checkstyle.json")
|
|
|
|
for project in PROJECT_LOCATIONS:
|
|
for path in pathlib.Path(os.path.join(project, "build/reports/checkstyle/")).glob("*.xml"):
|
|
_parse_checkstyle(path)
|
|
|
|
print("::remove-matcher owner=checkstyle::")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parse_junit()
|
|
parse_checkstyle()
|