224 lines
6.9 KiB
GDScript
224 lines
6.9 KiB
GDScript
|
@tool
|
||
|
extends ConfirmationDialog
|
||
|
|
||
|
const GdUnitTools := preload("res://addons/gdUnit4/src/core/GdUnitTools.gd")
|
||
|
const GdUnitUpdateClient := preload("res://addons/gdUnit4/src/update/GdUnitUpdateClient.gd")
|
||
|
|
||
|
@onready var _progress_content :RichTextLabel = %message
|
||
|
@onready var _progress_bar :TextureProgressBar = %progress
|
||
|
|
||
|
|
||
|
var _debug_mode := false
|
||
|
var _update_client :GdUnitUpdateClient
|
||
|
var _download_url :String
|
||
|
|
||
|
|
||
|
func _ready() -> void:
|
||
|
message_h4("Press 'Update' to start!", Color.GREEN)
|
||
|
init_progress(5)
|
||
|
|
||
|
|
||
|
func _process(_delta :float) -> void:
|
||
|
if _progress_content != null and _progress_content.is_visible_in_tree():
|
||
|
_progress_content.queue_redraw()
|
||
|
|
||
|
|
||
|
func init_progress(max_value : int) -> void:
|
||
|
_progress_bar.max_value = max_value
|
||
|
_progress_bar.value = 1
|
||
|
|
||
|
|
||
|
func setup(update_client :GdUnitUpdateClient, download_url :String) -> void:
|
||
|
_update_client = update_client
|
||
|
_download_url = download_url
|
||
|
|
||
|
|
||
|
func update_progress(message :String) -> void:
|
||
|
message_h4(message, Color.GREEN)
|
||
|
_progress_bar.value += 1
|
||
|
if _debug_mode:
|
||
|
await get_tree().create_timer(3).timeout
|
||
|
await get_tree().create_timer(.2).timeout
|
||
|
|
||
|
|
||
|
func _colored(message :String, color :Color) -> String:
|
||
|
return "[color=#%s]%s[/color]" % [color.to_html(), message]
|
||
|
|
||
|
|
||
|
func message_h4(message :String, color :Color) -> void:
|
||
|
_progress_content.clear()
|
||
|
_progress_content.append_text("[font_size=16]%s[/font_size]" % _colored(message, color))
|
||
|
|
||
|
|
||
|
func run_update() -> void:
|
||
|
get_cancel_button().disabled = true
|
||
|
get_ok_button().disabled = true
|
||
|
|
||
|
await update_progress("Download Release ... [img=24x24]%s[/img]" % GdUnitUiTools.get_spinner())
|
||
|
await download_release()
|
||
|
await update_progress("Extract update ... [img=24x24]%s[/img]" % GdUnitUiTools.get_spinner())
|
||
|
var zip_file := temp_dir() + "/update.zip"
|
||
|
var tmp_path := create_temp_dir("update")
|
||
|
var result :Variant = extract_zip(zip_file, tmp_path)
|
||
|
if result == null:
|
||
|
await update_progress("Update failed!")
|
||
|
await get_tree().create_timer(3).timeout
|
||
|
queue_free()
|
||
|
return
|
||
|
|
||
|
await update_progress("Uninstall GdUnit4 ... [img=24x24]%s[/img]" % GdUnitUiTools.get_spinner())
|
||
|
disable_gdUnit()
|
||
|
if not _debug_mode:
|
||
|
delete_directory("res://addons/gdUnit4/")
|
||
|
# give editor time to react on deleted files
|
||
|
await get_tree().create_timer(1).timeout
|
||
|
|
||
|
await update_progress("Install new GdUnit4 version ...")
|
||
|
if _debug_mode:
|
||
|
copy_directory(tmp_path, "res://debug")
|
||
|
else:
|
||
|
copy_directory(tmp_path, "res://")
|
||
|
|
||
|
await update_progress("New GdUnit version successfully installed, Restarting Godot ...")
|
||
|
await get_tree().create_timer(3).timeout
|
||
|
enable_gdUnit()
|
||
|
hide()
|
||
|
delete_directory("res://addons/.gdunit_update")
|
||
|
restart_godot()
|
||
|
|
||
|
|
||
|
func restart_godot() -> void:
|
||
|
prints("Force restart Godot")
|
||
|
EditorInterface.restart_editor(true)
|
||
|
|
||
|
|
||
|
func enable_gdUnit() -> void:
|
||
|
var enabled_plugins := PackedStringArray()
|
||
|
if ProjectSettings.has_setting("editor_plugins/enabled"):
|
||
|
enabled_plugins = ProjectSettings.get_setting("editor_plugins/enabled")
|
||
|
if not enabled_plugins.has("res://addons/gdUnit4/plugin.cfg"):
|
||
|
enabled_plugins.append("res://addons/gdUnit4/plugin.cfg")
|
||
|
ProjectSettings.set_setting("editor_plugins/enabled", enabled_plugins)
|
||
|
ProjectSettings.save()
|
||
|
|
||
|
|
||
|
func disable_gdUnit() -> void:
|
||
|
EditorInterface.set_plugin_enabled("gdUnit4", false)
|
||
|
|
||
|
|
||
|
const GDUNIT_TEMP := "user://tmp"
|
||
|
|
||
|
func temp_dir() -> String:
|
||
|
if not DirAccess.dir_exists_absolute(GDUNIT_TEMP):
|
||
|
DirAccess.make_dir_recursive_absolute(GDUNIT_TEMP)
|
||
|
return GDUNIT_TEMP
|
||
|
|
||
|
|
||
|
func create_temp_dir(folder_name :String) -> String:
|
||
|
var new_folder := temp_dir() + "/" + folder_name
|
||
|
delete_directory(new_folder)
|
||
|
if not DirAccess.dir_exists_absolute(new_folder):
|
||
|
DirAccess.make_dir_recursive_absolute(new_folder)
|
||
|
return new_folder
|
||
|
|
||
|
|
||
|
func delete_directory(path :String, only_content := false) -> void:
|
||
|
var dir := DirAccess.open(path)
|
||
|
if dir != null:
|
||
|
dir.list_dir_begin()
|
||
|
var file_name := "."
|
||
|
while file_name != "":
|
||
|
file_name = dir.get_next()
|
||
|
if file_name.is_empty() or file_name == "." or file_name == "..":
|
||
|
continue
|
||
|
var next := path + "/" +file_name
|
||
|
if dir.current_is_dir():
|
||
|
delete_directory(next)
|
||
|
else:
|
||
|
# delete file
|
||
|
var err := dir.remove(next)
|
||
|
if err:
|
||
|
push_error("Delete %s failed: %s" % [next, error_string(err)])
|
||
|
if not only_content:
|
||
|
var err := dir.remove(path)
|
||
|
if err:
|
||
|
push_error("Delete %s failed: %s" % [path, error_string(err)])
|
||
|
|
||
|
|
||
|
func copy_directory(from_dir :String, to_dir :String) -> bool:
|
||
|
if not DirAccess.dir_exists_absolute(from_dir):
|
||
|
push_error("Source directory not found '%s'" % from_dir)
|
||
|
return false
|
||
|
# check if destination exists
|
||
|
if not DirAccess.dir_exists_absolute(to_dir):
|
||
|
# create it
|
||
|
var err := DirAccess.make_dir_recursive_absolute(to_dir)
|
||
|
if err != OK:
|
||
|
push_error("Can't create directory '%s'. Error: %s" % [to_dir, error_string(err)])
|
||
|
return false
|
||
|
var source_dir := DirAccess.open(from_dir)
|
||
|
var dest_dir := DirAccess.open(to_dir)
|
||
|
if source_dir != null:
|
||
|
source_dir.list_dir_begin()
|
||
|
var next := "."
|
||
|
|
||
|
while next != "":
|
||
|
next = source_dir.get_next()
|
||
|
if next == "" or next == "." or next == "..":
|
||
|
continue
|
||
|
var source := source_dir.get_current_dir() + "/" + next
|
||
|
var dest := dest_dir.get_current_dir() + "/" + next
|
||
|
if source_dir.current_is_dir():
|
||
|
copy_directory(source + "/", dest)
|
||
|
continue
|
||
|
var err := source_dir.copy(source, dest)
|
||
|
if err != OK:
|
||
|
push_error("Error checked copy file '%s' to '%s'" % [source, dest])
|
||
|
return false
|
||
|
return true
|
||
|
else:
|
||
|
push_error("Directory not found: " + from_dir)
|
||
|
return false
|
||
|
|
||
|
|
||
|
func extract_zip(zip_package :String, dest_path :String) -> Variant:
|
||
|
var zip: ZIPReader = ZIPReader.new()
|
||
|
var err := zip.open(zip_package)
|
||
|
if err != OK:
|
||
|
push_error("Extracting `%s` failed! Please collect the error log and report this. Error Code: %s" % [zip_package, err])
|
||
|
return null
|
||
|
var zip_entries: PackedStringArray = zip.get_files()
|
||
|
# Get base path and step over archive folder
|
||
|
var archive_path := zip_entries[0]
|
||
|
zip_entries.remove_at(0)
|
||
|
|
||
|
for zip_entry in zip_entries:
|
||
|
var new_file_path: String = dest_path + "/" + zip_entry.replace(archive_path, "")
|
||
|
if zip_entry.ends_with("/"):
|
||
|
DirAccess.make_dir_recursive_absolute(new_file_path)
|
||
|
continue
|
||
|
var file: FileAccess = FileAccess.open(new_file_path, FileAccess.WRITE)
|
||
|
file.store_buffer(zip.read_file(zip_entry))
|
||
|
zip.close()
|
||
|
return dest_path
|
||
|
|
||
|
|
||
|
func download_release() -> void:
|
||
|
var zip_file := GdUnitFileAccess.temp_dir() + "/update.zip"
|
||
|
var response :GdUnitUpdateClient.HttpResponse
|
||
|
if _debug_mode:
|
||
|
response = GdUnitUpdateClient.HttpResponse.new(200, PackedByteArray())
|
||
|
zip_file = "res://update.zip"
|
||
|
else:
|
||
|
response = await _update_client.request_zip_package(_download_url, zip_file)
|
||
|
_update_client.queue_free()
|
||
|
if response.code() != 200:
|
||
|
push_warning("Update information cannot be retrieved from GitHub! \n Error code: %d : %s" % [response.code(), response.response()])
|
||
|
message_h4("Update failed! Try it later again.", Color.RED)
|
||
|
await get_tree().create_timer(3).timeout
|
||
|
return
|
||
|
|
||
|
|
||
|
func _on_confirmed() -> void:
|
||
|
await run_update()
|