[yum-cvs] yum/yum depsolve.py,1.145,1.146
Seth Vidal
skvidal at linux.duke.edu
Wed Mar 28 08:09:16 UTC 2007
Update of /home/groups/yum/cvs/yum/yum
In directory login1.linux.duke.edu:/tmp/cvs-serv15156
Modified Files:
depsolve.py
Log Message:
- catch the case where we remove something needed in the transaction
- partial limited delta case
Index: depsolve.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/depsolve.py,v
retrieving revision 1.145
retrieving revision 1.146
diff -u -r1.145 -r1.146
--- depsolve.py 23 Mar 2007 07:41:36 -0000 1.145
+++ depsolve.py 28 Mar 2007 08:09:14 -0000 1.146
@@ -43,7 +43,6 @@
self.dsCallback = None
self.logger = logging.getLogger("yum.Depsolve")
self.verbose_logger = logging.getLogger("yum.verbose.Depsolve")
- self.tsInfoDelta = []
def doTsSetup(self):
warnings.warn('doTsSetup() will go away in a future version of Yum.\n',
@@ -510,7 +509,6 @@
requiringPo, needname)
txmbr = self.tsInfo.addErase(requiringPo)
txmbr.setAsDep(po=needpo)
- self.tsInfoDelta.append(txmbr)
checkdeps = 1
if needmode in ['i', 'u']:
@@ -532,7 +530,6 @@
txmbr = self.tsInfo.addObsoleting(po, requiringPo)
self.tsInfo.addObsoleted(requiringPo, po)
txmbr.setAsDep(po=needpo)
- self.tsInfoDelta.append(txmbr)
self.verbose_logger.log(logginglevels.DEBUG_2, 'TSINFO: Obsoleting %s with %s to resolve dep.',
requiringPo, po)
checkdeps = 1
@@ -564,7 +561,6 @@
if po.pkgtup == new:
txmbr = self.tsInfo.addUpdate(po, requiringPo)
txmbr.setAsDep(po=needpo)
- self.tsInfoDelta.append(txmbr)
self.verbose_logger.log(logginglevels.DEBUG_2, 'TSINFO: Updating %s to resolve dep.', po)
checkdeps = 1
@@ -706,13 +702,11 @@
# FIXME: we should probably handle updating multiple packages...
txmbr = self.tsInfo.addUpdate(best, inst[0])
txmbr.setAsDep()
- self.tsInfoDelta.append(txmbr)
else:
self.verbose_logger.debug('TSINFO: Marking %s as install for %s', best,
name)
txmbr = self.tsInfo.addInstall(best)
txmbr.setAsDep()
- self.tsInfoDelta.append(txmbr)
checkdeps = 1
@@ -773,7 +767,6 @@
'TSINFO: Updating %s to resolve conflict.', po)
txmbr = self.tsInfo.addUpdate(po, confpkg)
txmbr.setAsDep()
- self.tsInfoDelta.append(txmbr)
CheckDeps = 1
else:
@@ -887,6 +880,9 @@
ret = []
for txmbr in self.tsInfo.getMembers():
+
+ if self.dcobj.already_seen.has_key(txmbr):
+ continue
self.verbose_logger.log(logginglevels.INFO_2,
"Checking deps for %s" %(txmbr,))
if txmbr.output_state in (TS_INSTALL, TS_TRUEINSTALL, TS_OBSOLETING):
@@ -895,8 +891,8 @@
ret.extend(self._checkUpdate(txmbr))
elif txmbr.output_state in TS_REMOVE_STATES:
ret.extend(self._checkRemove(txmbr))
-
- self.tsInfoDelta = []
+ self.dcobj.already_seen[txmbr] = 1
+
return ret
def _resolveDeps(self):
@@ -909,7 +905,6 @@
errors = []
if self.dsCallback: self.dsCallback.start()
- self.tsInfoDelta = self.tsInfo.getMembers()
while CheckDeps:
self.cheaterlookup = {} # short cache for some information we'd resolve
# (needname, needversion) = pkgtup
@@ -1099,7 +1094,7 @@
newpoprovs[(f, None, (None, None, None))] = 1
ret = []
- removing = []
+ self._removing = []
# iterate over the provides of the package being removed
for prov in provs:
if prov[0].startswith('rpmlib('): # ignore rpmlib() provides
@@ -1108,96 +1103,11 @@
continue
if newpoprovs.has_key(prov):
continue
-
- self.verbose_logger.log(logginglevels.DEBUG_4, "looking to see what requires %s of %s", prov, po)
-
+
(r, f, v) = prov
-
- removeList = []
- # see what requires this provide name
- for pkgtup in self.rpmdb.whatRequires(r, None, None):
- self.verbose_logger.log(logginglevels.DEBUG_2, "looking at %s as a requirement of %s", r, pkgtup)
- isok = False
- # ignore stuff already being removed
- if self.tsInfo.getMembers(pkgtup, TS_REMOVE_STATES):
- continue
- if pkgtup in removing:
- continue
- instpo = self.getInstalledPackageObject(pkgtup)
-
- # check to ensure that we really fulfill instpo's need for r
- if not instpo.checkPrco('requires', (r,f,v)):
- continue
-
- # now see if anything else is providing what we need
- for provtup in self.rpmdb.whatProvides(r, None, None):
- # check if this provider is being removed
- if provtup in removing:
- continue
- if self.tsInfo.getMembers(provtup, TS_REMOVE_STATES):
- continue
-
- provpo = self.getInstalledPackageObject(provtup)
- if provpo in removeList:
- continue
- # check if provpo actually satisfies instpo's need for r
- # if so, we're golden
- ok = True
- for (rr, rf, rv) in instpo.requires:
- if rr != r:
- continue
- if not provpo.checkPrco('provides', (rr, rf, rv)):
- ok = False
- if ok:
- isok = True
- break
-
- if isok:
- continue
-
- # for files, we need to do a searchProvides() to take
- # advantage of the shortcut of the files globbed into
- # primary.xml.gz. this is a bit of a hack, but saves us
- # from having to download the filelists for a lot of cases
- if r.startswith("/"):
- for po in self.pkgSack.searchProvides(r):
- if self.tsInfo.getMembers(po.pkgtup, TS_INSTALL_STATES):
- isok = True
- break
- for po in self.rpmdb.searchFiles(r):
- if not self.tsInfo.getMembers(po.pkgtup, TS_REMOVE_STATES):
- isok = True
- break
- if isok:
- continue
-
- # now do the same set of checks with packages that are
- # set to be installed.
- for txmbr in self.tsInfo.getMembers(None, TS_INSTALL_STATES):
- if txmbr.po.checkPrco('provides',
- (r, None, (None,None,None))):
- ok = True
- for (rr, rf, rv) in instpo.requires:
- if rr != r:
- continue
- if not txmbr.po.checkPrco('provides', (rr, rf, rv)):
- ok = False
- if ok:
- isok = True
- break
-
- # FIXME: it's ugly to have to check files separately here
- elif r.startswith("/") and r in txmbr.po.filelist:
- isok = True
- break
-
- if isok:
- continue
-
- if not isok:
- removeList.append(instpo)
-
-
+ self.verbose_logger.log(logginglevels.DEBUG_4, "looking to see what requires %s of %s", prov, po)
+ removeList = self._requiredByPkg(prov)
+
# we have a list of all the items impacted and
# left w/unresolved deps
# by this remove. stick them in the ret list with their
@@ -1215,7 +1125,7 @@
v = rv
break
- removing.append(pkgtup)
+ self._removing.append(po.pkgtup)
reqtuple = (r, version_tuple_to_string(v), flags[f])
self.dcobj.addRequires(po, [reqtuple])
@@ -1228,13 +1138,55 @@
def _requiredByPkg(self, prov):
"""check to see if anything will or does require the provide, return
list of requiring pkg objects if so"""
-
+
# check if anything installed needs it
# make sure installed item is not set to be removed/obsoleted
# make sure nothing else provides the same thing just as well
# check if anything in the ts set to be installed/updated requires it
# make sure nothing else provides the same thing just as well
+ (r, f, v) = prov
+ removeList = []
+ # if anything else provides this as well and is installed or
+ # to be installed, then skip this whole step
+ other_provider = False
+ tsSack = self.tsInfo.getMembers(None, TS_INSTALL_STATES, asSack=True)
+ for provpo in self.rpmdb.searchProvides(r) + tsSack.searchProvides(r):
+ if self.tsInfo.getMembers(provpo.pkgtup, TS_REMOVE_STATES): # if it's being removed in the ts, it doesn't count
+ continue
+ if provpo.pkgtup in self._removing: # if we're going to be removed in the ts, it doesn't count
+ continue
+ if not provpo.checkPrco('provides', (r, f, v)): # if it doesn't actually provide the req, it doesn't count
+ continue
+ other_provider = True
+
+ if other_provider:
+ return []
+
+ # see what requires this provide name
+ tsSack = self.tsInfo.getMembers(None, TS_INSTALL_STATES, asSack=True)
+ for reqpo in self.rpmdb.searchRequires(r) + tsSack.searchRequires(r):
+ self.verbose_logger.log(logginglevels.DEBUG_2, "looking at %s as a requirement of %s", r, reqpo)
+ isok = False
+ # ignore stuff already being removed
+ if self.tsInfo.getMembers(reqpo.pkgtup, TS_REMOVE_STATES):
+ continue
+ # ignore stuff soon to be removed
+ if reqpo.pkgtup in self._removing:
+ continue
+
+ # check to ensure that we really fulfill instpo's need for r
+ if not reqpo.checkPrco('requires', (r,f,v)):
+ continue
+
+ if provpo in removeList: # if we already found it
+ continue
+
+ # otherwise, add it to the removeList
+ removeList.append(reqpo)
+
+ return removeList
+
class DepCheck(object):
"""object that YumDepsolver uses to see what things are needed to close
the transaction set. attributes: requires, conflicts are a list of
@@ -1243,7 +1195,8 @@
def __init__(self):
self.requires = []
self.conflicts = []
-
+ self.already_seen = {}
+
def addRequires(self, po, req_tuple_list):
# fixme - do checking for duplicates or additions in here to zip things along
reqobj = Requires(po, req_tuple_list)
More information about the Yum-cvs-commits
mailing list