mirror of
https://github.com/git-learning-game/oh-my-git.git
synced 2024-11-28 16:20:19 +01:00
53c249d059
It uses a Perl script to keep a bash session open, which attaches to a port the game keeps open. This avoids having to start a new Git bash for each command, improving the execution speed by a factor of 3-4.
152 lines
4.2 KiB
GDScript
152 lines
4.2 KiB
GDScript
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()
|
|
# Oh, still here? Let's crash more violently, by calling a non-existing method.
|
|
# Violent delights have violent ends.
|
|
get_tree().fatal_error()
|
|
|
|
func map(array, object, f):
|
|
var new_array = []
|
|
for i in range(array.size()):
|
|
new_array.push_back(object.call(f, array[i]))
|
|
return new_array
|
|
|
|
# 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 \nExit Code %d" % [command, PoolStringArray(args).join(", "), output, exit_code])
|
|
elif debug:
|
|
print("Output: %s" %output)
|
|
|
|
return {"output": output, "exit_code": exit_code}
|
|
|
|
func exec_async(command, args=[]):
|
|
OS.execute(command, args, false)
|
|
|
|
# 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)
|
|
|
|
# Create the base directory of the file, if it doesn't exist.
|
|
var parts = Array(path.split("/"))
|
|
parts.pop_back()
|
|
var dirname = PoolStringArray(parts).join("/")
|
|
var dir = Directory.new()
|
|
if not dir.dir_exists(path):
|
|
dir.make_dir_recursive(dirname)
|
|
|
|
var file = File.new()
|
|
file.open(path, File.WRITE)
|
|
file.store_string(content)
|
|
file.close()
|
|
return true
|
|
|
|
func parse_args():
|
|
var arguments = {}
|
|
for argument in OS.get_cmdline_args():
|
|
if argument.substr(0, 2) == "--":
|
|
# Parse valid command-line arguments into a dictionary
|
|
if argument.find("=") > -1:
|
|
var key_value = argument.split("=")
|
|
arguments[key_value[0].lstrip("--")] = key_value[1]
|
|
else:
|
|
arguments[argument.lstrip("--")] = true
|
|
return arguments
|
|
|
|
func careful_delete(path_inside):
|
|
var expected_prefix
|
|
|
|
var os = OS.get_name()
|
|
|
|
if os == "X11":
|
|
expected_prefix = "/home/%s/.local/share/Oh My Git/tmp/" % OS.get_environment("USER")
|
|
elif os == "OSX":
|
|
expected_prefix = "/Users/%s/Library/Application Support/Oh My Git/tmp/" % OS.get_environment("USER")
|
|
elif os == "Windows":
|
|
expected_prefix = "C:/Users/%s/AppData/Roaming/Oh My Git/tmp/" % OS.get_environment("USERNAME")
|
|
else:
|
|
helpers.crash("Unsupported OS: %s" % os)
|
|
|
|
if path_inside.substr(0,expected_prefix.length()) != expected_prefix:
|
|
helpers.crash("Refusing to delete directory %s that does not start with %s" % [path_inside, expected_prefix])
|
|
else:
|
|
game.global_shell.cd(game.tmp_prefix)
|
|
game.global_shell.run("rm -rf '%s'" % path_inside)
|
|
|
|
func parse(file):
|
|
var text = read_file(file)
|
|
var result = {}
|
|
var current_section
|
|
|
|
var section_regex = RegEx.new()
|
|
section_regex.compile("^\\[(.*)\\]$")
|
|
|
|
var assignment_regex = RegEx.new()
|
|
assignment_regex.compile("^([a-z ]+)=(.*)$")
|
|
|
|
for line in text.split("\n"):
|
|
# Skip comments.
|
|
if line.substr(0, 1) == ";":
|
|
continue
|
|
|
|
# Parse a [section name].
|
|
var m = section_regex.search(line)
|
|
if m:
|
|
current_section = m.get_string(1)
|
|
result[current_section] = ""
|
|
continue
|
|
|
|
# Parse a direct=assignment.
|
|
m = assignment_regex.search(line)
|
|
if m:
|
|
var key = m.get_string(1).strip_edges()
|
|
var value = m.get_string(2).strip_edges()
|
|
result[key] = value
|
|
continue
|
|
|
|
# At this point, the line is just content belonging to the current section.
|
|
if current_section:
|
|
result[current_section] += line + "\n"
|
|
|
|
for key in result:
|
|
result[key] = result[key].strip_edges()
|
|
|
|
return result
|
|
|
|
func abbreviate(text, max_length):
|
|
if text.length() > max_length-3:
|
|
text = text.substr(0, max_length-3) + "..."
|
|
|
|
return text
|