summaryrefslogtreecommitdiffstats
path: root/apk-model.lua
diff options
context:
space:
mode:
Diffstat (limited to 'apk-model.lua')
-rw-r--r--apk-model.lua219
1 files changed, 207 insertions, 12 deletions
diff --git a/apk-model.lua b/apk-model.lua
index 66a9a30..e23ecc2 100644
--- a/apk-model.lua
+++ b/apk-model.lua
@@ -4,26 +4,170 @@ require("apk")
require("modelfunctions")
local configfile = "/etc/apk/repositories"
+local worldfile = "/var/lib/apk/world"
-get_all_packages = function()
- -- read in all of the packages
- return cfe({ type="list", value=apk.get_all(), label="All Packages"})
+local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "
+
+local repo = nil
+local install_cache = false
+local toplevel
+
+-- ################################################################################
+-- LOCAL FUNCTIONS
+
+local function gettoplevel()
+ if not toplevel then
+ toplevel = {}
+ local top = format.string_to_table(fs.read_file(worldfile) or "", "%s+")
+ for i,name in ipairs(top) do
+ toplevel[name] = i
+ end
+ end
+ return toplevel
+end
+
+local run_apk_cmd = function(cmd)
+ local c = path.."apk "..cmd.." 2>&1"
+ local f = io.popen(c)
+ local cmdresult = f:read("*a")
+ f:close()
+ return cmdresult
+end
+
+local reload_installed = function()
+ if repo then
+ -- clear out installed info
+ for name,value in pairs(repo) do
+ if value then
+ value.installed = nil
+ value.comment = nil
+ end
+ end
+ -- read in which are installed
+ local f = io.popen(path.."apk info -vv 2>/dev/null")
+ for line in f:lines() do
+ local name, ver, comment = string.match(line, "(%S+)%-(%d+%S*)%s+%-%s+(.*)")
+ if not repo[name] then
+ repo[name] = {}
+ end
+ repo[name].installed = ver
+ repo[name].comment = comment
+ end
+ f:close()
+ install_cache = true
+ end
+ return repo
end
+local repository = function()
+ if not repo then
+ -- read in all of the packages
+ local f = io.popen(path.."apk search 2>/dev/null")
+ repo = {}
+ install_cache = false
+ for line in f:lines() do
+ local name, ver = string.match(line, "(.*)%-(%d+.*)")
+ if name then
+ repo[name] = {}
+ repo[name].version = ver
+ end
+ end
+ f:close()
+ end
+ if not install_cache then
+ reload_installed()
+ end
+ return repo
+end
+
+-- Find all the packages that depend on this package (using recursion)
+-- package is the name of the package
+-- tab saves dependants for already processed packages
+-- saved marks when package included in output
+-- output is the output
+function find_dependants(package)
+ repo = repo or repository()
+ if not repo[package] then
+ return {}
+ end
+ if not repo[package].dependants then
+ repo[package].dependants = {}
+ local cmd = path .. "apk info -R "..package
+ local f = io.popen(cmd)
+ for line in f:lines() do
+ if not line:find("depends on:") and not line:find("^%s*$") then
+ table.insert(repo[package].dependants, line)
+ for i,dep in ipairs(find_dependants(line, saved, output)) do
+ table.insert(repo[package].dependants, dep)
+ end
+ end
+ end
+ end
+ return repo[package].dependants
+end
+
+local function upgrade_available(package)
+ local retval = false
+ repo = repo or repository()
+ if repo[package] and repo[package].version > repo[package].installed then
+ retval = true
+ else -- check the dependants
+ for i,dep in ipairs(find_dependants(package)) do
+ if repo[dep] and repo[dep].version > repo[dep].installed then
+ retval = true
+ break
+ end
+ end
+ end
+ return retval
+end
+
+-- ################################################################################
+-- PUBLIC FUNCTIONS
+
get_loaded_packages = function()
+ repo = repository()
+ toplevel = gettoplevel()
+
-- read in the loaded packages
- return cfe({ type="list", value=apk.get_loaded(), label="Loaded Packages"})
+ local top = cfe({ type="list", value={}, label="Top Level Packages"})
+ local depend = cfe({ type="list", value={}, label="Dependant Packages"})
+ for name,value in pairs(repo) do
+ if value.installed then
+ local temp = {}
+ temp.name = name
+ temp.version = value.installed
+ temp.description = value.comment
+ if toplevel[name] then
+ temp.upgrade = upgrade_available(name)
+ top.value[#top.value+1] = temp
+ else
+ depend.value[#depend.value+1] = temp
+ end
+ end
+ end
+ table.sort(top.value, function(a,b) return (a.name < b.name) end)
+ table.sort(depend.value, function(a,b) return (a.name < b.name) end)
+ return cfe({ type="group", value={toplevel=top, dependant=depend}, label="Loaded Packages" })
end
get_available_packages = function()
- -- available are all except loaded
- return cfe({ type="list", value=apk.get_available(), label="Available Packages" })
-end
-
-get_packages = function()
- local loaded = get_loaded_packages()
- local available = get_available_packages()
- return cfe({ type="group", value={loaded=loaded, available=available} })
+ repo = repository()
+ -- available are all except same version installed
+ local available = cfe({ type="list", value={}, label="Available Packages" })
+ for name,value in pairs(repo) do
+ if value.version ~= value.installed then
+ local temp = {}
+ temp.name = name
+ temp.version = value.version
+ if value.installed and value.version > value.installed then
+ temp.upgrade = true
+ end
+ available.value[#available.value + 1] = temp
+ end
+ end
+ table.sort(available.value, function(a,b) return (a.name < b.name) end)
+ return available
end
delete_package = function(package, sessiondata)
@@ -46,6 +190,18 @@ install_package = function(package,sessiondata)
return cfe({ value=cmdresult, label="Result of Install" })
end
+upgrade_package = function(package)
+ return cfe({ value=run_apk_cmd("add -u "..package), label="Result of Package Upgrade" })
+end
+
+update_all = function()
+ return cfe({ value=run_apk_cmd("update"), label="Result of Update" })
+end
+
+upgrade_all = function()
+ return cfe({ value=run_apk_cmd("upgrade"), label="Result of Upgrade" })
+end
+
get_configfile = function()
return modelfunctions.getfiledetails(configfile)
end
@@ -53,3 +209,42 @@ end
update_configfile = function(newconfig)
return modelfunctions.setfiledetails(newconfig, {configfile})
end
+
+get_package_details = function(package)
+ repo = repo or repository()
+ local details = {}
+ details.package = cfe({ value=package, label="Package" })
+ details.version = cfe({ label="Available Version" })
+ details.installed = cfe({ label="Installed Version" })
+ details.comment = cfe({ label="Description" })
+ details.webpage = cfe({ label="Web Page" })
+ details.size = cfe({ label="Size" })
+ details.upgrade = cfe({ label="Upgrade Details" })
+ if not repo[package] then
+ details.package.errtxt = "Invalid package"
+ else
+ details.version.value = repo[package].version
+ if repo[package].installed then
+ --details.installed.value = string.match(cmdresult[1], "%S*")
+ details.installed.value = repo[package].installed
+ details.comment.value = repo[package].comment
+ local cmdresult = format.string_to_table(run_apk_cmd("info -ws "..package), "\n")
+ details.webpage.value = cmdresult[2] or ""
+ details.size.value = cmdresult[5] or ""
+ local dependants = find_dependants(package)
+ table.insert(dependants, 1, package)
+ local revdeps = {}
+ details.upgrade.value = {}
+ for i,val in ipairs(dependants) do
+ if not revdeps[val] then
+ revdeps[val] = true
+ if repo[val].version > repo[val].installed then
+ table.insert(details.upgrade.value, val.." "..repo[val].installed.." -> "..repo[val].version)
+ end
+ end
+ end
+ details.upgrade.value = table.concat(details.upgrade.value, "\n")
+ end
+ end
+ return cfe({ type="group", value=details, label="Package Details" })
+end