mirror of
https://github.com/git-learning-game/oh-my-git.git
synced 2024-11-20 16:20:18 +01:00
On Windows, use the faster BetterShell
This commit is contained in:
parent
a60b2f9afb
commit
05b98d7a13
6 changed files with 127 additions and 39 deletions
|
@ -10,6 +10,11 @@ config_version=4
|
||||||
|
|
||||||
_global_script_classes=[ {
|
_global_script_classes=[ {
|
||||||
"base": "Node",
|
"base": "Node",
|
||||||
|
"class": "BetterShell",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://scenes/better_shell.gd"
|
||||||
|
}, {
|
||||||
|
"base": "Node",
|
||||||
"class": "Chapter",
|
"class": "Chapter",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://scenes/chapter.gd"
|
"path": "res://scenes/chapter.gd"
|
||||||
|
@ -40,6 +45,7 @@ _global_script_classes=[ {
|
||||||
"path": "res://scenes/shell_command.gd"
|
"path": "res://scenes/shell_command.gd"
|
||||||
} ]
|
} ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
"BetterShell": "",
|
||||||
"Chapter": "",
|
"Chapter": "",
|
||||||
"FileBrowserItem": "",
|
"FileBrowserItem": "",
|
||||||
"Level": "",
|
"Level": "",
|
||||||
|
|
75
scenes/better_shell.gd
Normal file
75
scenes/better_shell.gd
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
extends Node
|
||||||
|
class_name BetterShell
|
||||||
|
|
||||||
|
var exit_code
|
||||||
|
|
||||||
|
var _cwd
|
||||||
|
var _os = OS.get_name()
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
# Create required directories and move into the tmp directory.
|
||||||
|
_cwd = "/tmp"
|
||||||
|
run("mkdir -p '%s/repos'" % game.tmp_prefix)
|
||||||
|
_cwd = game.tmp_prefix
|
||||||
|
|
||||||
|
func cd(dir):
|
||||||
|
_cwd = dir
|
||||||
|
|
||||||
|
# Run a shell command given as a string. Run this if you're interested in the
|
||||||
|
# output of the command.
|
||||||
|
func run(command, crash_on_fail=true):
|
||||||
|
var shell_command = ShellCommand.new()
|
||||||
|
shell_command.command = command
|
||||||
|
shell_command.crash_on_fail = crash_on_fail
|
||||||
|
|
||||||
|
run_async_thread(shell_command)
|
||||||
|
exit_code = shell_command.exit_code
|
||||||
|
return shell_command.output
|
||||||
|
|
||||||
|
func run_async(command, crash_on_fail=true):
|
||||||
|
var shell_command = ShellCommand.new()
|
||||||
|
shell_command.command = command
|
||||||
|
shell_command.crash_on_fail = crash_on_fail
|
||||||
|
|
||||||
|
var t = Thread.new()
|
||||||
|
shell_command.thread = t
|
||||||
|
t.start(self, "run_async_thread", shell_command)
|
||||||
|
|
||||||
|
return shell_command
|
||||||
|
|
||||||
|
func run_async_thread(shell_command):
|
||||||
|
var debug = false
|
||||||
|
|
||||||
|
var command = shell_command.command
|
||||||
|
var crash_on_fail = shell_command.crash_on_fail
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print("$ %s" % command)
|
||||||
|
|
||||||
|
var env = {}
|
||||||
|
env["HOME"] = game.tmp_prefix
|
||||||
|
|
||||||
|
var hacky_command = ""
|
||||||
|
for variable in env:
|
||||||
|
hacky_command += "export %s='%s';" % [variable, env[variable]]
|
||||||
|
|
||||||
|
#hacky_command += "export PATH=\'"+game.tmp_prefix+":'\"$PATH\";"
|
||||||
|
hacky_command += "cd '%s' || exit 1;" % _cwd
|
||||||
|
hacky_command += command
|
||||||
|
|
||||||
|
#print(hacky_command)
|
||||||
|
|
||||||
|
var result
|
||||||
|
var shell_command_internal = game.shell_test(hacky_command)
|
||||||
|
|
||||||
|
shell_command.output = shell_command_internal.output
|
||||||
|
shell_command.exit_code = shell_command_internal.exit_code
|
||||||
|
shell_command.emit_signal("done")
|
||||||
|
|
||||||
|
func _shell_binary():
|
||||||
|
if _os == "X11" or _os == "OSX":
|
||||||
|
return "bash"
|
||||||
|
elif _os == "Windows":
|
||||||
|
return "dependencies\\windows\\git\\bin\\bash.exe"
|
||||||
|
else:
|
||||||
|
helpers.crash("Unsupported OS: %s" % _os)
|
|
@ -28,7 +28,7 @@ func _ready():
|
||||||
|
|
||||||
start_remote_shell()
|
start_remote_shell()
|
||||||
yield(get_tree().create_timer(0.1), "timeout")
|
yield(get_tree().create_timer(0.1), "timeout")
|
||||||
global_shell = Shell.new()
|
global_shell = new_shell()
|
||||||
|
|
||||||
# var cmd = global_shell.run("echo hi")
|
# var cmd = global_shell.run("echo hi")
|
||||||
# print(cmd)
|
# print(cmd)
|
||||||
|
@ -138,7 +138,6 @@ func toggle_music():
|
||||||
else:
|
else:
|
||||||
music.volume_db += 100
|
music.volume_db += 100
|
||||||
|
|
||||||
|
|
||||||
func shell_test(command):
|
func shell_test(command):
|
||||||
mutex.lock()
|
mutex.lock()
|
||||||
#print("go")
|
#print("go")
|
||||||
|
@ -150,3 +149,9 @@ func shell_test(command):
|
||||||
#print("stop")
|
#print("stop")
|
||||||
mutex.unlock()
|
mutex.unlock()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
func new_shell():
|
||||||
|
if OS.get_name() == "Windows":
|
||||||
|
return BetterShell.new()
|
||||||
|
else:
|
||||||
|
return Shell.new()
|
||||||
|
|
|
@ -14,7 +14,7 @@ var type = "remote"
|
||||||
|
|
||||||
var node = preload("res://scenes/node.tscn")
|
var node = preload("res://scenes/node.tscn")
|
||||||
|
|
||||||
var shell = Shell.new()
|
var shell = game.new_shell()
|
||||||
var objects = {}
|
var objects = {}
|
||||||
var mouse_inside = false
|
var mouse_inside = false
|
||||||
var has_been_layouted = false
|
var has_been_layouted = false
|
||||||
|
|
|
@ -53,44 +53,44 @@ func run_async_thread(shell_command):
|
||||||
for variable in env:
|
for variable in env:
|
||||||
hacky_command += "export %s='%s';" % [variable, env[variable]]
|
hacky_command += "export %s='%s';" % [variable, env[variable]]
|
||||||
|
|
||||||
#hacky_command += "export PATH=\'"+game.tmp_prefix+":'\"$PATH\";"
|
hacky_command += "export PATH=\'"+game.tmp_prefix+":'\"$PATH\";"
|
||||||
hacky_command += "cd '%s' || exit 1;" % _cwd
|
hacky_command += "cd '%s' || exit 1;" % _cwd
|
||||||
hacky_command += command
|
hacky_command += command
|
||||||
|
|
||||||
#print(hacky_command)
|
|
||||||
|
|
||||||
var result
|
var result
|
||||||
var shell_command_internal = game.shell_test(hacky_command)
|
if _os == "X11" or _os == "OSX":
|
||||||
# if _os == "X11" or _os == "OSX":
|
# Godot's OS.execute wraps each argument in double quotes before executing
|
||||||
# # Godot's OS.execute wraps each argument in double quotes before executing
|
# on Linux and macOS.
|
||||||
# # on Linux and macOS.
|
# Because we want to be in a single-quote context, where nothing is evaluated,
|
||||||
# # Because we want to be in a single-quote context, where nothing is evaluated,
|
# we end those double quotes and start a single quoted string. For each single
|
||||||
# # we end those double quotes and start a single quoted string. For each single
|
# quote appearing in our string, we close the single quoted string, and add
|
||||||
# # quote appearing in our string, we close the single quoted string, and add
|
# a double quoted string containing the single quote. Ooooof!
|
||||||
# # a double quoted string containing the single quote. Ooooof!
|
|
||||||
# #
|
|
||||||
# # Example: The string
|
|
||||||
# #
|
|
||||||
# # test 'fu' "bla" blubb
|
|
||||||
# #
|
|
||||||
# # becomes
|
|
||||||
# #
|
|
||||||
# # "'test '"'"'fu'"'"' "bla" blubb"
|
|
||||||
#
|
#
|
||||||
# hacky_command = '"\''+hacky_command.replace("'", "'\"'\"'")+'\'"'
|
# Example: The string
|
||||||
# result = helpers.exec(_shell_binary(), ["-c", hacky_command], crash_on_fail)
|
#
|
||||||
# elif _os == "Windows":
|
# test 'fu' "bla" blubb
|
||||||
# # On Windows, if the command contains a newline (even if inside a string),
|
#
|
||||||
# # execution will end. To avoid that, we first write the command to a file,
|
# becomes
|
||||||
# # and run that file with bash.
|
#
|
||||||
# var script_path = game.tmp_prefix + "command" + str(randi())
|
# "'test '"'"'fu'"'"' "bla" blubb"
|
||||||
# helpers.write_file(script_path, hacky_command)
|
|
||||||
# result = helpers.exec(_shell_binary(), [script_path], crash_on_fail)
|
|
||||||
# else:
|
|
||||||
# helpers.crash("Unimplemented OS: %s" % _os)
|
|
||||||
|
|
||||||
shell_command.output = shell_command_internal.output
|
hacky_command = '"\''+hacky_command.replace("'", "'\"'\"'")+'\'"'
|
||||||
shell_command.exit_code = shell_command_internal.exit_code
|
result = helpers.exec(_shell_binary(), ["-c", hacky_command], crash_on_fail)
|
||||||
|
elif _os == "Windows":
|
||||||
|
# On Windows, if the command contains a newline (even if inside a string),
|
||||||
|
# execution will end. To avoid that, we first write the command to a file,
|
||||||
|
# and run that file with bash.
|
||||||
|
var script_path = game.tmp_prefix + "command" + str(randi())
|
||||||
|
helpers.write_file(script_path, hacky_command)
|
||||||
|
result = helpers.exec(_shell_binary(), [script_path], crash_on_fail)
|
||||||
|
else:
|
||||||
|
helpers.crash("Unimplemented OS: %s" % _os)
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print(result["output"])
|
||||||
|
|
||||||
|
shell_command.output = result["output"]
|
||||||
|
shell_command.exit_code = result["exit_code"]
|
||||||
shell_command.emit_signal("done")
|
shell_command.emit_signal("done")
|
||||||
|
|
||||||
func _shell_binary():
|
func _shell_binary():
|
||||||
|
|
|
@ -13,6 +13,8 @@ onready var completions = $Rows/TopHalf/Completions
|
||||||
var repository
|
var repository
|
||||||
onready var main = get_tree().get_root().get_node("Main")
|
onready var main = get_tree().get_root().get_node("Main")
|
||||||
|
|
||||||
|
var shell = Shell.new()
|
||||||
|
|
||||||
var premade_commands = [
|
var premade_commands = [
|
||||||
'git commit --allow-empty -m "empty"',
|
'git commit --allow-empty -m "empty"',
|
||||||
'echo $RANDOM | git hash-object -w --stdin',
|
'echo $RANDOM | git hash-object -w --stdin',
|
||||||
|
@ -85,9 +87,9 @@ func send_command(command):
|
||||||
editor_regex.compile("^(vim?|gedit|emacs|kate|nano|code) ")
|
editor_regex.compile("^(vim?|gedit|emacs|kate|nano|code) ")
|
||||||
command = editor_regex.sub(command, "fake-editor ")
|
command = editor_regex.sub(command, "fake-editor ")
|
||||||
|
|
||||||
# var cmd = repository.shell.run_async(command, false)
|
shell.cd(repository.path)
|
||||||
# yield(cmd, "done")
|
var cmd = shell.run_async(command, false)
|
||||||
var cmd = game.shell_test(command)
|
yield(cmd, "done")
|
||||||
call_deferred("command_done", cmd)
|
call_deferred("command_done", cmd)
|
||||||
|
|
||||||
func command_done(cmd):
|
func command_done(cmd):
|
||||||
|
|
Loading…
Reference in a new issue