Verified Commit 71ce6282 authored by Karel Koci's avatar Karel Koci 🤘

Don't split Depends to table and some cleanups

Don't split Depends field in backend. This format can also be specified
in configuration file, so it can be done in postprocess together.

prune_arr implemented in utils. It's code originally used in planner to
remove nil elements from array. This is now used on multiple places
where some workaround been used until now.

Also some more tests added to previously untested features.
parent 8573e2f5
......@@ -25,6 +25,9 @@ local type = type
local setmetatable = setmetatable
local getmetatable = getmetatable
local assert = assert
local table = table
local string = string
local math = math
local io = io
local unpack = unpack
local events_wait = events_wait
......@@ -32,7 +35,7 @@ local run_command = run_command
module "utils"
-- luacheck: globals lines2set map set2arr arr2set cleanup_dirs slurp clone shallow_copy table_merge arr_append exception multi_index private filter_best strip table_overlay randstr
-- luacheck: globals lines2set map set2arr arr2set cleanup_dirs slurp clone shallow_copy table_merge arr_append exception multi_index private filter_best strip table_overlay randstr arr_prune arr_inv
--[[
Convert provided text into set of lines. Doesn't care about the order.
......@@ -75,6 +78,29 @@ function arr2set(arr)
return map(arr, function (_, name) return name, true end)
end
-- Removes all nil values by shifting upper elements down.
function arr_prune(arr)
local indxs = set2arr(arr)
table.sort(indxs)
local res = {}
for _, i in ipairs(indxs) do
table.insert(res, arr[i])
end
return res
end
-- Inverts order of array
function arr_inv(arr)
local mid = math.modf(#arr / 2)
local endi = #arr + 1
for i = 1, mid do
local v = arr[i]
arr[i] = arr[endi - i]
arr[endi - i] = v
end
return arr
end
-- Run rm -rf on all dirs in the provided table
function cleanup_dirs(dirs)
if next(dirs) then
......
......@@ -178,10 +178,7 @@ function pkg_status_dump(status)
return block_dump_ordered({
raw "Package",
raw "Version",
line("Depends", function (deps)
-- Join the dependencies together, separated by commas
return table.concat(deps, ', ')
end),
raw "Depends",
raw "Conflicts",
line("Status", function (status)
-- Join status flags together, separated by spaces
......@@ -297,13 +294,7 @@ function package_postprocess(status)
-- Conffiles are lines with two „words“
replace("Conffiles", "\n", "%s*(%S+)%s+(%S+)")
status.Conffiles = slashes_sanitize(status.Conffiles)
-- Depends are separated by commas and may contain a version in parentheses
local idx = 0
replace("Depends", ",", function (s)
idx = idx + 1
return idx, s:gsub("^%s", ""):gsub("%s$", "")
end)
idx = 0
replace("Status", " ", function (s)
idx = idx + 1
return idx, s
......
......@@ -340,9 +340,10 @@ function pkg_aggregate()
-- Canonize dependencies
modifier.deps = deps_canon(modifier.deps)
for _, candidate in ipairs(pkg_group.candidates or {}) do
local candidate_deps = { candidate.deps } -- deps from updater configuration file
table.insert(candidate_deps, candidate.Depends) -- Depends from repository)
candidate.deps = deps_canon(candidate_deps)
candidate.deps = deps_canon(utils.arr_prune({
candidate.deps, -- deps from updater configuration file
candidate.Depends -- Depends from repository
}))
end
pkg_group.modifier = modifier
-- We merged them together, they are no longer needed separately
......
......@@ -330,8 +330,7 @@ local function build_plan(pkgs, requests, sat, satmap)
-- Recursively add all packages this package depends on --
inwstack[name] = #wstack + 1 -- Signal that we are working on this package group.
table.insert(wstack, name)
local alldeps = { utils.multi_index(pkg, 'modifier', 'deps') }
table.insert(alldeps, (candidate or {}).deps or {})
local alldeps = utils.arr_prune({ utils.multi_index(pkg, 'modifier', 'deps'), (candidate or {}).deps })
for _, p in pkg_dep_iterate(alldeps) do
pkg_plan(p, ignore_missing or utils.arr2set(utils.multi_index(pkg, 'modifier', 'ignore') or {})["deps"], false, "Package " .. name .. " requires package")
end
......@@ -410,6 +409,7 @@ function required_pkgs(pkgs, requests)
table.insert(reqs_critical, req)
else
if not req.priority then req.priority = 50 end
if not reqs_by_priority[req.priority] then reqs_by_priority[req.priority] = {} end
if req.tp ~= (utils.map(reqs_by_priority[req.priority], function(_, r) return r.package.name, r.tp end)[req.package.name] or req.tp) then
error(utils.exception('invalid-request', 'Requested both Install and Uninstall with same priority for package ' .. req.package.name))
......@@ -417,12 +417,7 @@ function required_pkgs(pkgs, requests)
table.insert(reqs_by_priority[req.priority], req)
end
end
local prios = utils.set2arr(reqs_by_priority)
table.sort(prios, function(a, b) return a > b end)
local reqs_prior = {}
for _, p in ipairs(prios) do
table.insert(reqs_prior, reqs_by_priority[p])
end
reqs_by_priority = utils.arr_inv(utils.arr_prune(reqs_by_priority))
-- Executes sat solver and adds clauses for maximal satisfiable set
local function clause_max_satisfiable()
......@@ -446,7 +441,7 @@ function required_pkgs(pkgs, requests)
-- Install and Uninstall requests.
DBG("Resolving Install and Uninstall requests")
for _, reqs in ipairs(reqs_prior) do
for _, reqs in ipairs(reqs_by_priority) do
for _, req in pairs(reqs) do
-- Assume all request for this priority
sat:assume(satmap.req2sat[req])
......
......@@ -127,7 +127,7 @@ function test_package_postprocces()
assert_equal(package, output)
assert_table_equal({"install", "user", "installed"}, output.Status)
assert_table_equal({["/etc/config/dhcp"] = "f81fe9bd228dede2165be71e5c9dcf76cc", ["/etc/dnsmasq.conf"] = "1e6ab19c1ae5e70d609ac7b6246541d520"}, output.Conffiles)
assert_table_equal({"libc", "kernel (= 3.18.21-1-70ea6b9a4b789c558ac9d579b5c1022f-10)", "kmod-nls-base"}, output.Depends)
assert_table_equal("libc, kernel (= 3.18.21-1-70ea6b9a4b789c558ac9d579b5c1022f-10), kmod-nls-base", output.Depends)
--[[
Now check it doesn't get confused when some of the modified fields aren't there
(or none, in this case).
......@@ -166,11 +166,7 @@ function test_status_parse()
["Installed-Size"] = "22537",
Description = "Kernel support for USB Mass Storage devices",
["Installed-Time"] = "1453896142",
Depends = {
"kernel (=3.18.21-1-70ea6b9a4b789c558ac9d579b5c1022f-10)",
"kmod-scsi-core",
"kmod-usb-core"
},
Depends = "kernel (=3.18.21-1-70ea6b9a4b789c558ac9d579b5c1022f-10), kmod-scsi-core, kmod-usb-core",
Status = std_status,
files = {
["/lib/modules/3.18.21-70ea6b9a4b789c558ac9d579b5c1022f-10/usb-storage.ko"] = true,
......@@ -189,7 +185,7 @@ function test_status_parse()
["Installed-Size"] = "5822",
Description = "Terminal Info Database (ncurses)",
["Installed-Time"] = "1453896265",
Depends = {"libc"},
Depends = "libc",
Status = std_status,
files = {
["/usr/share/terminfo/x/xterm"] = true,
......@@ -218,7 +214,7 @@ function test_status_parse()
This is a variant with DHCPv6 support]],
["Installed-Time"] = "1453896240",
Depends = {"libc"},
Depends = "libc",
Status = std_status,
files = {
["/etc/dnsmasq.conf"] = true,
......@@ -238,7 +234,7 @@ function test_status_parse()
Version = "27",
Architecture = "mpc85xx",
["Installed-Time"] = "1453896279",
Depends = {"libc", "ucollect-prog"},
Depends = "libc, ucollect-prog",
Status = std_status,
files = {}
})
......@@ -339,7 +335,7 @@ function test_pkg_unpack()
Architecture = "mpc85xx",
["Installed-Size"] = "14773",
Description = "updater",
Depends = {"libc", "vixie-cron", "openssl-util", "libatsha204", "curl", "cert-backup", "opkg", "bzip2", "cznic-cacert-bundle"},
Depends = "libc, vixie-cron, openssl-util, libatsha204, curl, cert-backup, opkg, bzip2, cznic-cacert-bundle",
Conffiles = conffiles,
Status = {"install", "user", "installed"},
files = files
......@@ -688,13 +684,13 @@ Installed-Time: 1
Version = "1",
["Installed-Time"] = "1",
Extra = "xxxx",
Depends = { "dep1", "dep2" },
Depends = "dep1, dep2",
Status = { "flag" },
Conffiles = { ["file"] = "1234567890123456" }
}))
end
function test_status_dump()
function test_status_parse_dump()
-- Read the status
local status = B.status_parse()
-- Make a copy of the status file, we'are going to write into it
......@@ -710,7 +706,7 @@ function test_status_dump()
Package = "New",
Version = "1",
["Installed-Time"] = "1",
Depends = { "Dep1", "dep2" },
Depends = "Dep1, dep2",
Status = { "flag" }
}
-- Do one more store-read-compare cycle
......@@ -850,12 +846,12 @@ function test_repo_parse()
["base-files"] = {
Package = "base-files",
Version = "160-r49274",
Depends = {"libc", "netifd", "procd", "jsonfilter"}
Depends = "libc, netifd, procd, jsonfilter"
},
["block-mount"] = {
Package = "block-mount",
Version = "2015-05-24-09027fc86babc3986027a0e677aca1b6999a9e14",
Depends = {"libc", "ubox", "libubox", "libuci"}
Depends = "libc, ubox, libubox, libuci"
}
}, B.repo_parse([[
Package: base-files
......
......@@ -1302,8 +1302,7 @@ function assert_plan_dep_order(expected, plan)
-- Check that objects are in correct order
local p2i = utils.map(plan, function(k, v) return v.name, k end)
for _, p in ipairs(plan) do
local alldeps = {p.modifier.deps}
utils.arr_append(alldeps, p.package.deps or {})
local alldeps = utils.arr_prune({p.modifier.deps, p.package.deps})
local pi = p2i[p.name]
for _, dep in ipairs(alldeps) do
for _, pkg in planner.pkg_dep_iterate(dep) do
......
......@@ -51,7 +51,7 @@ local example_output = {
list = {
["6in4"] = {
Architecture = "all",
Depends = {"libc", "kmod-sit"},
Depends = "libc, kmod-sit",
Description = [[Provides support for 6in4 tunnels in /etc/config/network.
Refer to http://wiki.openwrt.org/doc/uci/network for
configuration details.]],
......@@ -70,7 +70,7 @@ local example_output = {
},
["6rd"] = {
Architecture = "all",
Depends = {"libc", "kmod-sit"},
Depends = "libc, kmod-sit",
Description = [[Provides support for 6rd tunnels in /etc/config/network.
Refer to http://wiki.openwrt.org/doc/uci/network for
configuration details.]],
......@@ -188,7 +188,8 @@ function test_pkg_merge()
tp = 'pkg-list',
list = {
xyz = {Package = "xyz", Version = "1"},
abc = {Package = "abc", Version = "2"}
abc = {Package = "abc", Version = "2", Depends = "cde"},
cde = {Package = "cde", Version = "1"}
}
}
}
......@@ -247,11 +248,15 @@ function test_pkg_merge()
local exp = {
abc = {
candidates = {
{Package = "abc", Version = "2", repo = requests.known_repositories_all[1]},
{Package = "abc", Depends = "cde", deps = "cde", Version = "2", repo = requests.known_repositories_all[1]},
{Package = "abc", Version = "1", repo = requests.known_repositories_all[2]}
},
modifier = {name = "abc"}
},
cde = {
candidates = {{Package = "cde", Version = "1", repo = requests.known_repositories_all[1]}},
modifier = {name = "cde"}
},
another = {
candidates = {{Package = "another", Version = "4", repo = requests.known_repositories_all[2]}},
modifier = {name = "another"}
......@@ -305,6 +310,7 @@ function test_deps_canon()
assert_equal("x", postprocess.deps_canon("x"))
assert_equal("x", postprocess.deps_canon(" x "))
assert_equal("x", postprocess.deps_canon({"x"}))
assert_equal("x", postprocess.deps_canon({"x", ""}))
assert_equal("x", postprocess.deps_canon({tp = 'dep-and', sub = {"x"}}))
assert_equal("x", postprocess.deps_canon({tp = 'dep-or', sub = {"x"}}))
assert_equal("x", postprocess.deps_canon("x ( )"))
......
......@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
]]--
local string = string
require "lunit"
local U = require "utils"
......@@ -57,6 +58,18 @@ function test_arr2set()
assert_table_equal({a = true, b = true}, U.arr2set({"a", "b"}))
end
function test_arr_prune()
assert_table_equal({}, U.arr_prune({nil, nil, nil, nil}))
assert_table_equal({"a", "b", "c"}, U.arr_prune({"a", "b", "c"}))
assert_table_equal({"a", "b", "c"}, U.arr_prune({nil, "a", "b", nil, nil, "c"}))
end
function test_arr_inv()
assert_table_equal({}, U.arr_inv({}))
assert_table_equal({"c", "b", "a"}, U.arr_inv({"a", "b", "c"}))
assert_table_equal({"d", "c", "b", "a"}, U.arr_inv({"a", "b", "c", "d"}))
end
function test_clone()
local input = {
x = 1,
......@@ -167,6 +180,11 @@ function test_strip()
assert_nil(U.strip(nil))
end
function test_randstr()
assert_equal(4, string.len(U.randstr(4)))
assert_equal(18, string.len(U.randstr(18)))
end
function test_arr_append()
local a1 = {'a', 'b', 'c'}
local a2 = {'d', 'e', 'f'}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment