Move get_reverse_tree into britney_util

Rename get_reverse_tree and move it to britney_util with slightly
different arguments.

Signed-off-by: Niels Thykier <niels@thykier.net>
debian
Niels Thykier 12 years ago
parent 53012ea54b
commit 1c144b3eb2

@ -190,7 +190,6 @@ import urllib
import apt_pkg import apt_pkg
from functools import reduce, partial from functools import reduce, partial
from itertools import chain, repeat, izip
from operator import attrgetter from operator import attrgetter
if __name__ == '__main__': if __name__ == '__main__':
@ -213,7 +212,7 @@ from migrationitem import MigrationItem, HintItem
from hints import HintCollection from hints import HintCollection
from britney import buildSystem from britney import buildSystem
from britney_util import (old_libraries_format, same_source, undo_changes, from britney_util import (old_libraries_format, same_source, undo_changes,
register_reverses) register_reverses, compute_reverse_tree)
from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC, from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC,
SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS, SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS,
PROVIDES, RDEPENDS, RCONFLICTS) PROVIDES, RDEPENDS, RCONFLICTS)
@ -1887,6 +1886,7 @@ class Britney(object):
# local copies for better performances # local copies for better performances
sources = self.sources sources = self.sources
binaries = self.binaries['testing'] binaries = self.binaries['testing']
get_reverse_tree = partial(compute_reverse_tree, self.binaries["testing"])
# remove all binary packages (if the source already exists) # remove all binary packages (if the source already exists)
if item.architecture == 'source' or not item.is_removal: if item.architecture == 'source' or not item.is_removal:
if item.package in sources['testing']: if item.package in sources['testing']:
@ -1903,7 +1903,7 @@ class Britney(object):
# save the old binary for undo # save the old binary for undo
undo['binaries'][p] = binaries[parch][0][binary] undo['binaries'][p] = binaries[parch][0][binary]
# all the reverse dependencies are affected by the change # all the reverse dependencies are affected by the change
affected.update(self.get_reverse_tree(binary, parch, 'testing')) affected.update(get_reverse_tree(binary, parch))
# remove the provided virtual packages # remove the provided virtual packages
for j in binaries[parch][0][binary][PROVIDES]: for j in binaries[parch][0][binary][PROVIDES]:
key = j + "/" + parch key = j + "/" + parch
@ -1927,7 +1927,7 @@ class Britney(object):
# updates but not supported as a manual hint # updates but not supported as a manual hint
elif item.package in binaries[item.architecture][0]: elif item.package in binaries[item.architecture][0]:
undo['binaries'][item.package + "/" + item.architecture] = binaries[item.architecture][0][item.package] undo['binaries'][item.package + "/" + item.architecture] = binaries[item.architecture][0][item.package]
affected.update(self.get_reverse_tree(item.package, item.architecture, 'testing')) affected.update(get_reverse_tree(item.package, item.architecture))
del binaries[item.architecture][0][item.package] del binaries[item.architecture][0][item.package]
self.systems[item.architecture].remove_binary(item.package) self.systems[item.architecture].remove_binary(item.package)
@ -1948,10 +1948,10 @@ class Britney(object):
# save the old binary package # save the old binary package
undo['binaries'][p] = binaries[parch][0][binary] undo['binaries'][p] = binaries[parch][0][binary]
# all the reverse dependencies are affected by the change # all the reverse dependencies are affected by the change
affected.update(self.get_reverse_tree(binary, parch, 'testing')) affected.update(get_reverse_tree(binary, parch))
# all the reverse conflicts and their dependency tree are affected by the change # all the reverse conflicts and their dependency tree are affected by the change
for j in binaries[parch][0][binary][RCONFLICTS]: for j in binaries[parch][0][binary][RCONFLICTS]:
affected.update(self.get_reverse_tree(j, parch, 'testing')) affected.update(get_reverse_tree(j, parch))
self.systems[parch].remove_binary(binary) self.systems[parch].remove_binary(binary)
else: else:
# the binary isn't in testing, but it may have been at # the binary isn't in testing, but it may have been at
@ -1969,7 +1969,7 @@ class Britney(object):
if p in tundo['binaries']: if p in tundo['binaries']:
for rdep in tundo['binaries'][p][RDEPENDS]: for rdep in tundo['binaries'][p][RDEPENDS]:
if rdep in binaries[parch][0] and rdep not in source[BINARIES]: if rdep in binaries[parch][0] and rdep not in source[BINARIES]:
affected.update(self.get_reverse_tree(rdep, parch, 'testing')) affected.update(get_reverse_tree(rdep, parch))
# add/update the binary package # add/update the binary package
binaries[parch][0][binary] = self.binaries[item.suite][parch][0][binary] binaries[parch][0][binary] = self.binaries[item.suite][parch][0][binary]
self.systems[parch].add_binary(binary, binaries[parch][0][binary][:PROVIDES] + \ self.systems[parch].add_binary(binary, binaries[parch][0][binary][:PROVIDES] + \
@ -1984,7 +1984,7 @@ class Britney(object):
undo['virtual'][key] = binaries[parch][1][j][:] undo['virtual'][key] = binaries[parch][1][j][:]
binaries[parch][1][j].append(binary) binaries[parch][1][j].append(binary)
# all the reverse dependencies are affected by the change # all the reverse dependencies are affected by the change
affected.update(self.get_reverse_tree(binary, parch, 'testing')) affected.update(get_reverse_tree(binary, parch))
# register reverse dependencies and conflicts for the new binary packages # register reverse dependencies and conflicts for the new binary packages
if item.architecture == 'source': if item.architecture == 'source':
@ -2001,39 +2001,6 @@ class Britney(object):
# return the package name, the suite, the list of affected packages and the undo dictionary # return the package name, the suite, the list of affected packages and the undo dictionary
return (item, affected, undo) return (item, affected, undo)
def get_reverse_tree(self, pkg, arch, suite):
"""Calculate the full dependency tree for the given package
This method returns the full dependency tree for the package
`pkg`, inside the `arch` architecture for the suite `suite`
flatterned as an iterable.
The tree is returned as an iterable of (package, arch) tuples
and the iterable will contain (`pkg`, `arch`) if it is
available on that architecture.
If `pkg` is not available on that architecture in that suite,
this returns an empty iterable.
The method does not promise any ordering of the returned
elements and the iterable is not reusable nor mutable.
"""
binaries = self.binaries[suite][arch][0]
if pkg not in binaries:
return frozenset()
rev_deps = set(binaries[pkg][RDEPENDS])
seen = set([pkg])
binfilt = ifilter_only(binaries)
revfilt = ifilter_except(seen)
flatten = chain.from_iterable
while rev_deps:
# mark all of the current iteration of packages as affected
seen |= rev_deps
# generate the next iteration, which is the reverse-dependencies of
# the current iteration
rev_deps = set(revfilt(flatten( binaries[x][RDEPENDS] for x in binfilt(rev_deps) )))
return izip(seen, repeat(arch))
def _check_packages(self, binaries, systems, arch, affected, skip_archall, nuninst, pkg): def _check_packages(self, binaries, systems, arch, affected, skip_archall, nuninst, pkg):
broken = nuninst[arch + "+all"] broken = nuninst[arch + "+all"]

@ -20,7 +20,7 @@
import apt_pkg import apt_pkg
from functools import partial from functools import partial
from itertools import ifilter, ifilterfalse from itertools import chain, ifilter, ifilterfalse, izip, repeat
import re import re
@ -218,3 +218,44 @@ def register_reverses(packages, provides, check_doubles=True, iterator=None,
if i not in packages: continue if i not in packages: continue
if not check_doubles or pkg not in packages[i][RCONFLICTS]: if not check_doubles or pkg not in packages[i][RCONFLICTS]:
packages[i][RCONFLICTS].append(pkg) packages[i][RCONFLICTS].append(pkg)
def compute_reverse_tree(packages_s, pkg, arch,
set=set, flatten=chain.from_iterable,
RDEPENDS=RDEPENDS):
"""Calculate the full dependency tree for the given package
This method returns the full dependency tree for the package
"pkg", inside the "arch" architecture for a given suite flattened
as an iterable. The first argument "packages_s" is the binary
package table for that given suite (e.g. Britney().binaries["testing"]).
The tree (or graph) is returned as an iterable of (package, arch)
tuples and the iterable will contain ("pkg", "arch") if it is
available on that architecture.
If "pkg" is not available on that architecture in that suite,
this returns an empty iterable.
The method does not promise any ordering of the returned
elements and the iterable is not reusable.
The flatten=... and the "X=X" parameters are optimizations to
avoid "load global" in the loops.
"""
binaries = packages_s[arch][0]
if pkg not in binaries:
return frozenset()
rev_deps = set(binaries[pkg][RDEPENDS])
seen = set([pkg])
binfilt = ifilter_only(binaries)
revfilt = ifilter_except(seen)
while rev_deps:
# mark all of the current iteration of packages as affected
seen |= rev_deps
# generate the next iteration, which is the reverse-dependencies of
# the current iteration
rev_deps = set(revfilt(flatten( binaries[x][RDEPENDS] for x in binfilt(rev_deps) )))
return izip(seen, repeat(arch))

Loading…
Cancel
Save