diff --git a/kai/gitgud.lua b/kai/gitgud.lua new file mode 100644 index 0000000..2aa2d0f --- /dev/null +++ b/kai/gitgud.lua @@ -0,0 +1,156 @@ +--[[ + +Usages: +> gitgud sync +download file from repo + +> gitgud delete +delete downloaded file + +> gitgud +re-download all synced files + +> gitgud run +fetch and exec file from repo + +]] + +if not http then error("http is not enabled") end + +local function get(url) + local response, err = http.get(url) + if not response then + return nil, err + end + + local status, err = response.getResponseCode() + if status ~= 200 then + return nil, (status .. " " .. err) + end + + local result = response.readAll() + response.close() + return result +end + +local function ensure_dotlua(path) + if string.match(path, "%.lua$") then + return path + else + return path .. ".lua" + end +end + +local function gitea_url(path) + return "https://gitea.leafbla.de/dominic/turtles/raw/branch/master/".. path +end + +local function download_file(repo_path, local_path) + write("Downloading " .. repo_path .. " as " .. local_path .. "... ") + local result, err = get(gitea_url(repo_path)) + if not result then + print() + printError(err) + return false + end + + local f = fs.open(local_path, "w") + f.write(result) + f.close() + + print("OK") + return true +end + +-- keep track of downloaded files +local storage_path = ".gitgud" + +local storage = {} +if fs.exists(storage_path) then + local f = fs.open(storage_path, "r") + storage = textutils.unserialize(f.readAll()) + f.close() +end + +local function update_storage() + local f = fs.open(storage_path, "w") + f.write(textutils.serialize(storage)) + f.close() +end + +local args = {...} + +if #args == 0 then + + -- Lua being Lua, of course #storage won't work + local count = 0 + for _ in pairs(storage) do + count = count + 1 + end + + print("Syncing " .. count .. " files.") + + local success_count = 0 + for local_path, repo_path in pairs(storage) do + local success = download_file(repo_path, local_path) + if success then + success_count = success_count + 1 + end + end + + print("Done. " .. success_count .. " out of " .. count .. " files synced.") + +elseif args[1] == "sync" then + local usage = "gitgud sync " + local repo_path = args[2] or error(usage) + local local_path = args[3] or error(usage) + + repo_path = ensure_dotlua(repo_path) + local_path = ensure_dotlua(local_path) + + storage[local_path] = repo_path + update_storage() + + download_file(repo_path, local_path) + +elseif args[1] == "delete" then + local usage = "gitgud delete " + local local_path = args[2] or error(usage) + + local_path = ensure_dotlua(local_path) + + storage[local_path] = nil + update_storage() + + fs.delete(local_path) + +elseif args[1] == "run" then + local usage = "gitgud run [args...]" + local repo_path = args[2] or error(usage) + + repo_path = ensure_dotlua(repo_path) + + write("Downloading " .. repo_path .. "... ") + local result, err = get(gitea_url(repo_path)) + if not result then + print() + printError(err) + else + print("OK") + end + + local func, err = load(result, repo_path, "t", _ENV) + if not func then + printError(err) + return + end + local success, err = pcall(func, select(3, ...)) + if not success then + printError(err) + end + +else + print("Unknown command " .. args[1]) + print("Try \"sync\", \"delete\" or \"run\"") + +end \ No newline at end of file diff --git a/kai/lib.lua b/kai/lib.lua new file mode 100644 index 0000000..42e3ca4 --- /dev/null +++ b/kai/lib.lua @@ -0,0 +1,92 @@ +-- Do not lose state when reset (chunkloading etc) +state = (function () + local path = ".state" + local state_table = {} + + if fs.exists(path) then + local f = fs.open(path, "r") + state_table = textutils.unserialize(f.readAll()) + f.close() + end + + return setmetatable({}, { + __index = state_table, + + __newindex = function(self, k, v) + rawset(state_table, k, v) + local f = fs.open(path, "w") + f.write(textutils.serialize(state_table)) + f.close() + end, + }) +end)() + +if state.x == nil or state.y == nil or state.z == nil or state.o == nil then + printError("[lib] position is not set") + printError("[lib] defaulting to 0, 0, 0, +z") + state.x = 0 + state.y = 0 + state.z = 0 + state.o = 0 +end + +--[[ + orientation: + 0 = South (+z) + 1 = West (-x) + 2 = North (-z) + 3 = East (+x) +]] + +function getOrientation() + return ({"+z", "-x", "-z", "+x"})[1 + state.o] +end + +function move(raw_move, position_update) + return function() + success, err = raw_move() + if not success then + return false, err + end + position_update() + return true + end +end + +return { + state = state, + + getOrientation = getOrientation, + + fwd = move(turtle.forward, function() + if state.o == 1 or state.o == 3 then + state.x = state.x + ((state.o == 1) and -1 or 1) + elseif state.o == 0 or state.o == 2 then + state.z = state.z + ((state.o == 2) and -1 or 1) + end + end), + + back = move(turtle.back, function() + if state.o == 1 or state.o == 3 then + state.x = state.x + ((state.o == 1 and 1 or -1)) + elseif state.o == 0 or state.o == 2 then + state.z = state.z + ((state.o == 2) and 1 or -1) + end + end), + + up = move(turtle.up, function() + state.y = state.y + 1 + end), + + down = move(turtle.down, function() + state.y = state.y - 1 + end), + + left = move(turtle.turnLeft, function() + state.o = (state.o - 1) % 4 + end), + + right = move(turtle.turnRight, function() + state.o = (state.o + 1) % 4 + end), +} \ No newline at end of file