added the pkgman package manager library
This commit is contained in:
parent
c1fcfd652e
commit
360bb88ac3
152
lib/pkgman.lua
Normal file
152
lib/pkgman.lua
Normal file
@ -0,0 +1,152 @@
|
||||
local serial = require "serialization"
|
||||
local dl = require "download"
|
||||
local pkg = {}
|
||||
pkg.cfgPath = "/boot/cfg/pkg"
|
||||
pkg.sourcePath = pkg.cfgPath .. "/sources.cfg"
|
||||
pkg.installedPath = pkg.cfgPath .. "/installed.cfg"
|
||||
|
||||
local function getSources()
|
||||
local f = io.open(pkg.sourcePath,"rb")
|
||||
if not f then return {} end
|
||||
local c = f:read("*a")
|
||||
f:close()
|
||||
return serial.unserialize(c)
|
||||
end
|
||||
local function saveSources(t)
|
||||
fs.makeDirectory(pkg.cfgPath)
|
||||
local f = io.open(pkg.sourcePath,"wb")
|
||||
f:write(serial.serialize(t))
|
||||
f:close()
|
||||
end
|
||||
|
||||
local function getInstalled()
|
||||
local f = io.open(pkg.installedPath,"rb")
|
||||
if not f then return {} end
|
||||
local c = f:read("*a")
|
||||
f:close()
|
||||
return serial.unserialize(c)
|
||||
end
|
||||
local function saveInstalled(t)
|
||||
fs.makeDirectory(pkg.cfgPath)
|
||||
local f = io.open(pkg.installedPath,"wb")
|
||||
if not f then return false end
|
||||
f:write(serial.serialize(t))
|
||||
f:close()
|
||||
end
|
||||
|
||||
local function getRepoMeta(repo)
|
||||
if not getSources()[repo].cache or not fs.exists("/boot/cfg/pkg/repo-"..repo..".cfg") then
|
||||
dl(getSources()[repo].path.."/packages.cfg","/boot/cfg/pkg/repo-"..repo..".cfg")
|
||||
end
|
||||
local f = io.open("/boot/cfg/pkg/repo-"..repo..".cfg","rb")
|
||||
local rt = serial.unserialize(f:read("*a"))
|
||||
f:close()
|
||||
if not getSources()[repo].cache then
|
||||
fs.remove("/boot/cfg/pkg/repo-"..repo..".cfg")
|
||||
end
|
||||
return rt
|
||||
end
|
||||
|
||||
local function activatePackage(path,compressed)
|
||||
require("pkgfs").add(path,compressed)
|
||||
end
|
||||
local function deactivatePackage(path)
|
||||
require("pkgfs").remove(path)
|
||||
end
|
||||
|
||||
function pkg.addRepo(name,path,cache) -- string string boolean -- boolean -- Adds a repository, referred to as *name*, to the list of package sources, with the remote path *path*. If *cache* is set, keep a local copy of the repository index.
|
||||
local sources = getSources()
|
||||
sources[name] = {path=path,cache=cache,name=name}
|
||||
saveSources(sources)
|
||||
end
|
||||
|
||||
function pkg.delRepo(name) -- string -- boolean -- Removes a repository from the list of repositories.
|
||||
local sources = getSources()
|
||||
sources[name] = nil
|
||||
saveSources(sources)
|
||||
end
|
||||
|
||||
function pkg.update() -- Re-download cached repository indexes.
|
||||
for repo,meta in pairs(getSources()) do
|
||||
fs.remove("/boot/cfg/pkg/repo-"..repo..".cfg")
|
||||
if meta.cache then
|
||||
getRepoMeta(repo)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function pkg.list(filter) -- string -- -- Print a list of available packages matching *filter*.
|
||||
filter = filter or ""
|
||||
local pkglist = {}
|
||||
for repo,_ in pairs(getSources()) do
|
||||
for pkg,meta in pairs(getRepoMeta(repo)) do
|
||||
if pkg:find(filter) or (pkg.meta or ""):find(filter) then
|
||||
meta.repo = repo
|
||||
pkglist[pkg] = meta
|
||||
end
|
||||
end
|
||||
end
|
||||
for k,v in pairs(pkglist) do
|
||||
print(string.format("%s/%s\n %s",v.repo,k,v.description))
|
||||
end
|
||||
end
|
||||
|
||||
function pkg.getMeta(pkgname) -- string -- table -- Returns the metadata for a the package specified in *pkgname*.
|
||||
print("Finding package "..pkgname)
|
||||
for repo,info in pairs(getSources()) do
|
||||
local pkg = getRepoMeta(repo)[pkgname]
|
||||
if pkg then
|
||||
print("Package "..pkgname.." located in repo "..repo.." at "..info.path)
|
||||
pkg.repository = info
|
||||
return pkg
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function pkg.get(pkgname,auto) -- string boolean -- boolean -- Downloads and mounts a package, identified as *pkgname*, onto the pkgfs.
|
||||
local pkginfo = pkg.getMeta(pkgname)
|
||||
if not pkginfo then error("unable to locate package "..pkgname) end
|
||||
pkginfo.manual = not auto
|
||||
fs.makeDirectory("/boot/pkg")
|
||||
for k,v in ipairs(pkginfo.dependencies or {}) do
|
||||
if not getInstalled()[v] then
|
||||
pkg.get(v)
|
||||
end
|
||||
end
|
||||
dl(pkginfo.repository.path.."/"..pkginfo.filename,"/boot/pkg/"..pkginfo.filename)
|
||||
local installed = getInstalled()
|
||||
installed[pkgname] = pkginfo
|
||||
saveInstalled(installed)
|
||||
pcall(activatePackage,"/boot/pkg/"..pkginfo.filename,pkginfo.compressed)
|
||||
return true
|
||||
end
|
||||
|
||||
function pkg.upgrade(force) -- boolean -- boolean -- Upgrades all packages on the system to the current version stored in the relevant repository. If *force* is set, re-download all packages.
|
||||
pkg.update()
|
||||
fs.makeDirectory("/boot/pkg")
|
||||
local installed = getInstalled()
|
||||
for repo,info in pairs(getSources()) do
|
||||
for pkgname,pkg in pairs(getRepoMeta(repo)) do
|
||||
if pkg.version ~= installed[pkgname].version or force then
|
||||
dl(info.path.."/"..pkg.filename,"/boot/pkg/"..pkg.filename)
|
||||
installed[pkgname] = pkg
|
||||
pcall(activatePackage,"/boot/pkg/"..pkg.filename,pkg.compressed)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
saveInstalled(installed)
|
||||
end
|
||||
|
||||
function pkg.remove(pkgname) -- string -- boolean -- Remove the package *pkgname* from the pkgfs and package directory.
|
||||
local installed = getInstalled()
|
||||
local pkginfo = installed[pkgname]
|
||||
if not pkginfo then error(pkgname .." not installed") end
|
||||
pcall(deactivatePackage,"/boot/pkg/"..pkginfo.filename)
|
||||
fs.remove("/boot/pkg/"..pkginfo.filename)
|
||||
installed[pkgname] = nil
|
||||
saveInstalled(installed)
|
||||
return true
|
||||
end
|
||||
|
||||
return pkg
|
Loading…
Reference in New Issue
Block a user