mirror of
https://github.com/git-learning-game/oh-my-git.git
synced 2024-11-24 16:20:08 +01:00
Move exec, crash, and file IO to "helpers" autoload node
This commit is contained in:
parent
685af0ede6
commit
44214d2fdf
8 changed files with 77 additions and 74 deletions
54
game.gd
54
game.gd
|
@ -2,7 +2,6 @@ extends Node
|
||||||
|
|
||||||
var tmp_prefix = _tmp_prefix()
|
var tmp_prefix = _tmp_prefix()
|
||||||
var global_shell
|
var global_shell
|
||||||
var debug_file_io = false
|
|
||||||
var fake_editor
|
var fake_editor
|
||||||
|
|
||||||
var _file = "user://savegame.json"
|
var _file = "user://savegame.json"
|
||||||
|
@ -39,40 +38,15 @@ func load_state() -> bool:
|
||||||
savegame.close()
|
savegame.close()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
||||||
func copy_file_to_game_env(filename):
|
func copy_file_to_game_env(filename):
|
||||||
|
|
||||||
# Copy fake-editor to tmp directory (because the original might be in a .pck file).
|
# Copy fake-editor to tmp directory (because the original might be in a .pck file).
|
||||||
var file_outside = tmp_prefix + filename
|
var file_outside = tmp_prefix + filename
|
||||||
var file_inside = "/tmp/"+filename
|
var file_inside = "/tmp/"+filename
|
||||||
var content = game.read_file("res://scripts/"+filename, "")
|
var content = helpers.read_file("res://scripts/"+filename)
|
||||||
if content.empty():
|
helpers.write_file(file_outside, content)
|
||||||
push_error(filename + " could not be read.")
|
|
||||||
write_file(file_outside, content)
|
|
||||||
global_shell.run("chmod u+x " + file_inside)
|
global_shell.run("chmod u+x " + file_inside)
|
||||||
return file_inside
|
return file_inside
|
||||||
|
|
||||||
func read_file(path, fallback_string):
|
|
||||||
if debug_file_io:
|
|
||||||
print("reading " + path)
|
|
||||||
var file = File.new()
|
|
||||||
var open_status = file.open(path, File.READ)
|
|
||||||
if open_status == OK:
|
|
||||||
var content = file.get_as_text()
|
|
||||||
file.close()
|
|
||||||
return content
|
|
||||||
else:
|
|
||||||
return fallback_string
|
|
||||||
|
|
||||||
func write_file(path, content):
|
|
||||||
if debug_file_io:
|
|
||||||
print("writing " + path)
|
|
||||||
var file = File.new()
|
|
||||||
file.open(path, File.WRITE)
|
|
||||||
file.store_string(content)
|
|
||||||
file.close()
|
|
||||||
return true
|
|
||||||
|
|
||||||
func _tmp_prefix():
|
func _tmp_prefix():
|
||||||
var os = OS.get_name()
|
var os = OS.get_name()
|
||||||
if os == "X11":
|
if os == "X11":
|
||||||
|
@ -80,26 +54,6 @@ func _tmp_prefix():
|
||||||
elif os == "Windows":
|
elif os == "Windows":
|
||||||
# For some reason, this command outputs a space in the end? We remove it.
|
# For some reason, this command outputs a space in the end? We remove it.
|
||||||
# Also, Godot's default is to use forward slashes for everything.
|
# Also, Godot's default is to use forward slashes for everything.
|
||||||
return exec("echo", ["%TEMP%"]).replacen("\\", "/").replace(" \n", "/")
|
return helpers.exec("echo", ["%TEMP%"]).replacen("\\", "/").replace(" \n", "/")
|
||||||
else:
|
else:
|
||||||
push_error("Unsupported OS")
|
helpers.crash("Unsupported OS: %s" % os)
|
||||||
get_tree().quit()
|
|
||||||
|
|
||||||
# Run a simple command with arguments, blocking, using OS.execute.
|
|
||||||
func exec(command, args=[]):
|
|
||||||
var debug = false
|
|
||||||
|
|
||||||
if debug:
|
|
||||||
print("exec: %s [%s]" % [command, PoolStringArray(args).join(", ")])
|
|
||||||
|
|
||||||
var output = []
|
|
||||||
var exit_code = OS.execute(command, args, true, output, true)
|
|
||||||
output = output[0]
|
|
||||||
|
|
||||||
if exit_code != 0:
|
|
||||||
push_error("OS.execute failed: %s [%s] Output: %s" % [command, PoolStringArray(args).join(", "), output])
|
|
||||||
|
|
||||||
if debug:
|
|
||||||
print(output)
|
|
||||||
|
|
||||||
return output
|
|
||||||
|
|
54
helpers.gd
Normal file
54
helpers.gd
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
var debug_file_io = false
|
||||||
|
|
||||||
|
# Crash the game and display the error message.
|
||||||
|
func crash(message):
|
||||||
|
push_error(message)
|
||||||
|
print("Fatal error: " + message)
|
||||||
|
get_tree().quit()
|
||||||
|
|
||||||
|
# Run a simple command with arguments, blocking, using OS.execute.
|
||||||
|
func exec(command, args=[], crash_on_fail=true):
|
||||||
|
var debug = false
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print("exec: %s [%s]" % [command, PoolStringArray(args).join(", ")])
|
||||||
|
|
||||||
|
var output = []
|
||||||
|
var exit_code = OS.execute(command, args, true, output, true)
|
||||||
|
output = output[0]
|
||||||
|
|
||||||
|
if exit_code != 0 and crash_on_fail:
|
||||||
|
helpers.crash("OS.execute failed: %s [%s] Output: %s" % [command, PoolStringArray(args).join(", "), output])
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print(output)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
# Return the contents of a file. If no fallback_string is provided, crash when
|
||||||
|
# the file doesn't exist.
|
||||||
|
func read_file(path, fallback_string=null):
|
||||||
|
if debug_file_io:
|
||||||
|
print("reading " + path)
|
||||||
|
var file = File.new()
|
||||||
|
var open_status = file.open(path, File.READ)
|
||||||
|
if open_status == OK:
|
||||||
|
var content = file.get_as_text()
|
||||||
|
file.close()
|
||||||
|
return content
|
||||||
|
else:
|
||||||
|
if fallback_string != null:
|
||||||
|
return fallback_string
|
||||||
|
else:
|
||||||
|
helpers.crash("File %s could not be read, and has no fallback" % path)
|
||||||
|
|
||||||
|
func write_file(path, content):
|
||||||
|
if debug_file_io:
|
||||||
|
print("writing " + path)
|
||||||
|
var file = File.new()
|
||||||
|
file.open(path, File.WRITE)
|
||||||
|
file.store_string(content)
|
||||||
|
file.close()
|
||||||
|
return true
|
24
main.gd
24
main.gd
|
@ -67,13 +67,13 @@ func list_levels():
|
||||||
|
|
||||||
var final_level_sequence = []
|
var final_level_sequence = []
|
||||||
|
|
||||||
var level_sequence = Array(game.read_file("res://levels/%s/sequence" % chapter, "").split("\n"))
|
var level_sequence = Array(helpers.read_file("res://levels/%s/sequence" % chapter, "").split("\n"))
|
||||||
|
|
||||||
for level in level_sequence:
|
for level in level_sequence:
|
||||||
if level == "":
|
if level == "":
|
||||||
continue
|
continue
|
||||||
if not levels.has(level):
|
if not levels.has(level):
|
||||||
push_error("Level '%s' is specified in the sequence, but could not be found" % level)
|
helpers.crash("Level '%s' is specified in the sequence, but could not be found" % level)
|
||||||
levels.erase(level)
|
levels.erase(level)
|
||||||
final_level_sequence.push_back(level)
|
final_level_sequence.push_back(level)
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ func load_level(id):
|
||||||
var active_script = level_prefix+level+"/start"
|
var active_script = level_prefix+level+"/start"
|
||||||
|
|
||||||
var description_file = level_prefix+level+"/description"
|
var description_file = level_prefix+level+"/description"
|
||||||
var description = game.read_file(description_file, "no description")
|
var description = helpers.read_file(description_file, "(no description)")
|
||||||
|
|
||||||
# Surround all lines indented with four spaces with [code] tags.
|
# Surround all lines indented with four spaces with [code] tags.
|
||||||
var monospace_regex = RegEx.new()
|
var monospace_regex = RegEx.new()
|
||||||
|
@ -114,7 +114,7 @@ func load_level(id):
|
||||||
level_description.bbcode_text = description
|
level_description.bbcode_text = description
|
||||||
|
|
||||||
var congrats_file = level_prefix+level+"/congrats"
|
var congrats_file = level_prefix+level+"/congrats"
|
||||||
var congrats = game.read_file(congrats_file, "Good job, you solved the level!\n\nFeel free to try a few more things or click 'Next Level'.")
|
var congrats = helpers.read_file(congrats_file, "Good job, you solved the level!\n\nFeel free to try a few more things or click 'Next Level'.")
|
||||||
level_congrats.bbcode_text = congrats
|
level_congrats.bbcode_text = congrats
|
||||||
|
|
||||||
level_name.text = level
|
level_name.text = level
|
||||||
|
@ -123,18 +123,16 @@ func load_level(id):
|
||||||
# Make sure that active_repository is in a temporary directory.
|
# Make sure that active_repository is in a temporary directory.
|
||||||
var expected_prefix = "/tmp"
|
var expected_prefix = "/tmp"
|
||||||
if active_repository_path.substr(0,4) != expected_prefix:
|
if active_repository_path.substr(0,4) != expected_prefix:
|
||||||
push_error("Refusing to delete a directory that does not start with %s" % expected_prefix)
|
helpers.crash("Refusing to delete directory %s that does not start with %s" % [active_repository_path, expected_prefix])
|
||||||
get_tree().quit()
|
|
||||||
if goal_repository_path.substr(0,4) != expected_prefix:
|
if goal_repository_path.substr(0,4) != expected_prefix:
|
||||||
push_error("Refusing to delete a directory that does not start with %s" % expected_prefix)
|
helpers.crash("Refusing to delete directory %s that does not start with %s" % [goal_repository_path, expected_prefix])
|
||||||
get_tree().quit()
|
|
||||||
|
|
||||||
# Danger zone!
|
# Danger zone!
|
||||||
game.global_shell.run("rm -rf '%s'" % active_repository_path)
|
game.global_shell.run("rm -rf '%s'" % active_repository_path)
|
||||||
game.global_shell.run("rm -rf '%s'" % goal_repository_path)
|
game.global_shell.run("rm -rf '%s'" % goal_repository_path)
|
||||||
|
|
||||||
var goal_script_content = game.read_file(goal_script, "")
|
var goal_script_content = helpers.read_file(goal_script, "")
|
||||||
var active_script_content = game.read_file(active_script, "")
|
var active_script_content = helpers.read_file(active_script, "")
|
||||||
construct_repo(active_script_content +"\n"+ goal_script_content, goal_repository_path)
|
construct_repo(active_script_content +"\n"+ goal_script_content, goal_repository_path)
|
||||||
construct_repo(active_script_content, active_repository_path)
|
construct_repo(active_script_content, active_repository_path)
|
||||||
|
|
||||||
|
@ -143,8 +141,8 @@ func load_level(id):
|
||||||
|
|
||||||
var win_script = level_prefix+level+"/win"
|
var win_script = level_prefix+level+"/win"
|
||||||
var win_script_target = game.tmp_prefix+"/win"
|
var win_script_target = game.tmp_prefix+"/win"
|
||||||
var win_script_content = game.read_file(win_script, "exit 1\n")
|
var win_script_content = helpers.read_file(win_script, "exit 1\n")
|
||||||
game.write_file(win_script_target, win_script_content)
|
helpers.write_file(win_script_target, win_script_content)
|
||||||
|
|
||||||
terminal.clear()
|
terminal.clear()
|
||||||
|
|
||||||
|
@ -171,7 +169,7 @@ func construct_repo(script_content, path):
|
||||||
|
|
||||||
var script_path_outside = game.tmp_prefix+"/git-hydra-script"
|
var script_path_outside = game.tmp_prefix+"/git-hydra-script"
|
||||||
var script_path = "/tmp/git-hydra-script"
|
var script_path = "/tmp/git-hydra-script"
|
||||||
game.write_file(script_path_outside, script_content)
|
helpers.write_file(script_path_outside, script_content)
|
||||||
|
|
||||||
game.global_shell.run("mkdir " + path)
|
game.global_shell.run("mkdir " + path)
|
||||||
game.global_shell.cd(path)
|
game.global_shell.cd(path)
|
||||||
|
|
|
@ -26,6 +26,7 @@ run/main_scene="res://main.tscn"
|
||||||
[autoload]
|
[autoload]
|
||||||
|
|
||||||
game="*res://game.gd"
|
game="*res://game.gd"
|
||||||
|
helpers="*res://helpers.gd"
|
||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
|
|
5
shell.gd
5
shell.gd
|
@ -49,7 +49,7 @@ func run(command):
|
||||||
#
|
#
|
||||||
hacky_command = '"\''+hacky_command.replace("'", "'\"'\"'")+'\'"'
|
hacky_command = '"\''+hacky_command.replace("'", "'\"'\"'")+'\'"'
|
||||||
|
|
||||||
var output = game.exec(_shell_binary(), ["-c", hacky_command])
|
var output = helpers.exec(_shell_binary(), ["-c", hacky_command], false)
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
print(output)
|
print(output)
|
||||||
|
@ -64,8 +64,7 @@ func _shell_binary():
|
||||||
elif os == "Windows":
|
elif os == "Windows":
|
||||||
return "dependencies\\windows\\git\\bin\\bash.exe"
|
return "dependencies\\windows\\git\\bin\\bash.exe"
|
||||||
else:
|
else:
|
||||||
push_error("Unsupported OS")
|
helpers.crash("Unsupported OS: %s" % os)
|
||||||
get_tree().quit()
|
|
||||||
|
|
||||||
var _t
|
var _t
|
||||||
func run_async(command):
|
func run_async(command):
|
||||||
|
|
|
@ -18,7 +18,7 @@ func _process(_delta):
|
||||||
if _s.is_connection_available():
|
if _s.is_connection_available():
|
||||||
if _connected:
|
if _connected:
|
||||||
_c.disconnect_from_host()
|
_c.disconnect_from_host()
|
||||||
push_error("Dropping active connection")
|
helpers.crash("Dropping active connection")
|
||||||
_c = _s.take_connection()
|
_c = _s.take_connection()
|
||||||
_connected = true
|
_connected = true
|
||||||
print("connected!")
|
print("connected!")
|
||||||
|
@ -38,4 +38,4 @@ func send(text):
|
||||||
text += "\n"
|
text += "\n"
|
||||||
_c.put_data(text.to_utf8())
|
_c.put_data(text.to_utf8())
|
||||||
else:
|
else:
|
||||||
push_error("Trying to send data on closed connection")
|
helpers.crash("Trying to send data on closed connection")
|
||||||
|
|
|
@ -29,7 +29,7 @@ func _ready():
|
||||||
|
|
||||||
var error = $TextEditor.connect("hide", self, "editor_closed")
|
var error = $TextEditor.connect("hide", self, "editor_closed")
|
||||||
if error != OK:
|
if error != OK:
|
||||||
push_error("Could not connect TextEditor's hide signal")
|
helpers.crash("Could not connect TextEditor's hide signal")
|
||||||
input.grab_focus()
|
input.grab_focus()
|
||||||
|
|
||||||
var all_git_commands = repository.shell.run("git help -a | grep \"^ \\+[a-z-]\\+ \" -o")
|
var all_git_commands = repository.shell.run("git help -a | grep \"^ \\+[a-z-]\\+ \" -o")
|
||||||
|
|
|
@ -22,10 +22,7 @@ func open(filename):
|
||||||
path = filename
|
path = filename
|
||||||
|
|
||||||
var fixme_path = game.tmp_prefix+"/active/"
|
var fixme_path = game.tmp_prefix+"/active/"
|
||||||
var content = game.read_file(fixme_path+filename, "[ERROR_FAKE_EDITOR]")
|
var content = helpers.read_file(fixme_path+filename)
|
||||||
if content == "[ERROR_FAKE_EDITOR]":
|
|
||||||
push_error("Specified file could not be read.")
|
|
||||||
get_tree().quit()
|
|
||||||
text = content
|
text = content
|
||||||
|
|
||||||
show()
|
show()
|
||||||
|
@ -33,7 +30,7 @@ func open(filename):
|
||||||
|
|
||||||
func save():
|
func save():
|
||||||
var fixme_path = game.tmp_prefix+"/active/"
|
var fixme_path = game.tmp_prefix+"/active/"
|
||||||
game.write_file(fixme_path+path, text)
|
helpers.write_file(fixme_path+path, text)
|
||||||
close()
|
close()
|
||||||
|
|
||||||
func close():
|
func close():
|
||||||
|
|
Loading…
Reference in a new issue