Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Downloads StargateControl files from GitHub into disk/*.lua (or disk2/..., per file_list)
- if not http then
- error("HTTP API is disabled")
- end
- local BASE_URL = "https://raw.githubusercontent.com/APasz/StargateControl/main/"
- local COMMITS_API_URL = "https://api.github.com/repos/APasz/StargateControl/commits/main"
- local DEFAULT_TARGET_DIR = "disk"
- local FILE_LIST_PATH = "sync/file_list.lua"
- local UPDATER_PATH = "sync/updater.lua"
- local args = { ... }
- local self_only = args[1] == "self" or args[1] == "manifest"
- local function download(url, headers)
- local res, err = http.get(url, headers)
- if not res then
- return nil, err
- end
- local content = res.readAll()
- res.close()
- return content, nil
- end
- local function fetch_latest_commit_name()
- local parse_json = textutils.unserialiseJSON
- if not parse_json then
- return nil, "JSON parser unavailable"
- end
- local headers = {
- ["User-Agent"] = "StargateControlUpdater",
- Accept = "application/vnd.github+json",
- }
- local content, err = download(COMMITS_API_URL, headers)
- if not content then
- return nil, err
- end
- local ok, data = pcall(parse_json, content)
- if not ok or type(data) ~= "table" then
- return nil, "Unexpected API response"
- end
- local message = data.commit and data.commit.message
- if type(message) ~= "string" then
- return nil, "Commit message unavailable"
- end
- local subject = message:match("([^\r\n]+)") or message
- return subject
- end
- local function load_file_list()
- local content, err = download(BASE_URL .. FILE_LIST_PATH)
- if not content then
- error("Failed to download file list: " .. tostring(err), 0)
- end
- local chunk, load_err = load(content, FILE_LIST_PATH, "t", {})
- if not chunk then
- error("Unable to parse file list: " .. tostring(load_err), 0)
- end
- local ok, result = pcall(chunk)
- if not ok then
- error("Failed to load file list: " .. tostring(result), 0)
- end
- if type(result) ~= "table" then
- error("Invalid file list contents", 0)
- end
- return result
- end
- local function download_file(path, destination, target_dir)
- local url = BASE_URL .. path
- local content, err = download(url)
- if not content then
- print("Failed; " .. path .. ": " .. tostring(err))
- return false
- end
- local base_dir = target_dir or DEFAULT_TARGET_DIR
- local target_path = destination or fs.combine(base_dir, path)
- local dir = fs.getDir(target_path)
- if dir and dir ~= "" then
- fs.makeDir(dir)
- end
- local f = fs.open(target_path, "w")
- if not f then
- print("Failed to open " .. target_path .. " for writing.")
- return false
- end
- f.write(content)
- f.close()
- print("Saved: " .. target_path)
- return true
- end
- local function collect_files(file_list)
- local files = {}
- local seen = {}
- for _, scope_files in pairs(file_list) do
- for _, file in ipairs(scope_files) do
- local path = file.git
- if path ~= FILE_LIST_PATH then
- local disk = file.disk
- local key = ("%s:%s"):format(disk or "", path)
- if not seen[key] then
- files[#files + 1] = { path = path, disk = disk }
- seen[key] = true
- end
- end
- end
- end
- return files
- end
- local function validate_target_dirs(files)
- local missing = {}
- if not fs.exists(DEFAULT_TARGET_DIR) or not fs.isDir(DEFAULT_TARGET_DIR) then
- missing[DEFAULT_TARGET_DIR] = true
- end
- for _, file in ipairs(files) do
- local base_dir = file.disk or DEFAULT_TARGET_DIR
- if not fs.exists(base_dir) or not fs.isDir(base_dir) then
- missing[base_dir] = true
- end
- end
- if next(missing) then
- local dirs = {}
- for dir in pairs(missing) do
- dirs[#dirs + 1] = dir
- end
- error("Missing target disk directories: " .. table.concat(dirs, ", "), 0)
- end
- end
- local function resolve_disk_for_file(file)
- return file.disk or DEFAULT_TARGET_DIR
- end
- local function download_files(files)
- local ok = true
- for _, file in ipairs(files) do
- local disk = resolve_disk_for_file(file)
- ok = download_file(file.path, nil, disk) and ok
- end
- return ok
- end
- local commit_name, commit_err = fetch_latest_commit_name()
- local success = true
- if self_only then
- validate_target_dirs({})
- success = download_file(FILE_LIST_PATH, nil, DEFAULT_TARGET_DIR) and success
- else
- local file_list = load_file_list()
- local files = collect_files(file_list)
- validate_target_dirs(files)
- success = download_file(FILE_LIST_PATH, nil, DEFAULT_TARGET_DIR) and success
- success = download_files(files) and success
- end
- success = download_file(UPDATER_PATH, "updater.lua") and success
- if success then
- print("Done!")
- else
- print("Done (with errors; see above)")
- end
- if commit_name then
- print(commit_name)
- elseif commit_err then
- print("Latest commit unavailable: " .. tostring(commit_err))
- end
Advertisement
Add Comment
Please, Sign In to add comment