bliss

KISS in Lua
git clone git://bvnf.space/bliss.git
Log | Files | Refs | README | LICENSE

commit 4c9f07d2063becda9ce6e71821b6b105ff065236
parent 36509ffbc0a48ff70d86fd4343290b755689e5e9
Author: phoebos <ben@bvnf.space>
Date:   Tue, 18 Jul 2023 02:54:32 +0100

add install

Diffstat:
Mbliss/init.lua | 2+-
Abliss/install.lua | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmain.lua | 29++++++++++++++++++++++++++++-
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)