source: projects/specs/trunk/a/apt/allow-duplicated.lua @ 7862

Revision 7862, 6.0 KB checked in by daisuke, 11 years ago (diff)

add allow-duplicated scripts to repos

  • Property svn:executable set to *
Line 
1-- This script will handle Allow-Duplicated packages when more
2-- than one is available during an install operation, and will
3-- also upgrade these packages in a dist-upgrade operation (if
4-- they match a regex in RPM::Allow-Duplicated-Upgrade).
5--
6-- This script must be plugged in the following slots:
7--
8--   Scripts::AptGet::Install::SelectPackage
9--   Scripts::AptGet::DistUpgrade
10--   Scripts::Synaptic::DistUpgrade
11--
12-- Author: Gustavo Niemeyer <niemeyer@conectiva.com>
13
14rex = require("rex_posix")
15
16function realname(name)
17    local s, e, name = string.find(name, "(.+)#")
18    return name
19end
20
21function get_pkglist(name)
22    local j = 1
23    local packages = {}
24    for i, p in ipairs(pkglist()) do
25        if realname(pkgname(p)) == name then
26            packages[j] = p
27            j = j + 1
28        end
29    end
30    return packages
31end
32
33-- select best choice of virtual provided packages
34function select_goodpackage(packages)
35    local goodpkg = packages[1]
36    local goodpkgname = realname(pkgname(goodpkg))
37
38    if goodpkgname then
39        -- Check if every package has the same real name, and
40        -- leave only the one with the greatest version, if
41        -- that's the case.
42        for i = 2, table.getn(packages) do
43            local nextpkg = packages[i]
44            local nextpkgname = realname(pkgname(nextpkg))
45            if nextpkgname ~= goodpkgname then
46                --markkeep(goodpkg)
47                goodpkg = nil
48                break
49            end
50            if not pkgvercand(goodpkg)
51               or pkgvercand(nextpkg) and
52                  verstrcmp(verstr(pkgvercand(goodpkg)),
53                    verstr(pkgvercand(nextpkg))) == -1 then
54                        --markkeep(goodpkg)
55                        goodpkg = nextpkg
56            end
57        end
58        if goodpkg and pkgvercand(goodpkg) then
59            selected = goodpkg
60            markinstall(goodpkg)
61        end
62    end
63    if not selected then
64        -- Strip #... from package names if we can't find a good solution.
65        for i, name in ipairs(packagenames) do
66            local name = realname(name)
67            if name and name ~= virtualname then
68                packagenames[i] = name
69            end
70        end
71    end
72end
73
74if script_slot == "Scripts::AptGet::Install::PreResolve" then
75    for i, pkg in ipairs(pkglist()) do
76        s, e, name = string.find(pkgname(pkg), "(.+)#")
77        if statinstall(pkg) and s then
78            -- unmark selected packages
79            markkeep(pkg)
80            local packages = {}
81            packages = get_pkglist(name)
82
83            select_goodpackage(packages)
84        end
85    end
86end
87
88if script_slot == "Scripts::AptGet::Install::SelectPackage" then
89    local found = 0
90    for i, pkg in ipairs(packages) do
91        p = pkgfind(pkgname(pkg))
92        if pkgvercur(p) then
93            found = 1
94        end
95    end
96    if found == 0 then
97        select_goodpackage(packages)
98    end
99end
100
101if script_slot == "Scripts::AptGet::DistUpgrade" or
102   script_slot == "Scripts::AptGet::Upgrade" or
103   script_slot == "Scripts::Synaptic::DistUpgrade" or
104   script_slot == "Scripts::Synaptic::Upgrade" then
105    -- Automatically install newer versions of all packages which
106    -- are registered in the Allow-Duplicated scheme and are matched
107    -- by the regular expressions in RPM::Allow-Duplicated-Upgrade.
108
109    -- Compile expressions with package names which should
110    -- be considered for upgrade.
111    local updatelist = confgetlist("RPM::Allow-Duplicated-Upgrade")
112    for i, expr in ipairs(updatelist) do
113        updatelist[i] = rex.new(expr)
114    end
115
116    if table.getn(updatelist) ~= 0 then
117
118        -- Gather information about Allow-Duplicated packges.
119        local canddups = {}
120        local curdups = {}
121        for i, pkg in pairs(pkglist()) do 
122            local name = realname(pkgname(pkg))
123            if name then
124                if pkgvercur(pkg) then
125                    if not curdups[name] then
126                        curdups[name] = {}
127                    end
128                    table.insert(curdups[name],
129                             verstr(pkgvercur(pkg)))
130                elseif pkgvercand(pkg) then
131                    if not canddups[name] then
132                        canddups[name] = {}
133                    end
134                    table.insert(canddups[name],
135                             verstr(pkgvercand(pkg)))
136                end
137            end
138        end
139
140        -- Compile expressions with package names which should be hold.
141        local holdlist = confgetlist("RPM::Hold")
142        for i, expr in ipairs(holdlist) do
143            holdlist[i] = rex.new(expr)
144        end
145
146        -- Remove packages without any matches in updatelist, or with
147        -- any matches in holdlist.
148        for name, _ in pairs(curdups) do
149            local found = false
150            for i, expr in ipairs(updatelist) do
151                if expr:match(name) then
152                    found = true
153                    break
154                end
155            end
156            if found then
157                for i, expr in ipairs(holdlist) do
158                    if expr:match(name) then
159                        found = false
160                        break
161                    end
162                end
163            end
164            if not found then
165                curdups[name] = nil
166            end
167        end
168
169        -- Mark the newest packages for installation.
170        for name, _ in pairs(curdups) do
171            if canddups[name] then
172                -- Check the best candidate version.
173                local bestver = nil
174                for i, ver in ipairs(canddups[name]) do
175                    if not bestver or
176                       verstrcmp(bestver, ver) == -1 then
177                        bestver = ver
178                    end
179                end
180
181                -- Now check if it's newer than all installed
182                -- versions.
183                for i, ver in ipairs(curdups[name]) do
184                    if verstrcmp(ver, bestver) == 1 then
185                        bestver = nil
186                        break
187                    end
188                end
189
190                -- Finally, mark it for installation.
191                if bestver then
192                    markinstall(name.."#"..bestver)
193                end
194            end
195        end
196    end
197end
198
199-- vim:ts=4:sw=4:et
Note: See TracBrowser for help on using the repository browser.