commit 4c9f07d2063becda9ce6e71821b6b105ff065236
parent 36509ffbc0a48ff70d86fd4343290b755689e5e9
Author: phoebos <ben@bvnf.space>
Date: Tue, 18 Jul 2023 02:54:32 +0100
add install
Diffstat:
3 files changed, 129 insertions(+), 2 deletions(-)
diff --git a/bliss/init.lua b/bliss/init.lua
@@ -3,7 +3,7 @@ local cwd = (...):gsub("%.init$", "")
local M = {}
-- merge these into the toplevel bliss module
-local names = {"utils", "search", "list", "pkg", "download", "checksum", "build"}
+local names = {"utils", "search", "list", "pkg", "download", "checksum", "build", "install"}
for _, name in ipairs(names) do
local t = require(cwd .. "." .. name)
for k, v in pairs(t) do
diff --git a/bliss/install.lua b/bliss/install.lua
@@ -0,0 +1,100 @@
+local archive = require "bliss.archive"
+local utils = require "bliss.utils"
+local pkg = require "bliss.pkg"
+local libgen = require "posix.libgen"
+local sys_stat = require "posix.sys.stat"
+
+local function install(env, arg)
+ if #arg == 0 then end
+
+ for _,p in ipairs(arg) do
+ local pkgname, tarfile
+ if string.match(p, "%.tar%.") then
+ -- p is a path to a tarball.
+ if not sys_stat.stat(p) then
+ utils.die("File '" .. p .. "' does not exist")
+ end
+ pkgname = string.match(p, ".*/(.-)@")
+ tarfile = p
+ else
+ local path = utils.shallowcopy(env.PATH)
+ table.insert(path, env.sys_db)
+
+ local repo_dir = pkg.find(p, path)
+ local version = pkg.find_version(p, repo_dir)
+ tarfile = pkg.iscached(env, p, version)
+ if not tarfile then
+ utils.die(p, "Not yet built")
+ end
+ pkgname = p
+ end
+
+ utils.trap_off(env)
+ utils.mkcd(env.tar_dir .. "/" .. pkgname)
+
+ archive.tar_extract(tarfile)
+ local tar_man = env.tar_dir.."/"..pkgname.."/"..env.pkg_db.."/"..pkgname.."/manifest"
+ if not sys_stat.stat(tar_man) then
+ utils.die("Not a valid KISS package (no manifest file)")
+ end
+
+ if env.FORCE ~= 1 then
+ -- check installable
+ end
+
+ -- TODO: alternatives
+
+ utils.log(pkgname, "Installing package ("..libgen.basename(tarfile)..")")
+
+ local tar_manifest = pkg.read_lines(tar_man)
+ for k,v in ipairs(tar_manifest) do tar_manifest[k] = v[1] end
+ table.sort(tar_manifest)
+
+ -- TODO: diff manifests, remove old files, verify new files
+
+ -- PWD must contain the files
+ for _, file in ipairs(tar_manifest) do
+ local _file = env.ROOT .. file
+
+ if file:sub(-1) == "/" then
+ -- Directory
+ if not sys_stat.stat(_file) then
+ local mode = sys_stat.stat("./"..file).st_mode
+ local c,msg = sys_stat.mkdir(_file, mode)
+ if not c then utils.die("mkdir "..msg) end
+ end
+ else
+ if file:match("^/etc/") then
+ -- TODO: compare checksums
+ warn(pkgname, "saving "..file.." as "..file..".new")
+ _file = _file .. ".new"
+ end
+
+ local dirname = libgen.dirname(_file)
+ local sb = sys_stat.stat(_file)
+ if sb and sys_stat.S_ISLNK(sb.st_mode) ~= 0 then
+ if not utils.run("cp", {"-fP", "./"..file, dirname .. "/."}) then os.exit(false) end
+ else
+ local _tmp_file = dirname.."/__bliss-tmp-"..pkgname.."-"..libgen.basename(file).."-"..env.PID
+
+ if not utils.run("cp", {"-fP", "./"..file, _tmp_file}) or
+ not utils.run("mv", {"-f", _tmp_file, _file}) then
+ -- run pkg_clean
+ getmetatable(env.atexit).__gc()
+
+ utils.log(pkgname, "Failed to install package", "ERROR")
+ utils.die(pkgname, "Filesystem now dirty, manual repair needed.")
+ end
+ end
+ end
+ end
+
+ utils.trap_on(env)
+ utils.log(pkgname, "Installed successfully")
+ end
+end
+
+local M = {
+ install = install,
+}
+return M
diff --git a/main.lua b/main.lua
@@ -11,7 +11,7 @@ local function usage()
bliss.log("build Build packages")
bliss.log("checksum Generate checksums")
bliss.log("download Download sources")
- --bliss.log("install Install packages")
+ bliss.log("install Install packages")
bliss.log("list List installed packages")
--bliss.log("remove Remove packages")
bliss.log("search Search for packages")
@@ -43,6 +43,33 @@ local function args(env, arg)
local char = string.sub(arg[1], 1, 1)
if arg[1] == "upgrade" then char = "U" end
+ if char == "i" or char == "a" or char == "r" then
+ local user = bliss.am_not_owner(env.ROOT .. "/")
+ if user then
+ local newarg = {
+ "env",
+ "LOGNAME="..user,
+ "HOME="..os.getenv("HOME"),
+ "XDG_CACHE_HOME="..(os.getenv("XDG_CACHE_HOME") or ""),
+ "KISS_COMPRESS="..env.COMPRESS,
+ "KISS_PATH="..table.concat(env.PATH, ":"),
+ "KISS_FORCE="..env.FORCE,
+ "KISS_ROOT="..env.ROOT,
+ "KISS_CHOICE="..env.CHOICE,
+ "KISS_COLOR="..env.COLOR,
+ "KISS_TMPDIR="..env.TMPDIR,
+ "KISS_PID="..env.PID,
+ "_KISS_LVL="..env._LVL,
+ }
+ table.move(arg, 0, #arg, #newarg+1, newarg)
+
+ bliss.trap_off(env)
+ bliss.as_user(env, user, newarg)
+ bliss.trap_on(env)
+ return
+ end
+ end
+
-- shift
table.remove(arg, 1)