Fixed a bug: conflicts with virtual packages in check_conflicts.

master
Fabio Tranchitella 18 years ago
parent fd15f44b0c
commit da58215dd1

@ -831,7 +831,8 @@ class Britney:
for r in f: for r in f:
if ":" not in r: continue if ":" not in r: continue
arch, packages = r.strip().split(":", 1) arch, packages = r.strip().split(":", 1)
nuninst[arch] = packages.split() if arch in self.options.architectures:
nuninst[arch] = packages.split()
return nuninst return nuninst
@ -1526,9 +1527,6 @@ class Britney:
if pkg not in nuninst[arch]: if pkg not in nuninst[arch]:
nuninst[arch].append(pkg) nuninst[arch].append(pkg)
for p in binaries[arch][0][pkg]['rdepends']: for p in binaries[arch][0][pkg]['rdepends']:
tpkg = binaries[arch][0][p]
if skip_archall and tpkg['architecture'] == 'all':
continue
r = check_installable(p, arch, 'testing', excluded=nuninst[arch], conflicts=True) r = check_installable(p, arch, 'testing', excluded=nuninst[arch], conflicts=True)
if not r: if not r:
add_nuninst(p, arch) add_nuninst(p, arch)
@ -1545,13 +1543,17 @@ class Britney:
# uninstallable package is found # uninstallable package is found
nuninst[arch] = [] nuninst[arch] = []
for pkg_name in binaries[arch][0]: for pkg_name in binaries[arch][0]:
pkg = binaries[arch][0][pkg_name]
if skip_archall and pkg['architecture'] == 'all':
continue
r = check_installable(pkg_name, arch, 'testing', excluded=nuninst[arch], conflicts=True) r = check_installable(pkg_name, arch, 'testing', excluded=nuninst[arch], conflicts=True)
if not r: if not r:
add_nuninst(pkg_name, arch) add_nuninst(pkg_name, arch)
# if they are not required, removed architecture-indipendent packages
if skip_archall:
for pkg in nuninst[arch][:]:
bpkg = binaries[arch][0][pkg]
if bpkg['architecture'] == 'all':
nuninst[arch].remove(pkg)
# return the dictionary with the results # return the dictionary with the results
return nuninst return nuninst
@ -1678,6 +1680,12 @@ class Britney:
if len(conflicts[c]) == 0: if len(conflicts[c]) == 0:
del conflicts[c] del conflicts[c]
def remove_package(pkg, system, conflicts):
for k in system.keys():
if pkg in system[k][1]:
system[k][1].remove(pkg)
unregister_conflicts(pkg, conflicts)
# handle a conflict, local method to solve a conflict which happened # handle a conflict, local method to solve a conflict which happened
# in the system; the behaviour of the conflict-solver is: # in the system; the behaviour of the conflict-solver is:
# 1. If there are alternatives for the package which must be removed, # 1. If there are alternatives for the package which must be removed,
@ -1687,6 +1695,10 @@ class Britney:
# 3. If the top of the dependency tree is reached, then the conflict # 3. If the top of the dependency tree is reached, then the conflict
# can't be solved, so return False. # can't be solved, so return False.
def handle_conflict(pkg, source, system, conflicts): def handle_conflict(pkg, source, system, conflicts):
# skip packages which don't have reverse dependencies
if source not in system or system[source][1] == []:
remove_package(source, system, conflicts)
return (system, conflicts)
# reached the top of the tree # reached the top of the tree
if not system[source][1][0]: if not system[source][1][0]:
return False return False
@ -1697,14 +1709,19 @@ class Britney:
for alt in alternatives: for alt in alternatives:
if satisfy(alt, [x for x in alternatives if x != alt], pkg_from=system[source][1], if satisfy(alt, [x for x in alternatives if x != alt], pkg_from=system[source][1],
system=system, conflicts=conflicts, excluded=[source]): system=system, conflicts=conflicts, excluded=[source]):
remove_package(source, system, conflicts)
return (system, conflicts) return (system, conflicts)
# there are no good alternatives, so remove the package which depends on it # there are no good alternatives, so remove the package which depends on it
for p in system[source][1]: for p in system[source][1]:
# the package does not exist, we reached the top of the tree
if not p: return False if not p: return False
# we are providing the package we conflict on (eg. exim4 and mail-transfer-agent), skip it
if p == pkg: continue
output = handle_conflict(pkg, p, system, conflicts) output = handle_conflict(pkg, p, system, conflicts)
if output: if output:
system, conflicts = output system, conflicts = output
else: return False else: return False
remove_package(source, system, conflicts)
return (system, conflicts) return (system, conflicts)
# dependency tree satisfier, local method which tries to satisfy the dependency # dependency tree satisfier, local method which tries to satisfy the dependency
@ -1771,7 +1788,8 @@ class Britney:
if binary_u['provides']: if binary_u['provides']:
for p in binary_u['provides']: for p in binary_u['provides']:
if p in system: if p in system:
if system[p][1][0] == None: continue # do not consider packages providing the one which we are checking
if len(system[p][1]) == 1 and system[p][1][0] == None: continue
system[p][1].append(pkg) system[p][1].append(pkg)
else: else:
system[p] = ([], [pkg]) system[p] = ([], [pkg])
@ -1796,9 +1814,9 @@ class Britney:
for block in map(operator.itemgetter(0), parse_depends(binary_u.get('conflicts', []))): for block in map(operator.itemgetter(0), parse_depends(binary_u.get('conflicts', []))):
name, version, op = block name, version, op = block
# skip conflicts for packages provided by itself # skip conflicts for packages provided by itself
if name in binary_u['provides']: continue
# if the conflicting package is in the system (and it is not a self-conflict) # if the conflicting package is in the system (and it is not a self-conflict)
if block[0] != pkg and block[0] in system: if not (name in binary_u['provides'] and system[name][1] == [pkg]) and \
block[0] != pkg and block[0] in system:
if block[0] in binaries[0]: if block[0] in binaries[0]:
binary_c = binaries[0][block[0]] binary_c = binaries[0][block[0]]
else: binary_c = None else: binary_c = None

Loading…
Cancel
Save