[yum] update tolatest head including the orphan removal code and skipbroken debug output
Seth Vidal
skvidal at fedoraproject.org
Tue Nov 9 20:56:44 UTC 2010
commit 7b961396ddd00e6431e0895f92493deb04199595
Author: Seth Vidal <skvidal at fedoraproject.org>
Date: Tue Nov 9 15:56:42 2010 -0500
update tolatest head including the orphan removal code and skipbroken debug output
yum-HEAD.patch | 359 +++++++++++++++++++++++++++++++++++++++++++++-----------
yum.spec | 5 +-
2 files changed, 295 insertions(+), 69 deletions(-)
---
diff --git a/yum-HEAD.patch b/yum-HEAD.patch
index bb3be4f..303eb81 100644
--- a/yum-HEAD.patch
+++ b/yum-HEAD.patch
@@ -332,7 +332,7 @@ index 281bf17..111cda6 100644
Eliminate any cached data from the local rpmdb.
diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
-index 49d98c6..899e950 100644
+index 49d98c6..ff10251 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -80,9 +80,13 @@ Full directory and file name for where yum should write its log file.
@@ -416,7 +416,24 @@ index 49d98c6..899e950 100644
It's also possible to use the word "never", meaning that the metadata will
never expire. Note that when using a metalink file the metalink must always
be newer than the metadata for the repository, due to the validation, so this
-@@ -734,6 +753,17 @@ If this is unset it inherits it from the global setting
+@@ -536,6 +555,16 @@ be downloaded. The updates list is what is printed when you run "yum update",
+ Default is `normal'.
+ See color_list_installed_older for possible values.
+
++
++.IP
++\fBclean_requirements_on_remove \fR
++When removing packages (by removal, update or obsoletion) go through each
++package's dependencies. If any of them are no longer required by any other
++package then also mark them to be removed.
++Boolean (1, 0, True, False, yes,no) Defaults to False
++
++
++
+ .SH "[repository] OPTIONS"
+ .LP
+ The repository section(s) take the following form:
+@@ -734,6 +763,17 @@ If this is unset it inherits it from the global setting
password for this proxy.
If this is unset it inherits it from the global setting
@@ -37515,10 +37532,36 @@ index df641f7..6bc2efe 100644
+ self.assert_(res=='ok', msg)
+ self.assertResult((pa1, pa2))
diff --git a/test/skipbroken-tests.py b/test/skipbroken-tests.py
-index 43b0726..c1d0c1f 100644
+index 43b0726..9f09e87 100644
--- a/test/skipbroken-tests.py
+++ b/test/skipbroken-tests.py
-@@ -626,6 +626,7 @@ class SkipBrokenTests(DepsolveTests):
+@@ -598,7 +598,24 @@ class SkipBrokenTests(DepsolveTests):
+ self.tsInfo.addUpdate(u1, oldpo=i2)
+ self.assertEquals('empty', *self.resolveCode(skip=True))
+ self.assertResult([i1,i2])
+-
++
++ def testDowngrade1(self):
++ '''
++ bar require foolib=2.0 provided by foo-1.2
++ foo-1.2 is downgraded to foo-1.1 there only contains foolib=1.0
++ so bar requirement is broken and the downgrade should be removed from
++ transaction
++ '''
++ i1 = self.instPackage('foo', '1.2')
++ i1.addProvides('foolib', 'EQ', ('0', '2', '0'))
++ i2 = self.instPackage('bar', '1.0')
++ i2.addRequires('foolib', 'EQ', ('0', '2', '0'))
++ d1 = self.repoPackage('foo', '1.1')
++ d1.addProvides('foolib', 'EQ', ('0', '1', '0'))
++ self.tsInfo.addDowngrade(d1, oldpo=i1)
++ self.assertEquals('empty', *self.resolveCode(skip=True))
++ self.assertResult([i1, i2])
++
+
+ def testMissingfileReqIptabes(self):
+ '''
+@@ -626,6 +643,7 @@ class SkipBrokenTests(DepsolveTests):
def resolveCode(self,skip = False):
solver = YumBase()
@@ -37527,7 +37570,7 @@ index 43b0726..c1d0c1f 100644
solver.conf = FakeConf()
solver.conf.skip_broken = skip
diff --git a/test/testbase.py b/test/testbase.py
-index f91fbf1..81591ad 100644
+index f91fbf1..4d7bd8d 100644
--- a/test/testbase.py
+++ b/test/testbase.py
@@ -27,6 +27,10 @@ from rpmUtils.transaction import initReadOnlyTransaction
@@ -37541,20 +37584,48 @@ index f91fbf1..81591ad 100644
class FakeConf(object):
def __init__(self):
-@@ -128,8 +132,10 @@ class DepSolveProgressCallBack:
+@@ -47,6 +51,7 @@ class FakeConf(object):
+ self.uid = 0
+ self.groupremove_leaf_only = False
+ self.protected_packages = []
++ self.clean_requirements_on_remove = True
+
+ class FakeSack:
+ """ Fake PackageSack to use with FakeRepository"""
+@@ -112,6 +117,10 @@ class FakePackage(packages.YumAvailablePackage):
+ self.prco['obsoletes'].append((name, flag, evr))
+ def addFile(self, name, ftype='file'):
+ self.files[ftype].append(name)
++ def required_packages(self):
++ return []
++ def requiring_packages(self):
++ return []
+
+ class _Container(object):
+ pass
+@@ -127,13 +136,17 @@ class DepSolveProgressCallBack:
+
def pkgAdded(self, pkgtup, mode):
modedict = { 'i': _('installed'),
- 'u': _('updated'),
+- 'u': _('updated'),
- 'o': _('obsoleted'),
- 'e': _('erased')}
-+ 'od': _('obsoleted'),
-+ 'o': _('obsoleting'),
++ 'u': _('an update'),
+ 'e': _('erased'),
-+ 'ud':_('update'),}
++ 'r': _('reinstalled'),
++ 'd': _('a downgrade'),
++ 'o': _('obsoleting'),
++ 'ud': _('updated'),
++ 'od': _('obsoleted'),}
(n, a, e, v, r) = pkgtup
modeterm = modedict[mode]
self.verbose_logger.log(logginglevels.INFO_2,
-@@ -356,9 +362,9 @@ class DepsolveTests(_DepsolveTestsBase):
+- _('---> Package %s.%s %s:%s-%s set to be %s'), n, a, e, v, r,
++ _('---> Package %s.%s %s:%s-%s will be %s'), n, a, e, v, r,
+ modeterm)
+
+ def start(self):
+@@ -356,9 +369,9 @@ class DepsolveTests(_DepsolveTestsBase):
def resetTsInfo(self):
self.tsInfo = transactioninfo.TransactionData()
@@ -37565,7 +37636,7 @@ index f91fbf1..81591ad 100644
solver.conf = FakeConf()
solver.arch.setup_arch('x86_64')
solver.tsInfo = solver._tsInfo = self.tsInfo
-@@ -399,7 +405,7 @@ class OperationsTests(_DepsolveTestsBase):
+@@ -399,7 +412,7 @@ class OperationsTests(_DepsolveTestsBase):
"""
def runOperation(self, args, installed=[], available=[],
@@ -37574,7 +37645,7 @@ index f91fbf1..81591ad 100644
"""Sets up and runs the depsolver. args[0] must be a valid yum command
("install", "update", ...). It might be followed by pkg names as on the
yum command line. The pkg objects in installed are added to self.rpmdb and
-@@ -407,6 +413,7 @@ class OperationsTests(_DepsolveTestsBase):
+@@ -407,6 +420,7 @@ class OperationsTests(_DepsolveTestsBase):
requirements from.
"""
depsolver = YumBaseCli()
@@ -37582,7 +37653,7 @@ index f91fbf1..81591ad 100644
depsolver.arch.setup_arch('x86_64')
self.rpmdb = depsolver.rpmdb = FakeRpmDb()
self.xsack = depsolver._pkgSack = packageSack.PackageSack()
-@@ -428,9 +435,18 @@ class OperationsTests(_DepsolveTestsBase):
+@@ -428,9 +442,18 @@ class OperationsTests(_DepsolveTestsBase):
po.repoid = po.repo.id
self.depsolver._pkgSack.addPackage(po)
@@ -37659,7 +37730,7 @@ index c3c7133..fc05aa6 100644
Requires: python-iniparse
Requires: pygpgme
diff --git a/yum/__init__.py b/yum/__init__.py
-index 2ea9f20..234b599 100644
+index 2ea9f20..a588dc8 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -21,6 +21,19 @@ The Yum RPM software updater.
@@ -37760,7 +37831,19 @@ index 2ea9f20..234b599 100644
# feed it into _tags.add()
self._tags.add(repo.id, tag_sqlite)
except (Errors.RepoError, Errors.PkgTagsError), e:
-@@ -976,8 +1001,8 @@ class YumBase(depsolve.Depsolve):
+@@ -909,7 +934,10 @@ class YumBase(depsolve.Depsolve):
+
+ (rescode, restring) = self.resolveDeps()
+ self._limit_installonly_pkgs()
+-
++ # if enabled clean up requirments when removing the things which brought them in.
++ if self.conf.clean_requirements_on_remove:
++ self.verbose_logger.log(logginglevels.INFO_2, _('--> Finding unneeded leftover dependencies'))
++ self._remove_old_deps()
+ # We _must_ get rid of all the used tses before we go on, so that C-c
+ # works for downloads / mirror failover etc.
+ kern_pkgtup = None
+@@ -976,8 +1004,8 @@ class YumBase(depsolve.Depsolve):
restring.append(_('Trying to remove "%s", which is protected') %
pkgname)
@@ -37771,7 +37854,55 @@ index 2ea9f20..234b599 100644
self.verbose_logger.debug('Depsolve time: %0.3f' % (time.time() - ds_st))
return rescode, restring
-@@ -1311,7 +1336,10 @@ class YumBase(depsolve.Depsolve):
+@@ -1032,7 +1060,7 @@ class YumBase(depsolve.Depsolve):
+ # and skip-broken shouldn't care too much about speed.
+ self.rpmdb.transactionReset()
+ self.installedFileRequires = None # Kind of hacky
+- self.verbose_logger.debug(_("Skip-broken round %i"), count)
++ self.verbose_logger.debug("SKIPBROKEN: ########### Round %i ################" , count)
+ self._printTransaction()
+ depTree = self._buildDepTree()
+ startTs = set(self.tsInfo)
+@@ -1089,7 +1117,7 @@ class YumBase(depsolve.Depsolve):
+ self._checkUpdatedLeftovers() # Cleanup updated leftovers
+ rescode, restring = self.resolveDeps()
+ if rescode != 1:
+- self.verbose_logger.debug(_("Skip-broken took %i rounds "), count)
++ self.verbose_logger.debug("SKIPBROKEN: took %i rounds ", count)
+ self.verbose_logger.info(_('\nPackages skipped because of dependency problems:'))
+ skipped_list = [p for p in skipped_po]
+ skipped_list.sort()
+@@ -1203,14 +1231,14 @@ class YumBase(depsolve.Depsolve):
+ TS_AVAILABLE : "available",
+ TS_UPDATED : "updated"}
+
+- self.verbose_logger.log(logginglevels.DEBUG_2,"TSINFO: Current Transaction : %i member(s) " % len(self.tsInfo))
++ self.verbose_logger.log(logginglevels.DEBUG_2,"SKIPBROKEN: Current Transaction : %i member(s) " % len(self.tsInfo))
+ for txmbr in sorted(self.tsInfo):
+- msg = " %-11s : %s " % (state[txmbr.output_state],txmbr.po)
++ msg = "SKIPBROKEN: %-11s : %s " % (state[txmbr.output_state],txmbr.po)
+ self.verbose_logger.log(logginglevels.DEBUG_2, msg)
+ for po,rel in sorted(txmbr.relatedto):
+- msg = " %s : %s" % (rel,po)
++ msg = "SKIPBROKEN: %s : %s" % (rel,po)
+ self.verbose_logger.log(logginglevels.DEBUG_2, msg)
+-
++ self.verbose_logger.log(logginglevels.DEBUG_2,"SKIPBROKEN:%s" % (60 * "="))
+
+ def _getPackagesToRemove(self,po,deptree,toRemove):
+ '''
+@@ -1221,6 +1249,10 @@ class YumBase(depsolve.Depsolve):
+ for pkg in (txmbr.updates + txmbr.obsoletes):
+ toRemove.add(pkg)
+ self._getDepsToRemove(pkg, deptree, toRemove)
++ # Remove related packages
++ for (relative, relation) in txmbr.relatedto:
++ toRemove.add(relative)
++ self._getDepsToRemove(relative, deptree, toRemove)
+ self._getDepsToRemove(po, deptree, toRemove)
+
+ def _getDepsToRemove(self,po, deptree, toRemove):
+@@ -1311,7 +1343,10 @@ class YumBase(depsolve.Depsolve):
self.run_with_package_names.add('yum-metadata-parser')
break
@@ -37783,7 +37914,7 @@ index 2ea9f20..234b599 100644
using_pkgs_pats = list(self.run_with_package_names)
using_pkgs = self.rpmdb.returnPackages(patterns=using_pkgs_pats)
rpmdbv = self.rpmdb.simpleVersion(main_only=True)[0]
-@@ -1330,10 +1358,14 @@ class YumBase(depsolve.Depsolve):
+@@ -1330,10 +1365,14 @@ class YumBase(depsolve.Depsolve):
cmdline = ' '.join(self.args)
elif hasattr(self, 'cmds') and self.cmds:
cmdline = ' '.join(self.cmds)
@@ -37798,7 +37929,7 @@ index 2ea9f20..234b599 100644
self.plugins.run('historybegin')
# Just before we update the transaction, update what we think the
-@@ -1341,8 +1373,15 @@ class YumBase(depsolve.Depsolve):
+@@ -1341,8 +1380,15 @@ class YumBase(depsolve.Depsolve):
# "something" happens and the rpmdb is different from what we think it
# will be we store what we thought, not what happened (so it'll be an
# invalid cache).
@@ -37815,7 +37946,7 @@ index 2ea9f20..234b599 100644
errors = self.ts.run(cb.callback, '')
# ts.run() exit codes are, hmm, "creative": None means all ok, empty
# list means some errors happened in the transaction and non-empty
-@@ -1382,7 +1421,9 @@ class YumBase(depsolve.Depsolve):
+@@ -1382,7 +1428,9 @@ class YumBase(depsolve.Depsolve):
except (IOError, OSError), e:
self.logger.critical(_('Failed to remove transaction file %s') % fn)
@@ -37826,7 +37957,7 @@ index 2ea9f20..234b599 100644
self.plugins.run('posttrans')
# sync up what just happened versus what is in the rpmdb
if not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST):
-@@ -1403,8 +1444,8 @@ class YumBase(depsolve.Depsolve):
+@@ -1403,8 +1451,8 @@ class YumBase(depsolve.Depsolve):
# that there is not also an install of this pkg in the tsInfo (reinstall)
# for any kind of install add from_repo to the yumdb, and the cmdline
# and the install reason
@@ -37837,7 +37968,7 @@ index 2ea9f20..234b599 100644
self.plugins.run('preverifytrans')
for txmbr in self.tsInfo:
if txmbr.output_state in TS_INSTALL_STATES:
-@@ -1482,13 +1523,15 @@ class YumBase(depsolve.Depsolve):
+@@ -1482,13 +1530,15 @@ class YumBase(depsolve.Depsolve):
self.verbose_logger.log(logginglevels.DEBUG_2, 'What is this? %s' % txmbr.po)
self.plugins.run('postverifytrans')
@@ -37854,7 +37985,7 @@ index 2ea9f20..234b599 100644
def costExcludePackages(self):
""" Create an excluder for repos. with higher cost. Eg.
-@@ -1836,6 +1879,10 @@ class YumBase(depsolve.Depsolve):
+@@ -1836,6 +1886,10 @@ class YumBase(depsolve.Depsolve):
self.plugins.run('postdownload', pkglist=pkglist, errors=errors)
@@ -37865,7 +37996,7 @@ index 2ea9f20..234b599 100644
return errors
def verifyHeader(self, fo, po, raiseError):
-@@ -1919,7 +1966,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1919,7 +1973,7 @@ class YumBase(depsolve.Depsolve):
- 2 - Fatal GPG verification error, give up.
'''
if hasattr(po, 'pkgtype') and po.pkgtype == 'local':
@@ -37874,7 +38005,7 @@ index 2ea9f20..234b599 100644
hasgpgkey = 0
else:
repo = self.repos.getRepo(po.repoid)
-@@ -2276,7 +2323,8 @@ class YumBase(depsolve.Depsolve):
+@@ -2276,7 +2330,8 @@ class YumBase(depsolve.Depsolve):
return results
# pre 3.2.10 API used to always showdups, so that's the default atm.
@@ -37884,7 +38015,7 @@ index 2ea9f20..234b599 100644
"""Generator method to lighten memory load for some searches.
This is the preferred search function to use. Setting keys to True
will use the search keys that matched in the sorting, and return
-@@ -2322,41 +2370,45 @@ class YumBase(depsolve.Depsolve):
+@@ -2322,41 +2377,45 @@ class YumBase(depsolve.Depsolve):
if len(tmpvalues) > 0:
sorted_lists[count].append((po, tmpkeys, tmpvalues))
@@ -37960,7 +38091,7 @@ index 2ea9f20..234b599 100644
# take our existing dict-by-pkg and make the dict-by-count for
# this bizarro sorted_lists format
-@@ -2887,7 +2939,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2887,7 +2946,7 @@ class YumBase(depsolve.Depsolve):
if len(dep_split) == 3:
depname, flagsymbol, depver = dep_split
if not flagsymbol in SYMBOLFLAGS:
@@ -37969,7 +38100,7 @@ index 2ea9f20..234b599 100644
depflags = SYMBOLFLAGS[flagsymbol]
return self.rpmdb.getProvides(depname, depflags, depver).keys()
-@@ -3100,6 +3152,9 @@ class YumBase(depsolve.Depsolve):
+@@ -3100,6 +3159,9 @@ class YumBase(depsolve.Depsolve):
def _find_obsoletees(self, po):
""" Return the pkgs. that are obsoleted by the po we pass in. """
@@ -37979,7 +38110,7 @@ index 2ea9f20..234b599 100644
if not isinstance(po, YumLocalPackage):
for (obstup, inst_tup) in self.up.getObsoletersTuples(name=po.name):
if po.pkgtup == obstup:
-@@ -3160,7 +3215,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3160,7 +3222,7 @@ class YumBase(depsolve.Depsolve):
try:
mypkgs = self.returnPackagesByDep(arg)
except yum.Errors.YumBaseError, e:
@@ -37988,7 +38119,7 @@ index 2ea9f20..234b599 100644
else:
# install MTA* == fail, because provides don't do globs
# install /usr/kerberos/bin/* == success (and we want
-@@ -3490,7 +3545,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3490,7 +3552,7 @@ class YumBase(depsolve.Depsolve):
availpkgs.extend(m)
if not availpkgs and not instpkgs:
@@ -37997,7 +38128,7 @@ index 2ea9f20..234b599 100644
else: # we have kwargs, sort them out.
nevra_dict = self._nevra_kwarg_parse(kwargs)
-@@ -3576,6 +3631,9 @@ class YumBase(depsolve.Depsolve):
+@@ -3576,6 +3638,9 @@ class YumBase(depsolve.Depsolve):
self.tsInfo.addObsoleted(obsoletee, po)
tx_return.append(txmbr)
else:
@@ -38007,7 +38138,7 @@ index 2ea9f20..234b599 100644
txmbr = self._add_up_txmbr(requiringPo, po, installed_pkg)
tx_return.append(txmbr)
-@@ -3599,6 +3657,9 @@ class YumBase(depsolve.Depsolve):
+@@ -3599,6 +3664,9 @@ class YumBase(depsolve.Depsolve):
else:
updated_pkg = self.getInstalledPackageObject(updated)
@@ -38017,7 +38148,7 @@ index 2ea9f20..234b599 100644
txmbr = self._add_up_txmbr(requiringPo,
available_pkg, updated_pkg)
tx_return.append(txmbr)
-@@ -3669,7 +3730,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3669,7 +3737,8 @@ class YumBase(depsolve.Depsolve):
self.logger.critical(_('%s') % e)
if not depmatches:
@@ -38027,7 +38158,7 @@ index 2ea9f20..234b599 100644
else:
pkgs.extend(depmatches)
-@@ -3690,6 +3752,14 @@ class YumBase(depsolve.Depsolve):
+@@ -3690,6 +3759,14 @@ class YumBase(depsolve.Depsolve):
if self.conf.protected_packages and po.pkgtup == kern_pkgtup:
self.logger.warning(_("Skipping the running kernel: %s") % po)
continue
@@ -38042,7 +38173,7 @@ index 2ea9f20..234b599 100644
txmbr = self.tsInfo.addErase(po)
tx_return.append(txmbr)
-@@ -3952,7 +4022,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3952,7 +4029,7 @@ class YumBase(depsolve.Depsolve):
EOL """
if not po and not kwargs:
@@ -38051,7 +38182,7 @@ index 2ea9f20..234b599 100644
doing_group_pkgs = False
if po:
-@@ -3975,7 +4045,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3975,7 +4052,7 @@ class YumBase(depsolve.Depsolve):
try:
apkgs = self.returnPackagesByDep(arg)
except yum.Errors.YumBaseError, e:
@@ -38060,7 +38191,7 @@ index 2ea9f20..234b599 100644
else:
nevra_dict = self._nevra_kwarg_parse(kwargs)
-@@ -4196,23 +4266,20 @@ class YumBase(depsolve.Depsolve):
+@@ -4196,23 +4273,20 @@ class YumBase(depsolve.Depsolve):
key_installed = False
self.logger.info(_('Retrieving GPG key from %s') % keyurl)
@@ -38090,7 +38221,7 @@ index 2ea9f20..234b599 100644
except urlgrabber.grabber.URLGrabError, e:
raise Errors.YumBaseError(_('GPG key retrieval failed: ') +
-@@ -4276,12 +4343,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4276,12 +4350,11 @@ class YumBase(depsolve.Depsolve):
keyurls = repo.gpgkey
key_installed = False
@@ -38104,7 +38235,7 @@ index 2ea9f20..234b599 100644
# Check if key is already installed
if misc.keyInstalled(ts, info['keyid'], info['timestamp']) >= 0:
self.logger.info(_('GPG key at %s (0x%s) is already installed') % (
-@@ -4306,6 +4372,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4306,6 +4379,7 @@ class YumBase(depsolve.Depsolve):
raise Errors.YumBaseError, _("Not installing key")
# Import the key
@@ -38112,7 +38243,7 @@ index 2ea9f20..234b599 100644
result = ts.pgpImportPubkey(misc.procgpgkey(info['raw_key']))
if result != 0:
raise Errors.YumBaseError, \
-@@ -4626,6 +4693,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4626,6 +4700,7 @@ class YumBase(depsolve.Depsolve):
newrepo = yumRepo.YumRepository(repoid)
newrepo.name = repoid
newrepo.basecachedir = self.conf.cachedir
@@ -38120,7 +38251,7 @@ index 2ea9f20..234b599 100644
var_convert = kwargs.get('variable_convert', True)
if baseurls:
-@@ -4722,3 +4790,214 @@ class YumBase(depsolve.Depsolve):
+@@ -4722,3 +4797,267 @@ class YumBase(depsolve.Depsolve):
self.plugins.run('verify_package', verify_package=verify_package)
return verify_package
@@ -38335,6 +38466,59 @@ index 2ea9f20..234b599 100644
+ raise Errors.YumBaseError(msg)
+
+ return self.tsInfo.getMembers()
++
++ def _remove_old_deps(self):
++ """take the set of pkgs being removed and remove any pkgs which are:
++ 1. not required anymore
++ 2. marked as a 'dep' in the 'reason' in the yumdb. """
++ found_leaves = set()
++ checked = set()
++ beingremoved = [ t.po for t in self.tsInfo.getMembersWithState(output_states=TS_REMOVE_STATES) ]
++ for pkg in beingremoved: # for each package required by the pkg being removed
++ #print 'removal: %s' % pkg.name
++ for required in pkg.required_packages():
++ #if required in checked:
++ # continue # if we've already checked it, skip it.
++ #checked.add(required)
++ if required.yumdb_info.get('reason', '') != 'dep': # if the required pkg is not a dep, then skip it
++ continue
++ if required in beingremoved:
++ continue
++ still_needed = False
++ for requiring in required.requiring_packages(): # so we have required deps - look at all the pkgs which require them
++ if requiring == required: # if they are self-requiring skip them
++ continue
++ if requiring not in beingremoved: # if the requiring pkg is not in the list of pkgs being removed then it is still needed
++ still_needed = True
++ break
++ # go through the stuff in the ts to be installed - make sure none of that needs the required pkg, either.
++ for (provn,provf,provevr) in required.provides:
++ if self.tsInfo.getNewRequires(provn, provf, provevr).keys():
++ still_needed = True
++ break
++ for fn in required.filelist + required.dirlist:
++ if self.tsInfo.getNewRequires(fn, None,(None,None,None)).keys():
++ still_needed = True
++ break
++
++ #for tbi_pkg in self.tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES):
++ # for reqtuple in tbi_pkg.po.requires:
++ # if required.provides_for(reqtuple):
++ # still_needed = True
++ # break
++
++ if not still_needed:
++ print '---> Marking %s to be removed - no longer needed by %s' % (required.name, pkg.name)
++ txmbrs = self.remove(po=required)
++
++ for txmbr in txmbrs:
++ txmbr.setAsDep(po=pkg)
++ if txmbr.po not in beingremoved:
++ beingremoved.append(txmbr.po)
++ found_leaves.add(txmbr)
++ self.verbose_logger.log(logginglevels.INFO_2, "Found and removing %s unneeded dependencies" % len(found_leaves))
++
++
diff --git a/yum/comps.py b/yum/comps.py
index 5ccfba2..408bb1c 100755
--- a/yum/comps.py
@@ -38345,7 +38529,7 @@ index 5ccfba2..408bb1c 100755
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
diff --git a/yum/config.py b/yum/config.py
-index 650d7b9..2f133ef 100644
+index 650d7b9..aecef44 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -645,6 +645,8 @@ class YumConf(StartupConf):
@@ -38365,17 +38549,18 @@ index 650d7b9..2f133ef 100644
obsoletes = BoolOption(True)
showdupesfromrepos = BoolOption(False)
enabled = BoolOption(True)
-@@ -737,6 +740,9 @@ class YumConf(StartupConf):
+@@ -737,6 +740,10 @@ class YumConf(StartupConf):
parse_default=True)
exit_on_lock = BoolOption(False)
+ loadts_ignoremissing = BoolOption(False)
+ loadts_ignorerpm = BoolOption(False)
+
++ clean_requirements_on_remove = BoolOption(False)
_reposlist = []
def dump(self):
-@@ -794,6 +800,8 @@ class RepoConf(BaseConfig):
+@@ -794,6 +801,8 @@ class RepoConf(BaseConfig):
proxy_password = Inherit(YumConf.proxy_password)
retries = Inherit(YumConf.retries)
failovermethod = Inherit(YumConf.failovermethod)
@@ -38394,7 +38579,7 @@ index 06d5a6b..5c728d4 100644
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
diff --git a/yum/depsolve.py b/yum/depsolve.py
-index e9b3fa7..3cc7a7f 100644
+index e9b3fa7..b0d1e80 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -38,7 +38,7 @@ import Errors
@@ -38406,7 +38591,7 @@ index e9b3fa7..3cc7a7f 100644
try:
assert max(2, 4) == 4
-@@ -376,6 +376,34 @@ class Depsolve(object):
+@@ -376,19 +376,47 @@ class Depsolve(object):
self.verbose_logger.log(logginglevels.DEBUG_2, _('Mode for pkg providing %s: %s'),
niceformatneed, needmode)
@@ -38441,7 +38626,11 @@ index e9b3fa7..3cc7a7f 100644
if needmode in ['e']:
self.verbose_logger.log(logginglevels.DEBUG_2, _('TSINFO: %s package requiring %s marked as erase'),
requiringPo, needname)
-@@ -384,11 +412,10 @@ class Depsolve(object):
+- txmbr = self.tsInfo.addErase(requiringPo)
+- txmbr.setAsDep(po=inst_po)
++ txmbrs = self.remove(po=requiringPo)
++ for txmbr in txmbrs:
++ txmbr.setAsDep(po=inst_po)
checkdeps = 1
if needmode in ['i', 'u']:
@@ -38456,7 +38645,7 @@ index e9b3fa7..3cc7a7f 100644
if txmbrs[0].output_state == TS_OBSOLETED:
self.verbose_logger.log(logginglevels.DEBUG_2, _('TSINFO: Obsoleting %s with %s to resolve dep.'),
requiringPo, txmbrs[0].obsoleted_by[0])
-@@ -778,6 +805,7 @@ class Depsolve(object):
+@@ -778,6 +806,7 @@ class Depsolve(object):
if not len(self.tsInfo):
return (0, [_('Success - empty transaction')])
@@ -38464,7 +38653,7 @@ index e9b3fa7..3cc7a7f 100644
return (2, [_('Success - deps resolved')])
def _resolveRequires(self, errors):
-@@ -795,8 +823,11 @@ class Depsolve(object):
+@@ -795,8 +824,11 @@ class Depsolve(object):
dscb_ts_state = 'd'
if dscb_ts_state == 'u' and txmbr.reinstall:
dscb_ts_state = 'r'
@@ -38478,7 +38667,7 @@ index e9b3fa7..3cc7a7f 100644
self.dsCallback.pkgAdded(txmbr.pkgtup, dscb_ts_state)
self.verbose_logger.log(logginglevels.DEBUG_2,
_("Checking deps for %s") %(txmbr,))
-@@ -1092,6 +1123,10 @@ class Depsolve(object):
+@@ -1092,6 +1124,10 @@ class Depsolve(object):
continue
ret.append( (po, self._prco_req_nfv2req(r, f, v),
conflicting_po) )
@@ -38489,7 +38678,7 @@ index e9b3fa7..3cc7a7f 100644
self.rpmdb.transactionCacheConflictPackages(cpkgs)
return ret
-@@ -1195,6 +1230,10 @@ class Depsolve(object):
+@@ -1195,6 +1231,10 @@ class Depsolve(object):
# We get here from bestPackagesFromList(), give a giant
# bump to stuff that is already installed.
pkgresults[pkg] += 1000
@@ -39250,10 +39439,44 @@ index afc7947..31b1080 100755
if cpeid:
tag = """ <distro cpeid="%s">%s</distro>\n""" % (
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
-index ae73c32..346decc 100644
+index ae73c32..e227729 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
-@@ -195,13 +195,20 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -78,8 +78,32 @@ class RPMInstalledPackage(YumInstalledPackage):
+ # Also note that pkg.no_value raises KeyError.
+
+ return val
++
++ def requiring_packages(self):
++ """return list of installed pkgs requiring this package"""
++ pkgset = set()
++ for (reqn, reqf, reqevr) in self.provides:
++ for pkg in self.rpmdb.getRequires(reqn,reqf,reqevr):
++ if pkg != self:
++ pkgset.add(pkg)
++
++ for fn in self.filelist + self.dirlist:
++ for pkg in self.rpmdb.getRequires(fn, None, (None, None, None)):
++ if pkg != self:
++ pkgset.add(pkg)
++
++ return list(pkgset)
++
+
+-
++ def required_packages(self):
++ pkgset = set()
++ for (reqn, reqf, reqevr) in self.requires:
++ for pkg in self.rpmdb.getProvides(reqn, reqf, reqevr):
++ if pkg != self:
++ pkgset.add(pkg)
++
++ return list(pkgset)
++
+ class RPMDBProblem:
+ '''
+ Represents a problem in the rpmdb, from the check_*() functions.
+@@ -195,13 +219,20 @@ class RPMDBPackageSack(PackageSackBase):
}
addldb_path = os.path.normpath(self._persistdir + '/yumdb')
@@ -39275,7 +39498,7 @@ index ae73c32..346decc 100644
for (hdr, mi) in self._all_packages():
self._simple_pkgtup_list.append(self._hdr2pkgTuple(hdr))
-@@ -210,6 +217,10 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -210,6 +241,10 @@ class RPMDBPackageSack(PackageSackBase):
pkglist = property(_get_pkglist, None)
def dropCachedData(self):
@@ -39286,7 +39509,7 @@ index ae73c32..346decc 100644
self._idx2pkg = {}
self._name2pkg = {}
self._pkgnames_loaded = set()
-@@ -236,6 +247,80 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -236,6 +271,80 @@ class RPMDBPackageSack(PackageSackBase):
self.transactionReset() # Should do nothing, but meh...
self._cached_rpmdb_mtime = None
@@ -39367,7 +39590,7 @@ index ae73c32..346decc 100644
def setCacheDir(self, cachedir):
""" Sets the internal cachedir value for the rpmdb, to be the
"rpmdb-indexes" directory in the persisent yum storage. """
-@@ -244,6 +329,10 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -244,6 +353,10 @@ class RPMDBPackageSack(PackageSackBase):
else:
self._cachedir = '/' + cachedir
@@ -39378,7 +39601,7 @@ index ae73c32..346decc 100644
def readOnlyTS(self):
if not self.ts:
self.ts = initReadOnlyTransaction(root=self.root)
-@@ -293,6 +382,7 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -293,6 +406,7 @@ class RPMDBPackageSack(PackageSackBase):
ts = self.readOnlyTS()
result = {}
@@ -39386,7 +39609,7 @@ index ae73c32..346decc 100644
mi = ts.dbMatch('basenames', name)
for hdr in mi:
if hdr['name'] == 'gpg-pubkey':
-@@ -511,12 +601,34 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -511,12 +625,34 @@ class RPMDBPackageSack(PackageSackBase):
return pkgobjlist
def _uncached_returnConflictPackages(self):
@@ -39426,7 +39649,7 @@ index ae73c32..346decc 100644
return self._cached_conflicts_data
def _write_conflicts_new(self, pkgs, rpmdbv):
-@@ -543,7 +655,7 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -543,7 +679,7 @@ class RPMDBPackageSack(PackageSackBase):
misc.unlink_f(self._cachedir + "/version")
misc.unlink_f(self._cachedir + '/conflicts')
misc.unlink_f(self._cachedir + '/file-requires')
@@ -39435,7 +39658,7 @@ index ae73c32..346decc 100644
# We have a couple of options here, we can:
#
# . Ignore it and continue - least invasive, least likely to get any
-@@ -627,8 +739,8 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -627,8 +763,8 @@ class RPMDBPackageSack(PackageSackBase):
data = self._trans_cache_store['file-requires']
self._write_file_requires(rpmdbv, data)
@@ -39446,7 +39669,7 @@ index ae73c32..346decc 100644
self._write_package_checksums(rpmdbv, data)
self._trans_cache_store = {}
-@@ -803,22 +915,23 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -803,22 +939,23 @@ class RPMDBPackageSack(PackageSackBase):
os.rename(self._cachedir + '/file-requires.tmp',
self._cachedir + '/file-requires')
@@ -39474,7 +39697,7 @@ index ae73c32..346decc 100644
frpmdbv = fo.readline()
if not frpmdbv or rpmdbv != frpmdbv[:-1]:
return
-@@ -837,7 +950,10 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -837,7 +974,10 @@ class RPMDBPackageSack(PackageSackBase):
T = _read_str(fo)
D = _read_str(fo)
@@ -39486,7 +39709,7 @@ index ae73c32..346decc 100644
if fo.readline() != '': # Should be EOF
return
-@@ -845,7 +961,13 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -845,7 +985,13 @@ class RPMDBPackageSack(PackageSackBase):
self._deal_with_bad_rpmdbcache("pkg checksums")
return
@@ -39500,7 +39723,7 @@ index ae73c32..346decc 100644
(n, a, e, v, r) = pkgtup
pkg = self.searchNevra(n, e, v, r, a)
if not pkg:
-@@ -863,24 +985,26 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -863,24 +1009,26 @@ class RPMDBPackageSack(PackageSackBase):
if not self.__cache_rpmdb__:
return
@@ -39531,7 +39754,7 @@ index ae73c32..346decc 100644
def _get_cached_simpleVersion_main(self):
""" Return the cached string of the main rpmdbv. """
-@@ -1046,7 +1170,6 @@ class RPMDBPackageSack(PackageSackBase):
+@@ -1046,7 +1194,6 @@ class RPMDBPackageSack(PackageSackBase):
if self.auto_close:
self.ts.close()
@@ -39539,7 +39762,7 @@ index ae73c32..346decc 100644
def _header_from_index(self, idx):
"""returns a package header having been given an index"""
warnings.warn('_header_from_index() will go away in a future version of Yum.\n',
-@@ -1422,9 +1545,10 @@ class RPMDBAdditionalData(object):
+@@ -1422,9 +1569,10 @@ class RPMDBAdditionalData(object):
# dirs have files per piece of info we're keeping
# repoid, install reason, status, blah, (group installed for?), notes?
@@ -39551,7 +39774,7 @@ index ae73c32..346decc 100644
self.conf.writable = False
self._packages = {} # pkgid = dir
-@@ -1566,7 +1690,6 @@ class RPMDBAdditionalDataPackage(object):
+@@ -1566,7 +1714,6 @@ class RPMDBAdditionalDataPackage(object):
self._yumdb_cache['attr'][value][2].add(fn)
self._yumdb_cache[fn] = value
@@ -39559,7 +39782,7 @@ index ae73c32..346decc 100644
return True
-@@ -1587,6 +1710,11 @@ class RPMDBAdditionalDataPackage(object):
+@@ -1587,6 +1734,11 @@ class RPMDBAdditionalDataPackage(object):
if attr.endswith('.tmp'):
raise AttributeError, "Cannot set attribute %s on %s" % (attr, self)
diff --git a/yum.spec b/yum.spec
index 65713c3..3ba5bc6 100644
--- a/yum.spec
+++ b/yum.spec
@@ -5,7 +5,7 @@
Summary: RPM installer/updater
Name: yum
Version: 3.2.28
-Release: 12%{?dist}
+Release: 13%{?dist}
License: GPLv2+
Group: System Environment/Base
Source0: http://yum.baseurl.org/download/3.2/%{name}-%{version}.tar.gz
@@ -156,6 +156,9 @@ rm -rf $RPM_BUILD_ROOT
%dir %{yum_pluginslib}
%changelog
+* Tue Nov 9 2010 Seth Vidal <skvidal at fedoraproject.org> - 3.2.28-13
+- once again with head
+
* Fri Nov 5 2010 James Antill <james at fedoraproject.org> - 3.2.28-12
- latest head
- Add load-ts command.
More information about the scm-commits
mailing list