123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- -- This script will handle Allow-Duplicated packages when more
- -- than one is available during an install operation, and will
- -- also upgrade these packages in a dist-upgrade operation (if
- -- they match a regex in RPM::Allow-Duplicated-Upgrade).
- --
- -- This script must be plugged in the following slots:
- --
- -- Scripts::AptGet::Install::SelectPackage
- -- Scripts::AptGet::DistUpgrade
- -- Scripts::Synaptic::DistUpgrade
- --
- -- Author: Gustavo Niemeyer <niemeyer@conectiva.com>
- rex = require("rex_posix")
- function realname(name)
- local s, e, name = string.find(name, "(.+)#")
- return name
- end
- function get_pkglist(name)
- local j = 1
- local packages = {}
- for i, p in ipairs(pkglist()) do
- if realname(pkgname(p)) == name then
- packages[j] = p
- j = j + 1
- end
- end
- return packages
- end
- -- select best choice of virtual provided packages
- function select_goodpackage(packages)
- local goodpkg = packages[1]
- local goodpkgname = realname(pkgname(goodpkg))
- if goodpkgname then
- -- Check if every package has the same real name, and
- -- leave only the one with the greatest version, if
- -- that's the case.
- for i = 2, table.getn(packages) do
- local nextpkg = packages[i]
- local nextpkgname = realname(pkgname(nextpkg))
- if nextpkgname ~= goodpkgname then
- --markkeep(goodpkg)
- goodpkg = nil
- break
- end
- if not pkgvercand(goodpkg)
- or pkgvercand(nextpkg) and
- verstrcmp(verstr(pkgvercand(goodpkg)),
- verstr(pkgvercand(nextpkg))) == -1 then
- --markkeep(goodpkg)
- goodpkg = nextpkg
- end
- end
- if goodpkg and pkgvercand(goodpkg) then
- selected = goodpkg
- markinstall(goodpkg)
- end
- end
- if not selected then
- -- Strip #... from package names if we can't find a good solution.
- for i, name in ipairs(packagenames) do
- local name = realname(name)
- if name and name ~= virtualname then
- packagenames[i] = name
- end
- end
- end
- end
- if script_slot == "Scripts::AptGet::Install::PreResolve" then
- for i, pkg in ipairs(pkglist()) do
- s, e, name = string.find(pkgname(pkg), "(.+)#")
- if statinstall(pkg) and s then
- -- unmark selected packages
- markkeep(pkg)
- local packages = {}
- packages = get_pkglist(name)
- select_goodpackage(packages)
- end
- end
- end
- if script_slot == "Scripts::AptGet::Install::SelectPackage" then
- local found = 0
- for i, pkg in ipairs(packages) do
- p = pkgfind(pkgname(pkg))
- if pkgvercur(p) then
- found = 1
- end
- end
- if found == 0 then
- select_goodpackage(packages)
- end
- end
- if script_slot == "Scripts::AptGet::DistUpgrade" or
- script_slot == "Scripts::AptGet::Upgrade" or
- script_slot == "Scripts::Synaptic::DistUpgrade" or
- script_slot == "Scripts::Synaptic::Upgrade" then
- -- Automatically install newer versions of all packages which
- -- are registered in the Allow-Duplicated scheme and are matched
- -- by the regular expressions in RPM::Allow-Duplicated-Upgrade.
- -- Compile expressions with package names which should
- -- be considered for upgrade.
- local updatelist = confgetlist("RPM::Allow-Duplicated-Upgrade")
- for i, expr in ipairs(updatelist) do
- updatelist[i] = rex.new(expr)
- end
- if table.getn(updatelist) ~= 0 then
- -- Gather information about Allow-Duplicated packges.
- local canddups = {}
- local curdups = {}
- for i, pkg in pairs(pkglist()) do
- local name = realname(pkgname(pkg))
- if name then
- if pkgvercur(pkg) then
- if not curdups[name] then
- curdups[name] = {}
- end
- table.insert(curdups[name],
- verstr(pkgvercur(pkg)))
- elseif pkgvercand(pkg) then
- if not canddups[name] then
- canddups[name] = {}
- end
- table.insert(canddups[name],
- verstr(pkgvercand(pkg)))
- end
- end
- end
- -- Compile expressions with package names which should be hold.
- local holdlist = confgetlist("RPM::Hold")
- for i, expr in ipairs(holdlist) do
- holdlist[i] = rex.new(expr)
- end
- -- Remove packages without any matches in updatelist, or with
- -- any matches in holdlist.
- for name, _ in pairs(curdups) do
- local found = false
- for i, expr in ipairs(updatelist) do
- if expr:match(name) then
- found = true
- break
- end
- end
- if found then
- for i, expr in ipairs(holdlist) do
- if expr:match(name) then
- found = false
- break
- end
- end
- end
- if not found then
- curdups[name] = nil
- end
- end
- -- Mark the newest packages for installation.
- for name, _ in pairs(curdups) do
- if canddups[name] then
- -- Check the best candidate version.
- local bestver = nil
- for i, ver in ipairs(canddups[name]) do
- if not bestver or
- verstrcmp(bestver, ver) == -1 then
- bestver = ver
- end
- end
- -- Now check if it's newer than all installed
- -- versions.
- for i, ver in ipairs(curdups[name]) do
- if verstrcmp(ver, bestver) == 1 then
- bestver = nil
- break
- end
- end
- -- Finally, mark it for installation.
- if bestver then
- markinstall(name.."#"..bestver)
- end
- end
- end
- end
- end
- -- vim:ts=4:sw=4:et
|