Browse Source

add allow-duplicated scripts to repos

git-svn-id: http://trac.vinelinux.org/repos/projects/specs@7862 ec354946-7b23-47d6-9f5a-488ba84defc7
daisuke 10 years ago
parent
commit
d3384417e0
3 changed files with 207 additions and 0 deletions
  1. 1 0
      a/apt/allow-duplicated-upgrade.conf
  2. 7 0
      a/apt/allow-duplicated.conf
  3. 199 0
      a/apt/allow-duplicated.lua

+ 1 - 0
a/apt/allow-duplicated-upgrade.conf

@@ -0,0 +1 @@
+RPM::Allow-Duplicated-Upgrade:: "kernel.*";

+ 7 - 0
a/apt/allow-duplicated.conf

@@ -0,0 +1,7 @@
+Scripts::AptGet::Install::SelectPackage:: "allow-duplicated.lua";
+Scripts::AptGet::DistUpgrade:: "allow-duplicated.lua";
+Scripts::AptGet::Upgrade:: "allow-duplicated.lua";
+Scripts::Synaptic::DistUpgrade:: "allow-duplicated.lua";
+Scripts::Synaptic::Upgrade:: "allow-duplicated.lua";
+
+Scripts::AptGet::Install::PreResolve:: "allow-duplicated.lua";

+ 199 - 0
a/apt/allow-duplicated.lua

@@ -0,0 +1,199 @@
+-- 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