1 changed files with 152 additions and 0 deletions
@ -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…
issues.context.reference_issue