Provide a priority to standalone packages

Allow the Package to have a priority option and use it when comparing
stand-alone packages with other packages to pick the right one.

This'll allow us to have a testing package with a version higher than
the one in repository and have the repository outgrow the version in
future (or not, depending on the priority).
parent cd357eab
......@@ -495,7 +495,9 @@ abi_change_deep::
on.
content::
This is an alternative for the package being available from a
repository. This lists an URI where the package lives.
repository. This lists an URI where the package lives. If the
package has all parameters same as one from a repository (eg.
priority, version), the one with content is preferred.
verification::
sig::
pubkey::
......@@ -504,6 +506,11 @@ crl::
Options to verify the package integrity, if the content option is
specified. These are ignored in virtual packages and packages from a
repository.
priority::
A priority for packages not coming from a repository (eg. with the
`content` option) to be used when choosing the right candidate.
Defaults to 50, as with repositories. It is ignored with packages
from repositories and has no meaning for virtual packages.
ignore::
Ignore listed categories of errors. This takes an array of strings,
each string meaning one category to ignore.
......
......@@ -54,6 +54,7 @@ local allowed_package_extras = utils.arr2set({
"abi_change",
"abi_change_deep",
"content",
"priority",
"verification",
"sig",
"pubkey",
......
......@@ -164,6 +164,7 @@ function get_content_pkgs()
end
pkg.candidate = control
pkg.candidate.data = data
pkg.candidate.pkg = pkg
-- Remove unpacked package. Because we might run no far than planning.
-- If it is going to be installed, it will be unpacked again.
utils.cleanup_dirs({pkg_dir, tmpdir})
......@@ -384,14 +385,10 @@ function pkg_aggregate()
pkg_group.modifiers = nil
-- Sort candidates
if pkg_group.candidates then
local warn_local_remote = false
table.sort(pkg_group.candidates, function(a, b)
-- The locally created packages (with content) have no repo, consider them as from a repo with infinite priority (or, higher than 100, as 100 is the max) to be preferred
if (a.repo and not b.repo) or (not a.repo and b.repo) then
warn_local_remote = true;
end
local a_repo = a.repo or {priority = 1000, serial = -1}
local b_repo = b.repo or {priority = 1000, serial = -1}
-- The locally created packages (with content) have no repo, create a dummy one. Get its priority from the Package command, or the default 50
local a_repo = a.repo or {priority = utils.multi_index(a, "pkg", "priority") or 50, serial = -1}
local b_repo = b.repo or {priority = utils.multi_index(b, "pkg", "priority") or 50, serial = -1}
if a_repo.priority ~= b_repo.priority then -- Check repository priority
return a_repo.priority > b_repo.priority
end
......@@ -412,9 +409,6 @@ function pkg_aggregate()
WARN("Multiple candidates from same repository with same version for package " .. a.Package)
return true -- lets prioritize a, for no reason, lets make b angry.
end)
if warn_local_remote then
WARN("Package " .. name .. " comes from both local content and a repository. The local content is preferred and no updates will happen to the package.")
end
end
end
end
......
......@@ -342,15 +342,17 @@ function test_local_and_repo()
xyz = {
tp = 'package',
name = 'xyz',
priority = 60,
candidate = {Package = "xyz", Version = "1", local_mark = true}, -- Mark the package so we recognize it got through unmodified
content = "dummy-content"
}
}
requests.known_packages.xyz.candidate.pkg = requests.known_packages.xyz
postprocess.pkg_aggregate()
local exp = {
xyz = {
candidates = {
{Package = "xyz", Version = "1", local_mark = true},
{Package = "xyz", Version = "1", local_mark = true, pkg = requests.known_packages.xyz},
{Package = "xyz", Version = "2", repo = requests.known_repositories_all[1]}
},
modifier = {
......@@ -369,6 +371,12 @@ function test_local_and_repo()
}
}
assert_table_equal(exp, postprocess.available_packages)
-- Try again, but with the same priority ‒ versions should be used to sort them
postprocess.available_packages = {}
requests.known_packages.xyz.priority = nil
exp.xyz.candidates = {exp.xyz.candidates[2], exp.xyz.candidates[1]}
postprocess.pkg_aggregate()
assert_table_equal(exp, postprocess.available_packages)
end
function test_deps_canon()
......
......@@ -46,12 +46,13 @@ function test_package()
tp = "package",
name = "pkg_name"
}, p1)
local p2 = run_sandbox_fun "Package 'pkg_name' {replan = true, reboot = 'delayed'}"
local p2 = run_sandbox_fun "Package 'pkg_name' {replan = true, reboot = 'delayed', priority = 42}"
assert_table_equal({
tp = "package",
name = "pkg_name",
replan = true,
reboot = "delayed"
reboot = "delayed",
priority = 42
}, p2)
assert_table_equal({p1, p2}, requests.known_packages)
end
......
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