|
|
@@ -1,10 +1,13 @@ |
|
|
|
local serial = require "serialization" |
|
|
|
local dl = require "download" |
|
|
|
local mtar = require "libmtar" |
|
|
|
local pkg = {} |
|
|
|
pkg.cfgPath = "/boot/cfg/pkg" |
|
|
|
pkg.sourcePath = pkg.cfgPath .. "/sources.cfg" |
|
|
|
pkg.installedPath = pkg.cfgPath .. "/installed.cfg" |
|
|
|
require("pkgfs") |
|
|
|
local w, lz16 = pcall(require,"liblz16") |
|
|
|
if not w then lz16 = nil end |
|
|
|
require "pkgfs" |
|
|
|
|
|
|
|
local function getSources() |
|
|
|
local f = io.open(pkg.sourcePath,"rb") |
|
|
@@ -54,6 +57,31 @@ end |
|
|
|
local function deactivatePackage(path) |
|
|
|
require("pkgfs").remove(path) |
|
|
|
end |
|
|
|
local function fnormalize(s) |
|
|
|
return table.concat(fs.segments(s),"/") |
|
|
|
end |
|
|
|
local function installSystemPackage(path,comp) |
|
|
|
local f |
|
|
|
if comp and lz16 then |
|
|
|
f = lz16.open(path,"rb") |
|
|
|
else |
|
|
|
f = io.open(path,"rb") |
|
|
|
end |
|
|
|
for fname, read, size in mtar.iter(f) do |
|
|
|
local opath = "/boot/"..fnormalize(fname) |
|
|
|
print(opath..": "..tostring(size)) |
|
|
|
fs.makeDirectory(opath:match("(.+)/[^/]+")) |
|
|
|
local of = io.open(opath,"wb") |
|
|
|
if not of then error("unable to open "..opath.." for writing") end |
|
|
|
local tmp |
|
|
|
repeat |
|
|
|
tmp = read(2048) or "" |
|
|
|
of:write(tmp) |
|
|
|
until not tmp or tmp:len() < 1 |
|
|
|
of:close() |
|
|
|
end |
|
|
|
return true |
|
|
|
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() |
|
|
@@ -76,7 +104,7 @@ function pkg.update() -- Re-download cached repository indexes. |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
function pkg.list(filter) -- string -- -- Print a list of available packages matching *filter*. |
|
|
|
function pkg.list(filter,installed) -- string boolean -- -- Print a list of available packages matching *filter*, optionally filtering to only installed packages if *installed* is set. |
|
|
|
filter = filter or "" |
|
|
|
local pkglist = {} |
|
|
|
for repo,_ in pairs(getSources()) do |
|
|
@@ -88,7 +116,8 @@ function pkg.list(filter) -- string -- -- Print a list of available packages mat |
|
|
|
end |
|
|
|
end |
|
|
|
for k,v in pairs(pkglist) do |
|
|
|
print(string.format("%s/%s\n %s",v.repo,k,v.description)) |
|
|
|
if v.system then io.write("\27[31m") end |
|
|
|
print(string.format("%s/%s: %s\27[0m\n %s\n Authors: %s",v.repo,k,v.name,v.description,v.authors)) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
@@ -104,25 +133,30 @@ function pkg.getMeta(pkgname) -- string -- table -- Returns the metadata for a t |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
function pkg.get(pkgname,auto) -- string boolean -- boolean -- Downloads and mounts a package, identified as *pkgname*, onto the pkgfs. |
|
|
|
function pkg.get(pkgname,auto) -- string boolean -- boolean -- Downloads and mounts a package, identified as *pkgname,* onto the pkgfs. Setting *auto* will flag the package as automatically installed; this is used for dependencies. |
|
|
|
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) |
|
|
|
pkg.get(v,true) |
|
|
|
end |
|
|
|
end |
|
|
|
dl(pkginfo.repository.path.."/"..pkginfo.filename,"/boot/pkg/"..pkginfo.filename) |
|
|
|
local installed = getInstalled() |
|
|
|
installed[pkgname] = pkginfo |
|
|
|
saveInstalled(installed) |
|
|
|
if pkginfo.system then |
|
|
|
local rv = installSystemPackage("/boot/pkg/"..pkginfo.filename,pkginfo.compressed) |
|
|
|
fs.remove("/boot/pkg/"..pkginfo.filename) |
|
|
|
return rv |
|
|
|
end |
|
|
|
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. |
|
|
|
function pkg.upgrade(force) -- 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() |
|
|
@@ -130,13 +164,10 @@ function pkg.upgrade(force) -- boolean -- boolean -- Upgrades all packages on th |
|
|
|
for pkgname,pkginfo in pairs(getRepoMeta(repo)) do |
|
|
|
if installed[pkgname] and pkginfo.version ~= installed[pkgname].version or force then |
|
|
|
pkg.remove(pkgname) |
|
|
|
dl(info.path.."/"..pkginfo.filename,"/boot/pkg/"..pkginfo.filename) |
|
|
|
installed[pkgname] = pkg |
|
|
|
pcall(activatePackage,"/boot/pkg/"..pkginfo.filename,pkginfo.compressed) |
|
|
|
pkg.get(pkgname,pkginfo.auto) |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
saveInstalled(installed) |
|
|
|
end |
|
|
|
|
|
|
|
function pkg.remove(pkgname) -- string -- boolean -- Remove the package *pkgname* from the pkgfs and package directory. |
|
|
@@ -145,6 +176,11 @@ function pkg.remove(pkgname) -- string -- boolean -- Remove the package *pkgname |
|
|
|
if not pkginfo then return true end |
|
|
|
pcall(deactivatePackage,"/boot/pkg/"..pkginfo.filename) |
|
|
|
fs.remove("/boot/pkg/"..pkginfo.filename) |
|
|
|
if pkginfo.system then |
|
|
|
for k,v in pairs(pkginfo.files) do |
|
|
|
fs.remove(v) |
|
|
|
end |
|
|
|
end |
|
|
|
installed[pkgname] = nil |
|
|
|
saveInstalled(installed) |
|
|
|
return true |
|
|
|