[yum-git] test/transactiontests.py yum/depsolve.py yum/__init__.py yum/transactioninfo.py
Florian Festi
ffesti at linux.duke.edu
Wed Jun 4 07:38:12 UTC 2008
test/transactiontests.py | 8 +--
yum/__init__.py | 110 +++++++++++++++++++++++------------------------
yum/depsolve.py | 27 +++++------
yum/transactioninfo.py | 91 +++++++++++++++++++++++++++++---------
4 files changed, 142 insertions(+), 94 deletions(-)
New commits:
commit ca31584860a944d18095e9684e3672e4ee6e52d8
Author: Florian Festi <ffesti at redhat.com>
Date: Mon Feb 18 13:33:47 2008 +0100
Introduce AdditionResult class
to report back the results of TransactionInfo.add*
diff --git a/test/transactiontests.py b/test/transactiontests.py
index 74a7666..724012f 100644
--- a/test/transactiontests.py
+++ b/test/transactiontests.py
@@ -48,7 +48,7 @@ class TransactionDataTests(unittest.TestCase):
def testRemove(self):
''' test remove from transaction '''
- txmbr = self.tsInfo.addInstall(self.foo1)
+ txmbr = self.tsInfo.addInstall(self.foo1).primary
self.tsInfo.addInstall(self.bar2)
self.tsInfo.remove(self.bar2.pkgtup)
self.dumpTsInfo()
@@ -60,7 +60,7 @@ class TransactionDataTests(unittest.TestCase):
txmbr2 = self.tsInfo.addUpdate(self.foogui2,self.foogui1)
txmbr3 = self.tsInfo.getMembers(self.foogui1.pkgtup)[0]
self.dumpTsInfo()
- self.assertResult([txmbr1,txmbr2,txmbr3])
+ self.assertResult([txmbr1.primary,txmbr2.primary,txmbr3])
def testGetFromTransaction(self):
''' test getting from Transaction '''
@@ -105,8 +105,8 @@ class TransactionDataTests(unittest.TestCase):
def testAddUpdatesAndObsoletes(self):
''' test addUpdated,addObsoleted'''
- txmbr1 = self.tsInfo.addUpdated(self.foo1,self.foo2)
- txmbr2 = self.tsInfo.addObsoleted(self.bar1,self.bar2)
+ txmbr1 = self.tsInfo.addUpdated(self.foo1,self.foo2).primary
+ txmbr2 = self.tsInfo.addObsoleted(self.bar1,self.bar2).primary
self.dumpTsInfo()
self.assertResult([txmbr1,txmbr2])
txmbr = self.tsInfo.getMembersWithState(output_states=[TS_UPDATED])[0]
diff --git a/yum/__init__.py b/yum/__init__.py
index 35b44d4..e26cd1d 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -2184,19 +2184,22 @@ class YumBase(depsolve.Depsolve):
# - better error handling/reporting
- tx_return = []
+ result = transactioninfo.AdditionResult()
for po in pkgs:
if self.tsInfo.exists(pkgtup=po.pkgtup):
- if self.tsInfo.getMembersWithState(po.pkgtup, TS_INSTALL_STATES):
+ found = False
+ for txmbr in self.tsInfo.getMembersWithState(po.pkgtup, TS_INSTALL_STATES):
+ found = True
self.verbose_logger.log(logginglevels.DEBUG_1,
_('Package: %s - already in transaction set'), po)
- tx_return.extend(self.tsInfo.getMembers(pkgtup=po.pkgtup))
+ result.addMember(txmbr) # XXX ERASE members???
+ if found:
continue
# make sure this shouldn't be passed to update:
if self.up.updating_dict.has_key(po.pkgtup):
- txmbrs = self.update(po=po)
- tx_return.extend(txmbrs)
+ res = self.update(po=po)
+ result.add(res)
continue
# make sure it's not already installed
@@ -2210,8 +2213,8 @@ class YumBase(depsolve.Depsolve):
if self.rpmdb.contains(name=po.name, arch=po.arch) and not self.allowedMultipleInstalls(po):
if not self.tsInfo.getMembersWithState(po.pkgtup, TS_REMOVE_STATES):
self.verbose_logger.warning(_('Package matching %s already installed. Checking for update.'), po)
- txmbrs = self.update(po=po)
- tx_return.extend(txmbrs)
+ res = self.update(po=po)
+ result.add(res)
continue
# make sure we're not installing a package which is obsoleted by something
@@ -2222,13 +2225,13 @@ class YumBase(depsolve.Depsolve):
obsoleting_pkg = self.getPackageObject(obsoleting)
self.verbose_logger.warning(_('Package %s is obsoleted by %s, trying to install %s instead'),
po.name, obsoleting_pkg.name, obsoleting_pkg)
- self.install(po=obsoleting_pkg)
+ self.install(po=obsoleting_pkg) # XXX result???
continue
- txmbr = self.tsInfo.addInstall(po)
- tx_return.append(txmbr)
+ res = self.tsInfo.addInstall(po)
+ result.add(res)
- return tx_return
+ return result
def update(self, po=None, requiringPo=None, **kwargs):
@@ -2251,17 +2254,17 @@ class YumBase(depsolve.Depsolve):
else:
obsoletes = []
- tx_return = []
+ result = transactioninfo.AdditionResult()
if not po and not kwargs: # update everything (the easy case)
self.verbose_logger.log(logginglevels.DEBUG_2, _('Updating Everything'))
for (obsoleting, installed) in obsoletes:
obsoleting_pkg = self.getPackageObject(obsoleting)
installed_pkg = self.rpmdb.searchPkgTuple(installed)[0]
- txmbr = self.tsInfo.addObsoleting(obsoleting_pkg, installed_pkg)
- self.tsInfo.addObsoleted(installed_pkg, obsoleting_pkg)
+ res = self.tsInfo.addObsoleting(obsoleting_pkg, installed_pkg)
+ self.tsInfo.addObsoleted(installed_pkg, obsoleting_pkg) # XXX result???
if requiringPo:
- txmbr.setAsDep(requiringPo)
- tx_return.append(txmbr)
+ res.primary.setAsDep(requiringPo)
+ result.add(res)
for (new, old) in updates:
if self.tsInfo.isObsoleted(pkgtup=old):
@@ -2270,12 +2273,12 @@ class YumBase(depsolve.Depsolve):
else:
updating_pkg = self.getPackageObject(new)
updated_pkg = self.rpmdb.searchPkgTuple(old)[0]
- txmbr = self.tsInfo.addUpdate(updating_pkg, updated_pkg)
+ res = self.tsInfo.addUpdate(updating_pkg, updated_pkg)
if requiringPo:
- txmbr.setAsDep(requiringPo)
- tx_return.append(txmbr)
+ res.primary.setAsDep(requiringPo)
+ result.add(res)
- return tx_return
+ return result
# complications
# the user has given us something - either a package object to be
@@ -2343,23 +2346,23 @@ class YumBase(depsolve.Depsolve):
for obsoleting in self.up.obsoleted_dict.get(installed_pkg.pkgtup, []):
obsoleting_pkg = self.getPackageObject(obsoleting)
# FIXME check for what might be in there here
- txmbr = self.tsInfo.addObsoleting(obsoleting_pkg, installed_pkg)
- self.tsInfo.addObsoleted(installed_pkg, obsoleting_pkg)
+ res = self.tsInfo.addObsoleting(obsoleting_pkg, installed_pkg)
+ self.tsInfo.addObsoleted(installed_pkg, obsoleting_pkg) # XXX result???
if requiringPo:
- txmbr.setAsDep(requiringPo)
- tx_return.append(txmbr)
+ res.primary.setAsDep(requiringPo)
+ result.add(res)
for available_pkg in availpkgs:
for obsoleted in self.up.obsoleting_dict.get(available_pkg.pkgtup, []):
obsoleted_pkg = self.getInstalledPackageObject(obsoleted)
- txmbr = self.tsInfo.addObsoleting(available_pkg, obsoleted_pkg)
+ res = self.tsInfo.addObsoleting(available_pkg, obsoleted_pkg)
if requiringPo:
- txmbr.setAsDep(requiringPo)
- tx_return.append(txmbr)
+ res.primary.setAsDep(requiringPo)
+ result.add(res)
if self.tsInfo.isObsoleted(obsoleted):
self.verbose_logger.log(logginglevels.DEBUG_2, _('Package is already obsoleted: %s.%s %s:%s-%s'), obsoleted)
else:
- txmbr = self.tsInfo.addObsoleted(obsoleted_pkg, available_pkg)
- tx_return.append(txmbr)
+ res = self.tsInfo.addObsoleted(obsoleted_pkg, available_pkg)
+ result.add(res)
for installed_pkg in instpkgs:
for updating in self.up.updatesdict.get(installed_pkg.pkgtup, []):
@@ -2368,10 +2371,10 @@ class YumBase(depsolve.Depsolve):
self.verbose_logger.log(logginglevels.DEBUG_2, _('Not Updating Package that is already obsoleted: %s.%s %s:%s-%s'),
installed_pkg.pkgtup)
else:
- txmbr = self.tsInfo.addUpdate(updating_pkg, installed_pkg)
+ res = self.tsInfo.addUpdate(updating_pkg, installed_pkg)
if requiringPo:
- txmbr.setAsDep(requiringPo)
- tx_return.append(txmbr)
+ res.primary.setAsDep(requiringPo)
+ result.add(res)
for available_pkg in availpkgs:
@@ -2385,10 +2388,10 @@ class YumBase(depsolve.Depsolve):
else:
updated_pkg = self.rpmdb.searchPkgTuple(updated)[0]
- txmbr = self.tsInfo.addUpdate(available_pkg, updated_pkg)
+ res = self.tsInfo.addUpdate(available_pkg, updated_pkg)
if requiringPo:
- txmbr.setAsDep(requiringPo)
- tx_return.append(txmbr)
+ res.primary.setAsDep(requiringPo)
+ result.add(res)
# check to see if the pkg we want to install is not _quite_ the newest
# one but still technically an update over what is installed.
@@ -2399,13 +2402,12 @@ class YumBase(depsolve.Depsolve):
pot_updated = self.rpmdb.searchNevra(name=available_pkg.name, arch=available_pkg.arch)
for ipkg in pot_updated:
if ipkg.EVR < available_pkg.EVR:
- txmbr = self.tsInfo.addUpdate(available_pkg, ipkg)
+ res = self.tsInfo.addUpdate(available_pkg, ipkg)
if requiringPo:
- txmbr.setAsDep(requiringPo)
- tx_return.append(txmbr)
-
+ res.primary.setAsDep(requiringPo)
+ result.add(res)
- return tx_return
+ return result
def remove(self, po=None, **kwargs):
@@ -2417,7 +2419,7 @@ class YumBase(depsolve.Depsolve):
if not po and not kwargs:
raise Errors.RemoveError, 'Nothing specified to remove'
- tx_return = []
+ result = transactioninfo.AdditionResult()
pkgs = []
@@ -2456,10 +2458,10 @@ class YumBase(depsolve.Depsolve):
self.logger.warning(_("No package matched to remove"))
for po in pkgs:
- txmbr = self.tsInfo.addErase(po)
- tx_return.append(txmbr)
+ res = self.tsInfo.addErase(po)
+ result.add(res)
- return tx_return
+ return result
def installLocal(self, pkg, po=None, updateonly=False):
"""
@@ -2478,7 +2480,7 @@ class YumBase(depsolve.Depsolve):
# check if it can be installed or updated based on nevra versus rpmdb
# don't import the repos until we absolutely need them for depsolving
- tx_return = []
+ result = transactioninfo.AdditionResult()
installpkgs = []
updatepkgs = []
donothingpkgs = []
@@ -2488,7 +2490,7 @@ class YumBase(depsolve.Depsolve):
po = YumLocalPackage(ts=self.rpmdb.readOnlyTS(), filename=pkg)
except Errors.MiscError:
self.logger.critical(_('Cannot open file: %s. Skipping.'), pkg)
- return tx_return
+ return result
self.verbose_logger.log(logginglevels.INFO_2,
_('Examining %s: %s'), po.localpath, po)
@@ -2498,7 +2500,7 @@ class YumBase(depsolve.Depsolve):
if len(installedByKey) == 0: # nothing installed by that name
if updateonly:
self.logger.warning(_('Package %s not installed, cannot update it. Run yum install to install it instead.'), po.name)
- return tx_return
+ return result
else:
installpkgs.append(po)
@@ -2531,26 +2533,25 @@ class YumBase(depsolve.Depsolve):
if po in toexc:
self.verbose_logger.debug(_('Excluding %s'), po)
- return tx_return
+ return result
for po in installpkgs:
self.verbose_logger.log(logginglevels.INFO_2,
_('Marking %s to be installed'), po.localpath)
self.localPackages.append(po)
- tx_return.extend(self.install(po=po))
+ result.add(self.install(po=po))
for (po, oldpo) in updatepkgs:
self.verbose_logger.log(logginglevels.INFO_2,
_('Marking %s as an update to %s'), po.localpath, oldpo)
self.localPackages.append(po)
- txmbr = self.tsInfo.addUpdate(po, oldpo)
- tx_return.append(txmbr)
+ result.add(self.tsInfo.addUpdate(po, oldpo))
for po in donothingpkgs:
self.verbose_logger.log(logginglevels.INFO_2,
_('%s: does not update installed package.'), po.localpath)
- return tx_return
+ return result
def reinstall(self, po=None, **kwargs):
"""Setup the problem filters to allow a reinstall to work, then
@@ -2563,9 +2564,8 @@ class YumBase(depsolve.Depsolve):
if rpm.RPMPROB_FILTER_REPLACEOLDFILES not in self.tsInfo.probFilterFlags:
self.tsInfo.probFilterFlags.append(rpm.RPMPROB_FILTER_REPLACEOLDFILES)
- tx_mbrs = []
- tx_mbrs.extend(self.remove(po, **kwargs))
- if not tx_mbrs:
+ result = self.remove(po, **kwargs)
+ if not tx_mbrs.transactionChanged():
raise Errors.ReinstallError, _("Problem in reinstall: no package matched to remove")
templen = len(tx_mbrs)
# this is a reinstall, so if we can't reinstall exactly what we uninstalled
diff --git a/yum/depsolve.py b/yum/depsolve.py
index ead17b7..c738fe3 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -282,8 +282,8 @@ class Depsolve(object):
if remove_txmbr and remove_txmbr.ts_state=='e' and not (remove_txmbr.obsoleted_by or remove_txmbr.updated_by):
self.verbose_logger.log(logginglevels.DEBUG_2, _('TSINFO: %s package requiring %s marked as erase'),
requiringPo, needname)
- txmbr = self.tsInfo.addErase(requiringPo)
- txmbr.setAsDep(po=remove_txmbr.po)
+ res = self.tsInfo.addErase(requiringPo)
+ res.primary.setAsDep(po=remove_txmbr.po)
checkdeps = 1
return checkdeps, missingdep
@@ -383,13 +383,12 @@ class Depsolve(object):
# try updating the already install pkgs
for pkg in provSack.returnNewestByName():
- results = self.update(requiringPo=requiringPo, name=pkg.name,
- epoch=pkg.epoch, version=pkg.version,
- rel=pkg.rel)
- for txmbr in results:
- if pkg == txmbr.po:
- checkdeps = True
- return checkdeps, missingdep
+ result = self.update(requiringPo=requiringPo, name=pkg.name,
+ epoch=pkg.epoch, version=pkg.version,
+ rel=pkg.rel)
+ if result.transactionChanged():
+ checkdeps = True
+ return checkdeps, missingdep
# find out which arch of the ones we can choose from is closest
# to the arch of the requesting pkg
@@ -421,14 +420,14 @@ class Depsolve(object):
self.verbose_logger.debug(_('TSINFO: Marking %s as update for %s') %(best,
requiringPo))
# FIXME: we should probably handle updating multiple packages...
- txmbr = self.tsInfo.addUpdate(best, inst[0])
- txmbr.setAsDep(po=requiringPo)
- txmbr.reason = "dep"
+ res = self.tsInfo.addUpdate(best, inst[0])
+ res.primary.setAsDep(po=requiringPo)
+ res.primary.reason = "dep"
else:
self.verbose_logger.debug(_('TSINFO: Marking %s as install for %s'), best,
requiringPo)
- txmbr = self.tsInfo.addInstall(best)
- txmbr.setAsDep(po=requiringPo)
+ res = self.tsInfo.addInstall(best)
+ res.primary.setAsDep(po=requiringPo)
# if we had other packages with this name.arch that we found
# before, they're not going to be installed anymore, so we
diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py
index b7fdd1e..a6336c7 100644
--- a/yum/transactioninfo.py
+++ b/yum/transactioninfo.py
@@ -172,9 +172,11 @@ class TransactionData:
def add(self, txmember):
"""add a package to the transaction"""
+ result = AdditionResult()
for oldpo in txmember.updates:
- self.addUpdated(oldpo, txmember.po)
+ res = self.addUpdated(oldpo, txmember.po)
+ result.add(res)
if not self.pkgdict.has_key(txmember.pkgtup):
self.pkgdict[txmember.pkgtup] = []
@@ -183,7 +185,11 @@ class TransactionData:
for member in self.pkgdict[txmember.pkgtup]:
if member.ts_state == txmember.ts_state:
self.debugprint("Package in same mode, skipping.")
- return
+ result.setPrimaryMember(member, new=False)
+ return result
+
+ result.setPrimaryMember(txmember)
+
self.pkgdict[txmember.pkgtup].append(txmember)
self._namedict.setdefault(txmember.name, []).append(txmember)
self.changed = True
@@ -196,15 +202,18 @@ class TransactionData:
for po in self.conditionals[txmember.name]:
if self.rpmdb.contains(po=po):
continue
- condtxmbr = self.addInstall(po)
- condtxmbr.setAsDep(po=txmember.po)
+ res = self.addInstall(po, True)
+ result.addConditionals(res)
+ res.primary.setAsDep(po=txmember.po)
+
self._unresolvedMembers.add(txmember)
+ return result
def remove(self, pkgtup):
"""remove a package from the transaction"""
if not self.pkgdict.has_key(pkgtup):
self.debugprint("Package: %s not in ts" %(pkgtup,))
- return
+ return []
for txmbr in self.pkgdict[pkgtup]:
txmbr.po.state = None
if self._isLocalPackage(txmbr):
@@ -214,10 +223,12 @@ class TransactionData:
self._namedict[txmbr.name].remove(txmbr)
self._unresolvedMembers.add(txmbr)
+ result = self.pkgdict[pkgtup]
del self.pkgdict[pkgtup]
if not self._namedict[pkgtup[0]]:
del self._namedict[pkgtup[0]]
- self.changed = True
+ self.changed = True
+ return result
def exists(self, pkgtup):
"""tells if the pkg is in the class"""
@@ -310,8 +321,7 @@ class TransactionData:
txmbr.po.state = TS_INSTALL
txmbr.ts_state = 'u'
txmbr.reason = 'user'
- self.add(txmbr)
- return txmbr
+ return self.add(txmbr)
def addTrueInstall(self, po):
"""adds a package as an install
@@ -323,9 +333,7 @@ class TransactionData:
txmbr.po.state = TS_INSTALL
txmbr.ts_state = 'i'
txmbr.reason = 'user'
- self.add(txmbr)
- return txmbr
-
+ return self.add(txmbr)
def addErase(self, po):
"""adds a package as an erasure
@@ -336,8 +344,7 @@ class TransactionData:
txmbr.output_state = TS_ERASE
txmbr.po.state = TS_INSTALL
txmbr.ts_state = 'e'
- self.add(txmbr)
- return txmbr
+ return self.add(txmbr)
def addUpdate(self, po, oldpo=None):
"""adds a package as an update
@@ -355,8 +362,7 @@ class TransactionData:
txmbr.relatedto.append((oldpo, 'updates'))
txmbr.updates.append(oldpo)
- self.add(txmbr)
- return txmbr
+ return self.add(txmbr)
def addUpdated(self, po, updating_po):
"""adds a package as being updated by another pkg
@@ -369,8 +375,7 @@ class TransactionData:
txmbr.ts_state = None
txmbr.relatedto.append((updating_po, 'updatedby'))
txmbr.updated_by.append(updating_po)
- self.add(txmbr)
- return txmbr
+ return self.add(txmbr)
def addObsoleting(self, po, oldpo):
"""adds a package as an obsolete over another pkg
@@ -383,8 +388,7 @@ class TransactionData:
txmbr.ts_state = 'u'
txmbr.relatedto.append((oldpo, 'obsoletes'))
txmbr.obsoletes.append(oldpo)
- self.add(txmbr)
- return txmbr
+ return self.add(txmbr)
def addObsoleted(self, po, obsoleting_po):
"""adds a package as being obsoleted by another pkg
@@ -397,8 +401,7 @@ class TransactionData:
txmbr.ts_state = None
txmbr.relatedto.append((obsoleting_po, 'obsoletedby'))
txmbr.obsoleted_by.append(obsoleting_po)
- self.add(txmbr)
- return txmbr
+ return self.add(txmbr)
def setDatabases(self, rpmdb, pkgSack):
@@ -515,6 +518,52 @@ class SortableTransactionData(TransactionData):
self._sorted.reverse()
return self._sorted
+class AdditionResult:
+ def __init__(self, txmbr=None):
+ self.primary = txmbr
+ self.new = set()
+ self.all = set()
+ self.new_conditionals = set()
+ self.all_conditionals = set()
+
+ def setPrimaryMember(self, txmbr, new=True):
+ if self.primary:
+ raise ValueError, "Primary already set"
+ self.primary = txmbr
+ self.all.add(txmbr)
+ if new:
+ self.new.add(txmbr)
+
+ def addNewMember(self, txmbr):
+ self.all.add(txmbr)
+ self.new.add(txmbr)
+
+ def addMember(self, txmbr):
+ self.all.add(txmbr)
+
+ def addNewConditional(self, txmbr):
+ self.new_conditionals.add(txmbr)
+ self.all_conditionals.add(txmbr)
+
+ def addConditional(self, txmbr):
+ self.all_conditionals.add(txmbr)
+
+ def removeMember(self, txmbr):
+ self.new.discard(txmbr)
+ self.all.discard(txmbr)
+ self.new_conditionals.discard(txmbr)
+ self.all_conditionals.discard(txmbr)
+ if self.primary is txmbr:
+ self.primary = None
+
+ def add(self, other):
+ for attr in ('new', 'all', 'new_conditionals', 'all_conditionals'):
+ getattr(self, attr).update(getattr(other, attr))
+
+ def transactionChanged(self):
+ return bool(self.new) | bool(self.new_conditionals)
+
+
class TransactionMember:
"""Class to describe a Transaction Member (a pkg to be installed/
updated/erased)."""
More information about the Yum-cvs-commits
mailing list