On Windows, put commands in a script before executing them

This avoids the problem that newlines in the command always interrupt
execution.
This commit is contained in:
Sebastian Morr 2020-10-26 07:26:23 -07:00
parent 251aef245c
commit 0fb30e99ec

View file

@ -37,35 +37,42 @@ func run(command, crash_on_fail=true):
hacky_command += "cd '%s' || exit 1;" % _cwd hacky_command += "cd '%s' || exit 1;" % _cwd
hacky_command += command hacky_command += command
# Godot's OS.execute wraps each argument in double quotes before executing. var result
# 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
# quote appearing in our string, we close the single quoted string, and add
# a double quoted string containing the single quote. Ooooof!
#
# Example: The string
#
# test 'fu' "bla" blubb
#
# becomes
#
# "'test '"'"'fu'"'"' "bla" blubb"
#
# Quoting Magic is not needed for Windows!
if _os == "X11" or _os == "OSX": if _os == "X11" or _os == "OSX":
hacky_command = '"\''+hacky_command.replace("'", "'\"'\"'")+'\'"' # Godot's OS.execute wraps each argument in double quotes before executing
# on Linux and macOS.
# 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
# quote appearing in our string, we close the single quoted string, and add
# a double quoted string containing the single quote. Ooooof!
#
# Example: The string
#
# test 'fu' "bla" blubb
#
# becomes
#
# "'test '"'"'fu'"'"' "bla" blubb"
var result = helpers.exec(_shell_binary(), ["-c", hacky_command], crash_on_fail) hacky_command = '"\''+hacky_command.replace("'", "'\"'\"'")+'\'"'
exit_code = result["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_inside + "command"
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: if debug:
print(result["output"]) print(result["output"])
exit_code = result["exit_code"]
return result["output"] return result["output"]
func _shell_binary(): func _shell_binary():
if _os == "X11" or _os == "OSX": if _os == "X11" or _os == "OSX":
return "bash" return "bash"
elif _os == "Windows": elif _os == "Windows":