mirror of
https://github.com/git-learning-game/oh-my-git.git
synced 2024-12-22 20:32:38 +01:00
Introduce Shell class with a cd
method and a run
method
game.exec is now the only point in the code that calls OS.execute. shell.run is the only point that refers to /bin/sh.
This commit is contained in:
parent
5a291685fa
commit
579f18736a
6 changed files with 93 additions and 102 deletions
66
game.gd
66
game.gd
|
@ -1,65 +1,27 @@
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
var _file = "user://savegame.json"
|
var cwd
|
||||||
var state = {}
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
load_state()
|
cwd = exec("pwd", [], true)
|
||||||
|
|
||||||
func _initial_state():
|
# Run a simple command with arguments, blocking, using OS.execute.
|
||||||
return {}
|
func exec(command, args=[], remote_trailing_newline=false):
|
||||||
|
var debug = false
|
||||||
|
if debug:
|
||||||
|
print("game.exec: %s [%s]" % [command, PoolStringArray(args).join(", ")])
|
||||||
|
|
||||||
func save_state() -> bool:
|
|
||||||
var savegame = File.new()
|
|
||||||
|
|
||||||
savegame.open(_file, File.WRITE)
|
|
||||||
savegame.store_line(to_json(state))
|
|
||||||
savegame.close()
|
|
||||||
return true
|
|
||||||
|
|
||||||
func load_state() -> bool:
|
|
||||||
var savegame = File.new()
|
|
||||||
if not savegame.file_exists(_file):
|
|
||||||
return false
|
|
||||||
|
|
||||||
savegame.open(_file, File.READ)
|
|
||||||
|
|
||||||
state = _initial_state()
|
|
||||||
var new_state = parse_json(savegame.get_line())
|
|
||||||
for key in new_state:
|
|
||||||
state[key] = new_state[key]
|
|
||||||
savegame.close()
|
|
||||||
return true
|
|
||||||
|
|
||||||
# Run a simple command given as a string, blocking, using execute.
|
|
||||||
func run(command):
|
|
||||||
print("run: "+command)
|
|
||||||
var output = []
|
var output = []
|
||||||
OS.execute(command, [], true, output, true)
|
OS.execute(command, args, true, output, true)
|
||||||
# Remove trailing newline.
|
output = output[0]
|
||||||
return output[0].substr(0,len(output[0])-1)
|
|
||||||
|
|
||||||
func sh(command, wd="/tmp/"):
|
if debug:
|
||||||
print("sh in "+wd+": "+command)
|
print(output)
|
||||||
var cwd = game.run("pwd")
|
|
||||||
var output = []
|
|
||||||
|
|
||||||
var hacky_command = command
|
if remote_trailing_newline:
|
||||||
hacky_command = "cd '"+wd+"';"+hacky_command
|
output = output.substr(0,len(output)-1)
|
||||||
hacky_command = "export EDITOR=fake-editor;"+hacky_command
|
|
||||||
hacky_command = "export PATH=\"$PATH\":"+cwd+"/scripts;"+hacky_command
|
|
||||||
OS.execute("/bin/sh", ["-c", hacky_command], true, output, true)
|
|
||||||
return output[0]
|
|
||||||
|
|
||||||
func script(filename, wd="/tmp/"):
|
return output
|
||||||
print("sh script in "+wd+": "+filename)
|
|
||||||
var cwd = game.run("pwd")
|
|
||||||
var output = []
|
|
||||||
|
|
||||||
var hacky_command = "/bin/sh " + filename
|
|
||||||
hacky_command = "cd '"+wd+"';"+hacky_command
|
|
||||||
OS.execute("/bin/sh", ["-c", hacky_command], true, output, true)
|
|
||||||
return output[0]
|
|
||||||
|
|
||||||
func read_file(path):
|
func read_file(path):
|
||||||
print("read "+path)
|
print("read "+path)
|
||||||
|
|
53
main.gd
53
main.gd
|
@ -46,9 +46,8 @@ func load_level(id):
|
||||||
var levels = list_levels()
|
var levels = list_levels()
|
||||||
|
|
||||||
var level = levels[id]
|
var level = levels[id]
|
||||||
var cwd = game.run("pwd")
|
|
||||||
var tmp_prefix = "/tmp/"
|
var tmp_prefix = "/tmp/"
|
||||||
var level_prefix = cwd + "/levels/"
|
var level_prefix = game.cwd + "/levels/"
|
||||||
|
|
||||||
var goal_repository_path = tmp_prefix+"goal/"
|
var goal_repository_path = tmp_prefix+"goal/"
|
||||||
var active_repository_path = tmp_prefix+"active/"
|
var active_repository_path = tmp_prefix+"active/"
|
||||||
|
@ -58,8 +57,19 @@ func load_level(id):
|
||||||
var description = game.read_file(level_prefix+level+"/description")
|
var description = game.read_file(level_prefix+level+"/description")
|
||||||
$LevelDescription.bbcode_text = description
|
$LevelDescription.bbcode_text = description
|
||||||
|
|
||||||
OS.execute("rm", ["-r", active_repository_path], true)
|
# Danger zone! We're actually destroying stuff here.
|
||||||
OS.execute("rm", ["-r", goal_repository_path], true)
|
# Make sure that active_repository is in a temporary directory.
|
||||||
|
var expected_prefix = "/tmp"
|
||||||
|
if active_repository_path.substr(0,4) != expected_prefix:
|
||||||
|
push_error("Refusing to delete a directory that does not start with %s" % expected_prefix)
|
||||||
|
get_tree().quit()
|
||||||
|
if goal_repository_path.substr(0,4) != expected_prefix:
|
||||||
|
push_error("Refusing to delete a directory that does not start with %s" % expected_prefix)
|
||||||
|
get_tree().quit()
|
||||||
|
|
||||||
|
game.exec("rm", ["-r", active_repository_path])
|
||||||
|
game.exec("rm", ["-r", goal_repository_path])
|
||||||
|
|
||||||
construct_repo(goal_script, goal_repository_path)
|
construct_repo(goal_script, goal_repository_path)
|
||||||
construct_repo(active_script, active_repository_path)
|
construct_repo(active_script, active_repository_path)
|
||||||
|
|
||||||
|
@ -67,41 +77,16 @@ func load_level(id):
|
||||||
active_repository.path = active_repository_path
|
active_repository.path = active_repository_path
|
||||||
|
|
||||||
func construct_repo(script, path):
|
func construct_repo(script, path):
|
||||||
print(path)
|
var shell = Shell.new()
|
||||||
game.sh("mkdir "+path)
|
shell.run("mkdir " + path)
|
||||||
game.sh("git init", path)
|
shell.cd(path)
|
||||||
print(game.script(script, path))
|
shell.run("git init")
|
||||||
#var commands = game.read_file(script).split("\n")
|
print(shell.run("source "+script))
|
||||||
#print(commands)
|
|
||||||
#for command in commands:
|
|
||||||
# print(command)
|
|
||||||
# game.sh(command, path)
|
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
if server.is_connection_available():
|
if server.is_connection_available():
|
||||||
client_connection = server.take_connection()
|
client_connection = server.take_connection()
|
||||||
read_commit_message()
|
read_commit_message()
|
||||||
# if true or get_global_mouse_position().x < get_viewport_rect().size.x*0.7:
|
|
||||||
# if Input.is_action_just_pressed("click"):
|
|
||||||
# var mindist = 9999999
|
|
||||||
# for o in objects.values():
|
|
||||||
# var d = o.position.distance_to(get_global_mouse_position())
|
|
||||||
# if d < mindist:
|
|
||||||
# mindist = d
|
|
||||||
# dragged = o
|
|
||||||
# if Input.is_action_just_released("click"):
|
|
||||||
# dragged = null
|
|
||||||
# if dragged:
|
|
||||||
# dragged.position = get_global_mouse_position()
|
|
||||||
|
|
||||||
#func run(command):
|
|
||||||
# var a = command.split(" ")
|
|
||||||
# var cmd = a[0]
|
|
||||||
# a.remove(0)
|
|
||||||
# var output = []
|
|
||||||
# OS.execute(cmd, a, true, output, true)
|
|
||||||
# print(command)
|
|
||||||
# print(output[0])
|
|
||||||
|
|
||||||
func read_commit_message():
|
func read_commit_message():
|
||||||
$CommitMessage.show()
|
$CommitMessage.show()
|
||||||
|
|
|
@ -8,9 +8,14 @@
|
||||||
|
|
||||||
config_version=4
|
config_version=4
|
||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ {
|
||||||
|
"base": "Node",
|
||||||
|
"class": "Shell",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://shell.gd"
|
||||||
|
} ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
"Shell": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
@ -60,3 +65,10 @@ click={
|
||||||
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
|
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[network]
|
||||||
|
|
||||||
|
limits/debugger_stdout/max_chars_per_second=100000
|
||||||
|
limits/debugger_stdout/max_messages_per_frame=1000
|
||||||
|
limits/debugger_stdout/max_errors_per_second=1000
|
||||||
|
limits/debugger_stdout/max_warnings_per_second=1000
|
||||||
|
|
|
@ -2,10 +2,12 @@ extends Container
|
||||||
|
|
||||||
export var label: String setget set_label
|
export var label: String setget set_label
|
||||||
export var path: String setget set_path, get_path
|
export var path: String setget set_path, get_path
|
||||||
var objects = {}
|
|
||||||
|
|
||||||
var node = preload("res://node.tscn")
|
var node = preload("res://node.tscn")
|
||||||
|
|
||||||
|
var shell = Shell.new()
|
||||||
|
var objects = {}
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -21,6 +23,7 @@ func update_everything():
|
||||||
|
|
||||||
func set_path(new_path):
|
func set_path(new_path):
|
||||||
path = new_path
|
path = new_path
|
||||||
|
shell.cd(new_path)
|
||||||
for o in objects.values():
|
for o in objects.values():
|
||||||
o.queue_free()
|
o.queue_free()
|
||||||
objects = {}
|
objects = {}
|
||||||
|
@ -109,13 +112,7 @@ func apply_forces():
|
||||||
o.position -= dir*f
|
o.position -= dir*f
|
||||||
|
|
||||||
func git(args, splitlines = false):
|
func git(args, splitlines = false):
|
||||||
var output = []
|
var o = shell.run("git " + args)
|
||||||
var a = args.split(" ")
|
|
||||||
#print ("Running: ", a)
|
|
||||||
a.insert(0, "-C")
|
|
||||||
a.insert(1, path)
|
|
||||||
OS.execute("git", a, true, output, true)
|
|
||||||
var o = output[0]
|
|
||||||
|
|
||||||
if splitlines:
|
if splitlines:
|
||||||
o = o.split("\n")
|
o = o.split("\n")
|
||||||
|
@ -150,7 +147,7 @@ func update_head():
|
||||||
add_child(n2)
|
add_child(n2)
|
||||||
|
|
||||||
func all_objects():
|
func all_objects():
|
||||||
return git("cat-file --batch-check=%(objectname) --batch-all-objects", true)
|
return git("cat-file --batch-check='%(objectname)' --batch-all-objects", true)
|
||||||
|
|
||||||
func object_type(id):
|
func object_type(id):
|
||||||
return git("cat-file -t "+id)
|
return git("cat-file -t "+id)
|
||||||
|
|
35
shell.gd
Normal file
35
shell.gd
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
extends Node
|
||||||
|
class_name Shell
|
||||||
|
|
||||||
|
var _cwd
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
pass
|
||||||
|
|
||||||
|
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):
|
||||||
|
var debug = true
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print("$ %s" % command)
|
||||||
|
|
||||||
|
var env = {}
|
||||||
|
env["EDITOR"] = game.cwd+"/scripts/fake-editor"
|
||||||
|
env["TEST"] = "hi"
|
||||||
|
|
||||||
|
var hacky_command = ""
|
||||||
|
for variable in env:
|
||||||
|
hacky_command += "export %s='%s';" % [variable, env[variable]]
|
||||||
|
hacky_command += "cd '%s';" % _cwd
|
||||||
|
hacky_command += command
|
||||||
|
|
||||||
|
var output = game.exec("/bin/sh", ["-c", hacky_command])
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print(output)
|
||||||
|
|
||||||
|
return output
|
|
@ -7,6 +7,7 @@ var history_position = 0
|
||||||
|
|
||||||
onready var input = $Control/Input
|
onready var input = $Control/Input
|
||||||
onready var output = $Control/Output
|
onready var output = $Control/Output
|
||||||
|
onready var repo = $"../Repositories/ActiveRepository"
|
||||||
|
|
||||||
func _input(event):
|
func _input(event):
|
||||||
if history.size() > 0:
|
if history.size() > 0:
|
||||||
|
@ -32,9 +33,8 @@ func send_command(command):
|
||||||
thread.start(self, "run_command_in_a_thread", command)
|
thread.start(self, "run_command_in_a_thread", command)
|
||||||
|
|
||||||
func run_command_in_a_thread(command):
|
func run_command_in_a_thread(command):
|
||||||
var o = game.sh(command, "/tmp/active")
|
var o = repo.shell.run(command)
|
||||||
|
|
||||||
input.text = ""
|
input.text = ""
|
||||||
output.text = output.text + "$ " + command + "\n" + o
|
output.text = output.text + "$ " + command + "\n" + o
|
||||||
#output.scroll_vertical = 999999
|
repo.update_everything() # FIXME
|
||||||
$"../Repositories/ActiveRepository".update_everything() # FIXME
|
|
||||||
|
|
Loading…
Reference in a new issue