2024-12-01 21:12:45 +01:00
|
|
|
|
#!/usr/bin/env -S godot -s
|
|
|
|
|
extends MainLoop
|
|
|
|
|
|
|
|
|
|
const GdUnitTools := preload("res://addons/gdUnit4/src/core/GdUnitTools.gd")
|
|
|
|
|
|
|
|
|
|
# gdlint: disable=max-line-length
|
2024-12-03 08:17:48 +01:00
|
|
|
|
const LOG_FRAME_TEMPLATE = """
|
2024-12-01 21:12:45 +01:00
|
|
|
|
<!DOCTYPE html>
|
2024-12-03 08:17:48 +01:00
|
|
|
|
<html style="display: inline-grid;">
|
2024-12-01 21:12:45 +01:00
|
|
|
|
<head>
|
2024-12-03 08:17:48 +01:00
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>Godot Logging</title>
|
|
|
|
|
<link rel="stylesheet" href="css/styles.css">
|
2024-12-01 21:12:45 +01:00
|
|
|
|
</head>
|
2024-12-03 08:17:48 +01:00
|
|
|
|
|
|
|
|
|
<body style="background-color: #eee;">
|
|
|
|
|
<div class="godot-report-frame"">
|
|
|
|
|
${content}
|
2024-12-01 21:12:45 +01:00
|
|
|
|
</div>
|
|
|
|
|
</body>
|
2024-12-03 08:17:48 +01:00
|
|
|
|
</html>
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
const NO_LOG_MESSAGE = """
|
|
|
|
|
<h3>No logging available!</h3>
|
|
|
|
|
</br>
|
|
|
|
|
<p>In order for logging to take place, you must activate the Activate file logging option in the project settings.</p>
|
|
|
|
|
<p>You can enable the logging under:
|
|
|
|
|
<b>Project Settings</b> > <b>Debug</b> > <b>File Logging</b> > <b>Enable File Logging</b> in the project settings.</p>
|
2024-12-01 21:12:45 +01:00
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
#warning-ignore-all:return_value_discarded
|
|
|
|
|
var _cmd_options := CmdOptions.new([
|
|
|
|
|
CmdOption.new(
|
|
|
|
|
"-rd, --report-directory",
|
|
|
|
|
"-rd <directory>",
|
|
|
|
|
"Specifies the output directory in which the reports are to be written. The default is res://reports/.",
|
|
|
|
|
TYPE_STRING,
|
|
|
|
|
true
|
|
|
|
|
)
|
|
|
|
|
])
|
|
|
|
|
|
2024-12-03 08:17:48 +01:00
|
|
|
|
|
2024-12-01 21:12:45 +01:00
|
|
|
|
var _report_root_path: String
|
2024-12-03 08:17:48 +01:00
|
|
|
|
var _current_report_path: String
|
|
|
|
|
var _debug_cmd_args := PackedStringArray()
|
2024-12-01 21:12:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _init() -> void:
|
2024-12-03 08:17:48 +01:00
|
|
|
|
set_report_directory(GdUnitFileAccess.current_dir() + "reports")
|
|
|
|
|
set_current_report_path()
|
2024-12-01 21:12:45 +01:00
|
|
|
|
|
|
|
|
|
|
2024-12-03 08:17:48 +01:00
|
|
|
|
func _process(_delta: float) -> bool:
|
2024-12-01 21:12:45 +01:00
|
|
|
|
# check if reports exists
|
|
|
|
|
if not reports_available():
|
|
|
|
|
prints("no reports found")
|
|
|
|
|
return true
|
2024-12-03 08:17:48 +01:00
|
|
|
|
|
2024-12-01 21:12:45 +01:00
|
|
|
|
# only process if godot logging is enabled
|
|
|
|
|
if not GdUnitSettings.is_log_enabled():
|
2024-12-03 08:17:48 +01:00
|
|
|
|
write_report(NO_LOG_MESSAGE, "")
|
2024-12-01 21:12:45 +01:00
|
|
|
|
return true
|
2024-12-03 08:17:48 +01:00
|
|
|
|
|
2024-12-01 21:12:45 +01:00
|
|
|
|
# parse possible custom report path,
|
|
|
|
|
var cmd_parser := CmdArgumentParser.new(_cmd_options, "GdUnitCmdTool.gd")
|
|
|
|
|
# ignore erros and exit quitly
|
2024-12-03 08:17:48 +01:00
|
|
|
|
if cmd_parser.parse(get_cmdline_args(), true).is_error():
|
2024-12-01 21:12:45 +01:00
|
|
|
|
return true
|
|
|
|
|
CmdCommandHandler.new(_cmd_options).register_cb("-rd", set_report_directory)
|
2024-12-03 08:17:48 +01:00
|
|
|
|
|
|
|
|
|
var godot_log_file := scan_latest_godot_log()
|
|
|
|
|
var result := read_log_file_content(godot_log_file)
|
2024-12-01 21:12:45 +01:00
|
|
|
|
if result.is_error():
|
2024-12-03 08:17:48 +01:00
|
|
|
|
write_report(result.error_message(), godot_log_file)
|
2024-12-01 21:12:45 +01:00
|
|
|
|
return true
|
2024-12-03 08:17:48 +01:00
|
|
|
|
write_report(result.value_as_string(), godot_log_file)
|
2024-12-01 21:12:45 +01:00
|
|
|
|
return true
|
|
|
|
|
|
|
|
|
|
|
2024-12-03 08:17:48 +01:00
|
|
|
|
func set_current_report_path() -> void:
|
|
|
|
|
# scan for latest report directory
|
|
|
|
|
var iteration := GdUnitFileAccess.find_last_path_index(
|
|
|
|
|
_report_root_path, GdUnitHtmlReport.REPORT_DIR_PREFIX
|
|
|
|
|
)
|
|
|
|
|
_current_report_path = "%s/%s%d" % [_report_root_path, GdUnitHtmlReport.REPORT_DIR_PREFIX, iteration]
|
|
|
|
|
|
|
|
|
|
|
2024-12-01 21:12:45 +01:00
|
|
|
|
func set_report_directory(path: String) -> void:
|
|
|
|
|
_report_root_path = path
|
|
|
|
|
|
|
|
|
|
|
2024-12-03 08:17:48 +01:00
|
|
|
|
func get_log_report_html() -> String:
|
|
|
|
|
return _current_report_path + "/godot_report_log.html"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func reports_available() -> bool:
|
|
|
|
|
return DirAccess.dir_exists_absolute(_report_root_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func scan_latest_godot_log() -> String:
|
2024-12-01 21:12:45 +01:00
|
|
|
|
var path := GdUnitSettings.get_log_path().get_base_dir()
|
|
|
|
|
var files_sorted := Array()
|
|
|
|
|
for file in GdUnitFileAccess.scan_dir(path):
|
|
|
|
|
var file_name := "%s/%s" % [path, file]
|
|
|
|
|
files_sorted.append(file_name)
|
|
|
|
|
# sort by name, the name contains the timestamp so we sort at the end by timestamp
|
|
|
|
|
files_sorted.sort()
|
2024-12-03 08:17:48 +01:00
|
|
|
|
return files_sorted.back()
|
2024-12-01 21:12:45 +01:00
|
|
|
|
|
|
|
|
|
|
2024-12-03 08:17:48 +01:00
|
|
|
|
func read_log_file_content(log_file: String) -> GdUnitResult:
|
|
|
|
|
var file := FileAccess.open(log_file, FileAccess.READ)
|
2024-12-01 21:12:45 +01:00
|
|
|
|
if file == null:
|
|
|
|
|
return GdUnitResult.error(
|
2024-12-03 08:17:48 +01:00
|
|
|
|
"Can't find log file '%s'. Error: %s"
|
|
|
|
|
% [log_file, error_string(FileAccess.get_open_error())]
|
2024-12-01 21:12:45 +01:00
|
|
|
|
)
|
2024-12-03 08:17:48 +01:00
|
|
|
|
var content := "<pre>" + file.get_as_text()
|
2024-12-01 21:12:45 +01:00
|
|
|
|
# patch out console format codes
|
|
|
|
|
for color_index in range(0, 256):
|
|
|
|
|
var to_replace := "[38;5;%dm" % color_index
|
|
|
|
|
content = content.replace(to_replace, "")
|
2024-12-03 08:17:48 +01:00
|
|
|
|
content += "</pre>"
|
2024-12-01 21:12:45 +01:00
|
|
|
|
content = content\
|
|
|
|
|
.replace("[0m", "")\
|
|
|
|
|
.replace(CmdConsole.CSI_BOLD, "")\
|
|
|
|
|
.replace(CmdConsole.CSI_ITALIC, "")\
|
|
|
|
|
.replace(CmdConsole.CSI_UNDERLINE, "")
|
2024-12-03 08:17:48 +01:00
|
|
|
|
return GdUnitResult.success(content)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func write_report(content: String, godot_log_file: String) -> GdUnitResult:
|
|
|
|
|
var file := FileAccess.open(get_log_report_html(), FileAccess.WRITE)
|
2024-12-01 21:12:45 +01:00
|
|
|
|
if file == null:
|
|
|
|
|
return GdUnitResult.error(
|
|
|
|
|
"Can't open to write '%s'. Error: %s"
|
2024-12-03 08:17:48 +01:00
|
|
|
|
% [get_log_report_html(), error_string(FileAccess.get_open_error())]
|
2024-12-01 21:12:45 +01:00
|
|
|
|
)
|
2024-12-03 08:17:48 +01:00
|
|
|
|
var report_html := LOG_FRAME_TEMPLATE.replace("${content}", content)
|
|
|
|
|
file.store_string(report_html)
|
|
|
|
|
_update_index_html(godot_log_file)
|
|
|
|
|
return GdUnitResult.success(file)
|
2024-12-01 21:12:45 +01:00
|
|
|
|
|
|
|
|
|
|
2024-12-03 08:17:48 +01:00
|
|
|
|
func _update_index_html(godot_log_file: String) -> void:
|
|
|
|
|
var index_file := FileAccess.open("%s/index.html" % _current_report_path, FileAccess.READ_WRITE)
|
|
|
|
|
if index_file == null:
|
|
|
|
|
push_error(
|
|
|
|
|
"Can't add log path to index.html. Error: %s"
|
|
|
|
|
% error_string(FileAccess.get_open_error())
|
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
var content := index_file.get_as_text()\
|
|
|
|
|
.replace("${log_report}", get_log_report_html())\
|
|
|
|
|
.replace("${godot_log_file}", godot_log_file)
|
|
|
|
|
# overide it
|
|
|
|
|
index_file.seek(0)
|
|
|
|
|
index_file.store_string(content)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func get_cmdline_args() -> PackedStringArray:
|
|
|
|
|
if _debug_cmd_args.is_empty():
|
|
|
|
|
return OS.get_cmdline_args()
|
|
|
|
|
return _debug_cmd_args
|