init
This commit is contained in:
commit
d46c11b3a8
|
@ -0,0 +1,12 @@
|
|||
local a={}local b="/ckg"local c=fs.combine(b,"cache")local d=fs.combine(c,"repos")local e=fs.combine(b,"config.txt")local f={"https://example.com/repo/packages.json"}local function g()if not fs.exists(e)then return{repos=f}end;local h=fs.open(e,"r")local i=textutils.unserialize(h.readAll())h.close()return i end;local function j(i)local h=fs.open(e,"w")h.write(textutils.serialize(i))h.close()end;local function k(i)if not fs.exists(d)then fs.makeDir(d)end;local l={}for m,n in ipairs(i.repos)do local o=fs.combine(d,"repo_"..m..".json")if fs.exists(o)then local h=fs.open(o,"r")local p=textutils.unserializeJSON(h.readAll())h.close()for q,r in pairs(p)do l[q]=r end else if http.checkURL(n)then print("Fetching index from "..n)local s=".pkg_tmp_repo.json"if fs.exists(s)then fs.delete(s)end;shell.run("wget",n,s)local h=fs.open(s,"r")local p=textutils.unserializeJSON(h.readAll())h.close()fs.delete(s)local t=fs.open(o,"w")t.write(textutils.serializeJSON(p))t.close()for q,r in pairs(p)do l[q]=r end else print("Warning: cannot reach repo "..n)end end end;return l end;local function u(v,w,x)for y,z in ipairs(w)do local n=v.."/"..z;local A=fs.combine(x,z)local B=fs.getDir(A)if not fs.exists(B)then fs.makeDir(B)end;if fs.exists(A)then fs.delete(A)end;shell.run("wget",n,A)end end;local function C(q,D,E)if E[q]then return end;local F=D[q]if not F then error("Package not found: "..q)end;if F.dependencies then for y,G in ipairs(F.dependencies)do C(G,D,E)end end;local x=fs.combine(b,q)if fs.exists(x)then print("Already installed: "..q)E[q]=true;return end;if not fs.exists(c)then fs.makeDir(c)end;local H=fs.combine(c,q)if fs.exists(H)then print("Installing "..q.." from cache...")fs.copy(H,x)else print("Downloading "..q.."...")fs.makeDir(H)u(F.base_url,F.files,H)fs.copy(H,x)end;print("Installed "..q)E[q]=true end;function CKG.install(q)local i=g()local D=k(i)C(q,D,{})end;function CKG.fetch(q)local i=g()local D=k(i)local F=D[q]if not F then error("Package not found: "..q)end;if not fs.exists(c)then fs.makeDir(c)end;local H=fs.combine(c,q)if fs.exists(H)then fs.delete(H)end;fs.makeDir(H)u(F.base_url,F.files,H)print("Fetched "..q.." to cache")end;function CKG.remove(q)local x=fs.combine(b,q)if fs.exists(x)then fs.delete(x)print("Removed "..q)else print("Package not installed: "..q)end end;function CKG.list()if not fs.exists(b)then print("No packages installed.")return end;local D=fs.list(b)for y,F in ipairs(D)do if F~="cache"and F~="config.txt"then print(F)end end end;function CKG.add_repo(n)local i=g()table.insert(i.repos,n)j(i)print("Repository added: "..n)end;function CKG.list_repos()local i=g()for y,n in ipairs(i.repos)do print(n)end end;function CKG.clear_repos()j({repos=f})print("Repositories reset to default")end;function CKG.clear_cache()if fs.exists(c)then fs.delete(c)print("Cache cleared")else print("Cache is already empty")end end;function CKG.update()if fs.exists(d)then fs.delete(d)end;fs.makeDir(d)local i=g()for m,n in ipairs(i.repos)do if http.checkURL(n)then print("Updating index from "..n)local s=".pkg_tmp_repo.json"if fs.exists(s)then fs.delete(s)end;shell.run("wget",n,s)local h=fs.open(s,"r")local p=textutils.unserializeJSON(h.readAll())h.close()fs.delete(s)local o=fs.combine(d,"repo_"..m..".json")local t=fs.open(o,"w")t.write(textutils.serializeJSON(p))t.close()else print("Warning: cannot reach repo "..n)end end;print("Repository indexes updated!")end;local I={...}local J=I[1]if J=="install"then CKG.install(I[2])elseif J=="remove"then CKG.remove(I[2])elseif J=="list"then CKG.list()elseif J=="fetch"then CKG.fetch(I[2])elseif J=="clear-cache"then CKG.clear_cache()elseif J=="add-repo"then CKG.add_repo(I[2])elseif J=="list-repos"then CKG.list_repos()elseif J=="clear-repos"then CKG.clear_repos()elseif J=="update"then CKG.update()else print([[
|
||||
Usage:
|
||||
ckg install <name> Install a package
|
||||
ckg remove <name> Remove a package
|
||||
ckg list List installed packages
|
||||
ckg fetch <name> Download package to cache
|
||||
ckg clear-cache Clear downloaded packages cache
|
||||
ckg add-repo <url> Add a new repository
|
||||
ckg list-repos List repositories
|
||||
ckg clear-repos Reset repositories to default
|
||||
ckg update Refresh package indexes
|
||||
]])end
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
--[[
|
||||
My ComputerCraft Package Manager
|
||||
Supports multiple repositories, dependency resolution, index and package caching.
|
||||
]]
|
||||
|
||||
local PKG = {}
|
||||
|
||||
local INSTALL_DIR = "/ckg"
|
||||
local CACHE_DIR = fs.combine(INSTALL_DIR, "cache")
|
||||
local REPO_CACHE_DIR = fs.combine(CACHE_DIR, "repos")
|
||||
local CONFIG_FILE = fs.combine(INSTALL_DIR, "config.txt")
|
||||
local DEFAULT_REPOS = {
|
||||
"https://example.com/repo/packages.json"
|
||||
}
|
||||
|
||||
local function load_config()
|
||||
if not fs.exists(CONFIG_FILE) then
|
||||
return { repos = DEFAULT_REPOS }
|
||||
end
|
||||
local f = fs.open(CONFIG_FILE, "r")
|
||||
local cfg = textutils.unserialize(f.readAll())
|
||||
f.close()
|
||||
return cfg
|
||||
end
|
||||
|
||||
local function save_config(cfg)
|
||||
local f = fs.open(CONFIG_FILE, "w")
|
||||
f.write(textutils.serialize(cfg))
|
||||
f.close()
|
||||
end
|
||||
|
||||
local function fetch_package_lists(cfg)
|
||||
if not fs.exists(REPO_CACHE_DIR) then fs.makeDir(REPO_CACHE_DIR) end
|
||||
local all = {}
|
||||
|
||||
for i, url in ipairs(cfg.repos) do
|
||||
local cached_file = fs.combine(REPO_CACHE_DIR, "repo_" .. i .. ".json")
|
||||
|
||||
if fs.exists(cached_file) then
|
||||
local f = fs.open(cached_file, "r")
|
||||
local data = textutils.unserializeJSON(f.readAll())
|
||||
f.close()
|
||||
for name, info in pairs(data) do
|
||||
all[name] = info
|
||||
end
|
||||
else
|
||||
if http.checkURL(url) then
|
||||
print("Fetching index from " .. url)
|
||||
local tmp = ".pkg_tmp_repo.json"
|
||||
if fs.exists(tmp) then fs.delete(tmp) end
|
||||
shell.run("wget", url, tmp)
|
||||
local f = fs.open(tmp, "r")
|
||||
local data = textutils.unserializeJSON(f.readAll())
|
||||
f.close()
|
||||
fs.delete(tmp)
|
||||
|
||||
local cache = fs.open(cached_file, "w")
|
||||
cache.write(textutils.serializeJSON(data))
|
||||
cache.close()
|
||||
|
||||
for name, info in pairs(data) do
|
||||
all[name] = info
|
||||
end
|
||||
else
|
||||
print("Warning: cannot reach repo " .. url)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return all
|
||||
end
|
||||
|
||||
local function install_files(base_url, files, install_path)
|
||||
for _, file in ipairs(files) do
|
||||
local url = base_url .. "/" .. file
|
||||
local path = fs.combine(install_path, file)
|
||||
local dir = fs.getDir(path)
|
||||
if not fs.exists(dir) then fs.makeDir(dir) end
|
||||
if fs.exists(path) then fs.delete(path) end
|
||||
shell.run("wget", url, path)
|
||||
end
|
||||
end
|
||||
|
||||
local function install_single(name, list, installed)
|
||||
if installed[name] then return end
|
||||
local pkg = list[name]
|
||||
if not pkg then
|
||||
error("Package not found: " .. name)
|
||||
end
|
||||
|
||||
if pkg.dependencies then
|
||||
for _, dep in ipairs(pkg.dependencies) do
|
||||
install_single(dep, list, installed)
|
||||
end
|
||||
end
|
||||
|
||||
local install_path = fs.combine(INSTALL_DIR, name)
|
||||
if fs.exists(install_path) then
|
||||
print("Already installed: " .. name)
|
||||
installed[name] = true
|
||||
return
|
||||
end
|
||||
|
||||
if not fs.exists(CACHE_DIR) then fs.makeDir(CACHE_DIR) end
|
||||
local cache_path = fs.combine(CACHE_DIR, name)
|
||||
|
||||
if fs.exists(cache_path) then
|
||||
print("Installing " .. name .. " from cache...")
|
||||
fs.copy(cache_path, install_path)
|
||||
else
|
||||
print("Downloading " .. name .. "...")
|
||||
fs.makeDir(cache_path)
|
||||
install_files(pkg.base_url, pkg.files, cache_path)
|
||||
fs.copy(cache_path, install_path)
|
||||
end
|
||||
|
||||
print("Installed " .. name)
|
||||
installed[name] = true
|
||||
end
|
||||
|
||||
function CKG.install(name)
|
||||
local cfg = load_config()
|
||||
local list = fetch_package_lists(cfg)
|
||||
install_single(name, list, {})
|
||||
end
|
||||
|
||||
function CKG.fetch(name)
|
||||
local cfg = load_config()
|
||||
local list = fetch_package_lists(cfg)
|
||||
local pkg = list[name]
|
||||
if not pkg then
|
||||
error("Package not found: " .. name)
|
||||
end
|
||||
if not fs.exists(CACHE_DIR) then fs.makeDir(CACHE_DIR) end
|
||||
local cache_path = fs.combine(CACHE_DIR, name)
|
||||
if fs.exists(cache_path) then fs.delete(cache_path) end
|
||||
fs.makeDir(cache_path)
|
||||
install_files(pkg.base_url, pkg.files, cache_path)
|
||||
print("Fetched " .. name .. " to cache")
|
||||
end
|
||||
|
||||
function CKG.remove(name)
|
||||
local install_path = fs.combine(INSTALL_DIR, name)
|
||||
if fs.exists(install_path) then
|
||||
fs.delete(install_path)
|
||||
print("Removed " .. name)
|
||||
else
|
||||
print("Package not installed: " .. name)
|
||||
end
|
||||
end
|
||||
|
||||
function CKG.list()
|
||||
if not fs.exists(INSTALL_DIR) then
|
||||
print("No packages installed.")
|
||||
return
|
||||
end
|
||||
local list = fs.list(INSTALL_DIR)
|
||||
for _, pkg in ipairs(list) do
|
||||
if pkg ~= "cache" and pkg ~= "config.txt" then
|
||||
print(pkg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CKG.add_repo(url)
|
||||
local cfg = load_config()
|
||||
table.insert(cfg.repos, url)
|
||||
save_config(cfg)
|
||||
print("Repository added: " .. url)
|
||||
end
|
||||
|
||||
function CKG.list_repos()
|
||||
local cfg = load_config()
|
||||
for _, url in ipairs(cfg.repos) do
|
||||
print(url)
|
||||
end
|
||||
end
|
||||
|
||||
function CKG.clear_repos()
|
||||
save_config({ repos = DEFAULT_REPOS })
|
||||
print("Repositories reset to default")
|
||||
end
|
||||
|
||||
function CKG.clear_cache()
|
||||
if fs.exists(CACHE_DIR) then
|
||||
fs.delete(CACHE_DIR)
|
||||
print("Cache cleared")
|
||||
else
|
||||
print("Cache is already empty")
|
||||
end
|
||||
end
|
||||
|
||||
function CKG.update()
|
||||
if fs.exists(REPO_CACHE_DIR) then fs.delete(REPO_CACHE_DIR) end
|
||||
fs.makeDir(REPO_CACHE_DIR)
|
||||
|
||||
local cfg = load_config()
|
||||
for i, url in ipairs(cfg.repos) do
|
||||
if http.checkURL(url) then
|
||||
print("Updating index from " .. url)
|
||||
local tmp = ".pkg_tmp_repo.json"
|
||||
if fs.exists(tmp) then fs.delete(tmp) end
|
||||
shell.run("wget", url, tmp)
|
||||
local f = fs.open(tmp, "r")
|
||||
local data = textutils.unserializeJSON(f.readAll())
|
||||
f.close()
|
||||
fs.delete(tmp)
|
||||
|
||||
local cached_file = fs.combine(REPO_CACHE_DIR, "repo_" .. i .. ".json")
|
||||
local cache = fs.open(cached_file, "w")
|
||||
cache.write(textutils.serializeJSON(data))
|
||||
cache.close()
|
||||
else
|
||||
print("Warning: cannot reach repo " .. url)
|
||||
end
|
||||
end
|
||||
|
||||
print("Repository indexes updated!")
|
||||
end
|
||||
|
||||
-- CLI interface
|
||||
local args = { ... }
|
||||
local cmd = args[1]
|
||||
|
||||
if cmd == "install" then
|
||||
CKG.install(args[2])
|
||||
elseif cmd == "remove" then
|
||||
CKG.remove(args[2])
|
||||
elseif cmd == "list" then
|
||||
CKG.list()
|
||||
elseif cmd == "fetch" then
|
||||
CKG.fetch(args[2])
|
||||
elseif cmd == "clear-cache" then
|
||||
CKG.clear_cache()
|
||||
elseif cmd == "add-repo" then
|
||||
CKG.add_repo(args[2])
|
||||
elseif cmd == "list-repos" then
|
||||
CKG.list_repos()
|
||||
elseif cmd == "clear-repos" then
|
||||
CKG.clear_repos()
|
||||
elseif cmd == "update" then
|
||||
CKG.update()
|
||||
else
|
||||
print([[
|
||||
Usage:
|
||||
ckg install <name> Install a package
|
||||
ckg remove <name> Remove a package
|
||||
ckg list List installed packages
|
||||
ckg fetch <name> Download package to cache
|
||||
ckg clear-cache Clear downloaded packages cache
|
||||
ckg add-repo <url> Add a new repository
|
||||
ckg list-repos List repositories
|
||||
ckg clear-repos Reset repositories to default
|
||||
ckg update Refresh package indexes
|
||||
]])
|
||||
end
|
Loading…
Reference in New Issue