#!/usr/bin/env -S godot -s extends MainLoop const GdUnitTools := preload("res://addons/gdUnit4/src/core/GdUnitTools.gd") # gdlint: disable=max-line-length const LOG_FRAME_TEMPLATE = """ Godot Logging
${content}
""" const NO_LOG_MESSAGE = """

No logging available!


In order for logging to take place, you must activate the Activate file logging option in the project settings.

You can enable the logging under: Project Settings > Debug > File Logging > Enable File Logging in the project settings.

""" #warning-ignore-all:return_value_discarded var _cmd_options := CmdOptions.new([ CmdOption.new( "-rd, --report-directory", "-rd ", "Specifies the output directory in which the reports are to be written. The default is res://reports/.", TYPE_STRING, true ) ]) var _report_root_path: String var _current_report_path: String var _debug_cmd_args := PackedStringArray() func _init() -> void: set_report_directory(GdUnitFileAccess.current_dir() + "reports") set_current_report_path() func _process(_delta: float) -> bool: # check if reports exists if not reports_available(): prints("no reports found") return true # only process if godot logging is enabled if not GdUnitSettings.is_log_enabled(): write_report(NO_LOG_MESSAGE, "") return true # parse possible custom report path, var cmd_parser := CmdArgumentParser.new(_cmd_options, "GdUnitCmdTool.gd") # ignore erros and exit quitly if cmd_parser.parse(get_cmdline_args(), true).is_error(): return true CmdCommandHandler.new(_cmd_options).register_cb("-rd", set_report_directory) var godot_log_file := scan_latest_godot_log() var result := read_log_file_content(godot_log_file) if result.is_error(): write_report(result.error_message(), godot_log_file) return true write_report(result.value_as_string(), godot_log_file) return true 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] func set_report_directory(path: String) -> void: _report_root_path = path 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: 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() return files_sorted.back() func read_log_file_content(log_file: String) -> GdUnitResult: var file := FileAccess.open(log_file, FileAccess.READ) if file == null: return GdUnitResult.error( "Can't find log file '%s'. Error: %s" % [log_file, error_string(FileAccess.get_open_error())] ) var content := "
" + file.get_as_text()
	# 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, "")
	content += "
" content = content\ .replace("", "")\ .replace(CmdConsole.CSI_BOLD, "")\ .replace(CmdConsole.CSI_ITALIC, "")\ .replace(CmdConsole.CSI_UNDERLINE, "") return GdUnitResult.success(content) func write_report(content: String, godot_log_file: String) -> GdUnitResult: var file := FileAccess.open(get_log_report_html(), FileAccess.WRITE) if file == null: return GdUnitResult.error( "Can't open to write '%s'. Error: %s" % [get_log_report_html(), error_string(FileAccess.get_open_error())] ) var report_html := LOG_FRAME_TEMPLATE.replace("${content}", content) file.store_string(report_html) _update_index_html(godot_log_file) return GdUnitResult.success(file) 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