From 7cb06b961704b39dac45204237362cf77dd7bea6 Mon Sep 17 00:00:00 2001 From: James Antill Date: Apr 08 2011 18:14:36 +0000 Subject: HEAD update - 3.2.29-10 --- diff --git a/yum-HEAD.patch b/yum-HEAD.patch index f5447bf..dc7dfe0 100644 --- a/yum-HEAD.patch +++ b/yum-HEAD.patch @@ -1,5 +1,5 @@ diff --git a/cli.py b/cli.py -index 640f190..2267b86 100644 +index 640f190..aefb841 100644 --- a/cli.py +++ b/cli.py @@ -45,6 +45,11 @@ import yumcommands @@ -22,7 +22,18 @@ index 640f190..2267b86 100644 self.registerCommand(yumcommands.InstallCommand()) self.registerCommand(yumcommands.UpdateCommand()) self.registerCommand(yumcommands.InfoCommand()) -@@ -504,30 +510,35 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -250,6 +256,10 @@ class YumBaseCli(yum.YumBase, output.YumOutput): + # apply some of the options to self.conf + (opts, self.cmds) = self.optparser.setupYumConfig(args=args) + ++ if opts.version: ++ opts.quiet = True ++ opts.verbose = False ++ + # Check that firstParse didn't miss anything, and warn the user if it + # did ... because this is really magic, and unexpected. + if opts.quiet: +@@ -504,30 +514,35 @@ class YumBaseCli(yum.YumBase, output.YumOutput): if self.gpgsigcheck(downloadpkgs) != 0: return 1 @@ -46,9 +57,7 @@ index 640f190..2267b86 100644 + dscb = self.dsCallback + self.dsCallback = None # dumb, dumb dumb dumb! + self.populateTs(keepold=0) # sigh - -- for msg in msgs: -- print to_utf8(msg) ++ + rcd_st = time.time() + self.verbose_logger.log(yum.logginglevels.INFO_2, + _('Running Transaction Check')) @@ -64,22 +73,24 @@ index 640f190..2267b86 100644 + else: + print _('ERROR with transaction check vs depsolve:') -- if rpmlib_only: -- return 1, [_('RPM needs to be updated')] -- return 1, [_('Please report this error in %s') % self.conf.bugtracker_url] +- for msg in msgs: +- print to_utf8(msg) + for msg in msgs: + print to_utf8(msg) -- self.verbose_logger.debug('rpm_check_debug time: %0.3f' % (time.time() - rcd_st)) +- if rpmlib_only: +- return 1, [_('RPM needs to be updated')] +- return 1, [_('Please report this error in %s') % self.conf.bugtracker_url] + if rpmlib_only: + return 1, [_('RPM needs to be updated')] + return 1, [_('Please report this error in %s') % self.conf.bugtracker_url] -+ + +- self.verbose_logger.debug('rpm_check_debug time: %0.3f' % (time.time() - rcd_st)) + self.verbose_logger.debug('Transaction Check time: %0.3f' % (time.time() - rcd_st)) tt_st = time.time() self.verbose_logger.log(yum.logginglevels.INFO_2, -@@ -535,14 +546,10 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -535,14 +550,10 @@ class YumBaseCli(yum.YumBase, output.YumOutput): if not self.conf.diskspacecheck: self.tsInfo.probFilterFlags.append(rpm.RPMPROB_FILTER_DISKSPACE) @@ -96,7 +107,7 @@ index 640f190..2267b86 100644 tserrors = self.ts.test(testcb) del testcb -@@ -555,7 +562,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -555,7 +566,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput): self.errorSummary(errstring) self.verbose_logger.log(yum.logginglevels.INFO_2, _('Transaction Test Succeeded')) @@ -104,7 +115,7 @@ index 640f190..2267b86 100644 self.verbose_logger.debug('Transaction Test time: %0.3f' % (time.time() - tt_st)) -@@ -563,10 +569,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -563,10 +573,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput): signal.signal(signal.SIGQUIT, signal.SIG_DFL) ts_st = time.time() @@ -115,7 +126,7 @@ index 640f190..2267b86 100644 # put back our depcheck callback self.dsCallback = dscb -@@ -629,7 +631,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -629,7 +635,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): ", ".join(matches)) self.verbose_logger.log(yum.logginglevels.INFO_2, to_unicode(msg)) @@ -124,7 +135,7 @@ index 640f190..2267b86 100644 """ If the update/remove argument doesn't match with case, or due to not being installed, tell the user. """ # always_output is a wart due to update/remove not producing the -@@ -638,7 +640,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -638,7 +644,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput): # skip it. if not arg or arg[0] == '@': return @@ -138,7 +149,7 @@ index 640f190..2267b86 100644 if (matches.installed or (not matches.available and self.returnInstalledPackagesByDep(arg))): return # Found a match so ignore -@@ -651,7 +658,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -651,7 +662,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return # No package name, so do the maybeYouMeant thing here too @@ -147,7 +158,72 @@ index 640f190..2267b86 100644 if not matches.installed and matches.available: self.verbose_logger.log(yum.logginglevels.INFO_2, _('Package(s) %s%s%s available, but not installed.'), -@@ -822,7 +829,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -706,7 +717,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): + return 1, [_('Nothing to do')] + return 0, [_('Nothing to do')] + +- def updatePkgs(self, userlist, quiet=0): ++ def updatePkgs(self, userlist, quiet=0, update_to=False): + """take user commands and populate transaction wrapper with + packages to be updated""" + +@@ -733,7 +744,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): + userlist.remove(item) + + for arg in userlist: +- if not self.update(pattern=arg): ++ if not self.update(pattern=arg, update_to=update_to): + self._checkMaybeYouMeant(arg) + + if len(self.tsInfo) > oldcount: +@@ -750,6 +761,13 @@ class YumBaseCli(yum.YumBase, output.YumOutput): + installed version is older or newer. We allow "selection" but not + local packages (use tmprepo, or something). """ + ++ level = 'diff' ++ if userlist and userlist[0] in ('full', 'diff', 'different'): ++ level = userlist[0] ++ userlist = userlist[1:] ++ if level == 'different': ++ level = 'diff' ++ + dupdates = [] + ipkgs = {} + for pkg in sorted(self.rpmdb.returnPackages(patterns=userlist)): +@@ -787,8 +805,31 @@ class YumBaseCli(yum.YumBase, output.YumOutput): + + ipkg = ipkgs[ipkgname] + apkg = apkgs[ipkgname] +- if ipkg.verEQ(apkg): ++ if ipkg.verEQ(apkg): # Latest installed == Latest avail. ++ if level == 'diff': ++ continue ++ ++ # level == full: do reinstalls if checksum doesn't match. ++ # do removals, if older installed versions. ++ for napkg in self.rpmdb.searchNames([ipkgname]): ++ if (not self.allowedMultipleInstalls(apkg) and ++ not napkg.verEQ(ipkg)): ++ dupdates.extend(self.remove(po=napkg)) ++ continue ++ ++ nayi = napkg.yumdb_info ++ for apkg in self.pkgSack.searchPkgTuple(napkg.pkgtup): ++ if ('checksum_type' in nayi and ++ 'checksum_data' in nayi and ++ nayi.checksum_type == apkg.checksum_type and ++ nayi.checksum_data == apkg.pkgId): ++ found = True ++ break ++ if found: ++ continue ++ dupdates.extend(self.reinstall(pkgtup=napkg.pkgtup)) + continue ++ + if self.allowedMultipleInstalls(apkg): + found = False + for napkg in self.rpmdb.searchNames([apkg.name]): +@@ -822,7 +863,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): for arg in userlist: rms = self.remove(pattern=arg) if not rms: @@ -156,7 +232,7 @@ index 640f190..2267b86 100644 all_rms.extend(rms) if all_rms: -@@ -1063,13 +1070,16 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1063,13 +1104,16 @@ class YumBaseCli(yum.YumBase, output.YumOutput): os.path.exists(arg))): thispkg = yum.packages.YumUrlPackage(self, self.ts, arg) pkgs.append(thispkg) @@ -178,11 +254,53 @@ index 640f190..2267b86 100644 return 0, [] +@@ -1390,7 +1434,7 @@ class YumOptionParser(OptionParser): + '-e', '--errorlevel', + '--installroot', + '--disableplugin', '--enableplugin', '--releasever', +- '--setopt'), ++ '--setopt'), + args) + except ValueError, arg: + self.base.usage() +@@ -1654,6 +1698,7 @@ def _filtercmdline(novalopts, valopts, args): + + Will raise ValueError if there was a problem parsing the command line. + ''' ++ # ' xemacs syntax hack + out = [] + args = list(args) # Make a copy because this func is destructive + +@@ -1664,6 +1709,9 @@ def _filtercmdline(novalopts, valopts, args): + if opt in valopts: + out.append(a) + ++ elif a == '--': ++ out.append(a) ++ + elif a in novalopts: + out.append(a) + diff --git a/docs/yum.8 b/docs/yum.8 -index 52f6b53..360a976 100644 +index 52f6b53..39c7253 100644 --- a/docs/yum.8 +++ b/docs/yum.8 -@@ -73,7 +73,7 @@ gnome\-packagekit application\&. +@@ -23,10 +23,14 @@ gnome\-packagekit application\&. + .br + .I \fR * update [package1] [package2] [\&.\&.\&.] + .br ++.I \fR * update-to [package1] [package2] [\&.\&.\&.] ++.br + .I \fR * check\-update + .br + .I \fR * upgrade [package1] [package2] [\&.\&.\&.] + .br ++.I \fR * upgrade-to [package1] [package2] [\&.\&.\&.] ++.br + .I \fR * distribution-synchronization [package1] [package2] [\&.\&.\&.] + .br + .I \fR * remove | erase package1 [package2] [\&.\&.\&.] +@@ -73,7 +77,7 @@ gnome\-packagekit application\&. .br .I \fR * version [ all | installed | available | group-* | nogroups* | grouplist | groupinfo ] .br @@ -191,7 +309,47 @@ index 52f6b53..360a976 100644 .br .I \fR * check .br -@@ -253,7 +253,10 @@ on groups, files, provides, filelists and rpm files just like the "install" comm +@@ -112,6 +116,16 @@ If the main obsoletes configure option is true (default) or the \-\-obsoletes + flag is present \fByum\fP will include package + obsoletes in its calculations - this makes it better for distro\-version + changes, for example: upgrading from somelinux 8.0 to somelinux 9. ++ ++Note that "\fBupdate\fP" works on installed packages first, and only if there ++are no matches does it look for available packages. The difference is most ++noticable when you do "\fBupdate\fP foo-1-2" which will act exactly as ++"\fBupdate\fP foo" if foo-1-2 is installed. You can use the "\fBupdate-to\fP" ++if you'd prefer that nothing happen in the above case. ++.IP ++.IP "\fBupdate-to\fP" ++This command works like "\fBupdate\fP" but always specifies the version of the ++package we want to update to. + .IP + .IP "\fBcheck\-update\fP" + Implemented so you could know if your machine had any updates that needed to +@@ -125,6 +139,10 @@ Running in verbose mode also shows obsoletes. + Is the same as the update command with the \-\-obsoletes flag set. See update + for more details. + .IP ++.IP "\fBupgrade-to\fP" ++This command works like "\fBupgrade\fP" but always specifies the version of the ++package we want to update to. ++.IP + .IP "\fBdistribution\-synchronization\fP or \fBdistro\-sync\fP" + Synchronizes the installed package set with the latest packages available, this + is done by either obsoleting, upgrading or downgrading as appropriate. This will +@@ -132,6 +150,11 @@ is done by either obsoleting, upgrading or downgrading as appropriate. This will + package FOO installed at version 4, and the latest available is only + version 3, then this command will \fBdowngrade\fP FOO to version 3. + ++If you give the optional argument "full", then the command will also reinstall ++packages where the install checksum and the available checksum do not match. And ++remove old packages (can be used to sync. rpmdb versions). The optional argument ++"different" can be used to specify the default operation. ++ + This command does not perform operations on groups, local packages or negative + selections. + .IP +@@ -253,7 +276,10 @@ on groups, files, provides, filelists and rpm files just like the "install" comm .IP .IP "\fBdeplist\fP" Produces a list of all dependencies and what packages provide those @@ -203,7 +361,7 @@ index 52f6b53..360a976 100644 .IP .IP "\fBrepolist\fP" Produces a list of configured repositories. The default is to list all -@@ -316,8 +319,12 @@ The undo/redo commands take either a transaction id or the keyword last and +@@ -316,8 +342,12 @@ The undo/redo commands take either a transaction id or the keyword last and an offset from the last transaction (Eg. if you've done 250 transactions, "last" refers to transaction 250, and "last-4" refers to transaction 246). @@ -217,7 +375,7 @@ index 52f6b53..360a976 100644 .I \fB>\fR - The rpmdb was changed, outside yum, after the transaction. .br -@@ -402,7 +409,11 @@ Doesn't limit packages to their latest versions in the info, list and search +@@ -402,7 +432,11 @@ Doesn't limit packages to their latest versions in the info, list and search commands (will also affect plugins which use the doPackageLists() API). .IP "\fB\-\-installroot=root\fP" Specifies an alternative installroot, relative to which all packages will be @@ -230,7 +388,7 @@ index 52f6b53..360a976 100644 .br Configuration Option: \fBinstallroot\fP .IP "\fB\-\-enablerepo=repoidglob\fP" -@@ -458,9 +469,11 @@ Configuration Option: \fBskip_broken\fP +@@ -458,9 +492,11 @@ Configuration Option: \fBskip_broken\fP .br .IP "\fB\-\-releasever=version\fP" Pretend the current release version is the given string. This is very useful @@ -259,7 +417,7 @@ index e1c3480..a535b79 100644 .IP diff --git a/etc/yum.bash b/etc/yum.bash -index f4be628..1ccb83d 100644 +index f4be628..cf43106 100644 --- a/etc/yum.bash +++ b/etc/yum.bash @@ -176,9 +176,13 @@ _yum() @@ -295,7 +453,59 @@ index f4be628..1ccb83d 100644 done done -@@ -251,7 +255,7 @@ _yum() +@@ -209,26 +213,32 @@ _yum() + ;; + + clean) +- if [ "$prev" = clean ] ; then ++ [ "$prev" = "$cmd" ] && \ + COMPREPLY=( $( compgen -W 'expire-cache packages headers + metadata cache dbcache all' -- "$cur" ) ) +- fi + return 0 + ;; + + deplist) + COMPREPLY=( $( compgen -f -o plusdirs -X '!*.[rs]pm' -- "$cur" ) ) +- [[ "$cur" == */* ]] || _yum_list all "$cur" ++ [[ "$cur" == */* || "$cur" == ~* ]] || _yum_list all "$cur" ++ return 0 ++ ;; ++ ++ distro-sync|distribution-synchronization) ++ [ "$prev" = "$cmd" ] && \ ++ COMPREPLY=( $( compgen -W 'full different' -- "$cur" ) ) ++ _yum_list installed "$cur" + return 0 + ;; + + downgrade|reinstall) + _yum_binrpmfiles "$cur" +- [[ "$cur" == */* ]] || _yum_list installed "$cur" ++ [[ "$cur" == */* || "$cur" == ~* ]] || _yum_list installed "$cur" + return 0 + ;; + +- erase|remove|distro-sync|distribution-synchronization) ++ erase|remove) + _yum_list installed "$cur" + return 0 + ;; +@@ -239,19 +249,18 @@ _yum() + ;; + + help) +- if [ "$prev" = help ] ; then ++ [ "$prev" = "$cmd" ] && \ + COMPREPLY=( $( compgen -W '${cmds[@]}' -- "$cur" ) ) +- fi + return 0 + ;; + + history) + case $prev in +- history) ++ $cmd) COMPREPLY=( $( compgen -W 'info list summary undo redo new addon-info package-list' -- "$cur" ) ) ;; @@ -304,6 +514,58 @@ index f4be628..1ccb83d 100644 COMPREPLY=( $( compgen -W "last $( $yum -d 0 -C history \ 2>/dev/null | \ sed -ne 's/^[[:space:]]*\([0-9]\{1,\}\).*/\1/p' )" \ +@@ -274,15 +283,14 @@ _yum() + + install) + _yum_binrpmfiles "$cur" +- [[ "$cur" == */* ]] || _yum_list available "$cur" ++ [[ "$cur" == */* || "$cur" == ~* ]] || _yum_list available "$cur" + return 0 + ;; + + list) +- if [ "$prev" = list ] ; then ++ [ "$prev" = "$cmd" ] && \ + COMPREPLY=( $( compgen -W 'all available updates installed + extras obsoletes recent' -- "$cur" ) ) +- fi + return 0 + ;; + +@@ -292,29 +300,26 @@ _yum() + ;; + + repolist) +- if [ "$prev" = repolist ] ; then ++ [ "$prev" = "$cmd" ] && \ + COMPREPLY=( $( compgen -W 'all enabled disabled' -- "$cur" ) ) +- fi + return 0 + ;; + + shell) +- if [ "$prev" = shell ] ; then ++ [ "$prev" = "$cmd" ] && \ + COMPREPLY=( $( compgen -f -o plusdirs -- "$cur" ) ) +- fi + return 0 + ;; + + update|upgrade) + _yum_binrpmfiles "$cur" +- [[ "$cur" == */* ]] || _yum_list updates "$cur" ++ [[ "$cur" == */* || "$cur" == ~* ]] || _yum_list updates "$cur" + return 0 + ;; + version) +- if [ "$prev" = version ] ; then ++ [ "$prev" = "$cmd" ] && \ + COMPREPLY=( $( compgen -W 'all installed available nogroups + grouplist groupinfo' -- "$cur" ) ) +- fi + return 0 + ;; + esac diff --git a/output.py b/output.py index b1d92e5..85b21f8 100755 --- a/output.py @@ -534,8 +796,135 @@ index e8f4459..121ad5b 100644 reserrors = [] if tserrors: +diff --git a/test/simpleupdatetests.py b/test/simpleupdatetests.py +index 6bc2efe..6177fb1 100644 +--- a/test/simpleupdatetests.py ++++ b/test/simpleupdatetests.py +@@ -871,3 +871,122 @@ class SimpleUpdateTests(OperationsTests): + [pa1, pa2], multi_cmds=True) + self.assert_(res=='ok', msg) + self.assertResult((pa1, pa2)) ++ ++ # Test how update-to != update. ++ def _setupUpdateTo(self): ++ foo11 = FakePackage('foo', '1', '1', '0', 'i386') ++ foo11.addProvides('foobar', 'EQ', ('0', '1', '1')) ++ foo12 = FakePackage('foo', '1', '2', '0', 'i386') ++ foo12.addProvides('foobar', 'EQ', ('0', '1', '2')) ++ foo13 = FakePackage('foo', '1', '3', '0', 'i386') ++ foo13.addProvides('foobar', 'EQ', ('0', '1', '3')) ++ foo20 = FakePackage('foo', '2', '0', '0', 'i386') ++ foo20.addProvides('foobar', 'EQ', ('0', '2', '0')) ++ all = (foo11, foo12, foo13, foo20) ++ return locals() ++ ++ def testUpdateTo1_1(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update', 'foo'], ++ [pkgs['foo11']], ++ pkgs['all']) ++ self.assert_(res=='ok', msg) ++ self.assertResult((pkgs['foo20'],)) ++ ++ def testUpdateTo1_2(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update-to', 'foo'], ++ [pkgs['foo11']], ++ pkgs['all']) ++ self.assert_(res=='ok', msg) ++ self.assertResult((pkgs['foo20'],)) ++ ++ def testUpdateTo2_1(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update', 'foo-1-2'], ++ [pkgs['foo11']], ++ pkgs['all']) ++ self.assert_(res=='ok', msg) ++ self.assertResult((pkgs['foo12'],)) ++ ++ def testUpdateTo2_2(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update-to', 'foo-1-2'], ++ [pkgs['foo11']], ++ pkgs['all']) ++ self.assert_(res=='ok', msg) ++ self.assertResult((pkgs['foo12'],)) ++ ++ def testUpdateTo3_1(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update', 'foo-1-2'], ++ [pkgs['foo12']], ++ pkgs['all']) ++ self.assert_(res=='ok', msg) ++ self.assertResult((pkgs['foo20'],)) ++ ++ def testUpdateTo3_2(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update-to', 'foo-1-2'], ++ [pkgs['foo12']], ++ pkgs['all']) ++ # Nothing to do... ++ self.assert_(res==0, msg) ++ ++ ++ def testUpdateToProv1_1(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update', 'foobar'], ++ [pkgs['foo11']], ++ pkgs['all']) ++ self.assert_(res=='ok', msg) ++ self.assertResult((pkgs['foo20'],)) ++ ++ def testUpdateToProv1_2(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update-to', 'foobar'], ++ [pkgs['foo11']], ++ pkgs['all']) ++ self.assert_(res=='ok', msg) ++ self.assertResult((pkgs['foo20'],)) ++ ++ def testUpdateToProv2_1(self): ++ pkgs = self._setupUpdateTo() ++ # This is kind of annoying, maybe even a bug (but an old one) what ++ # happens is that in "update" we only look for provides matches on ++ # installed pkgs. ... so we can't see a version mismatch. Thus. we ++ # don't see any pkgs. ++ # It also prints an annoying msg. at critical level. So ignoring. ++ if True: ++ return ++ res, msg = self.runOperation(['update', 'foobar = 1-2'], ++ [pkgs['foo11']], ++ pkgs['all']) ++ # self.assert_(res=='ok', msg) ++ # self.assertResult((pkgs['foo12'],)) ++ self.assert_(res==0, msg) ++ ++ def testUpdateToProv2_2(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update-to', 'foobar = 1-2'], ++ [pkgs['foo11']], ++ pkgs['all']) ++ self.assert_(res=='ok', msg) ++ self.assertResult((pkgs['foo12'],)) ++ ++ def testUpdateToProv3_1(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update', 'foobar = 1-2'], ++ [pkgs['foo12']], ++ pkgs['all']) ++ self.assert_(res=='ok', msg) ++ self.assertResult((pkgs['foo20'],)) ++ ++ def testUpdateToProv3_2(self): ++ pkgs = self._setupUpdateTo() ++ res, msg = self.runOperation(['update-to', 'foobar = 1-2'], ++ [pkgs['foo12']], ++ pkgs['all']) ++ # Nothing to do... ++ self.assert_(res==0, msg) ++ diff --git a/test/skipbroken-tests.py b/test/skipbroken-tests.py -index 4e6b2c8..36a4a6d 100644 +index 4e6b2c8..812785a 100644 --- a/test/skipbroken-tests.py +++ b/test/skipbroken-tests.py @@ -1,8 +1,11 @@ @@ -587,13 +976,13 @@ index 4e6b2c8..36a4a6d 100644 def testMissingReqNoSkip(self): ''' install fails, because of missing req. -@@ -669,8 +702,37 @@ class SkipBrokenTests(DepsolveTests): +@@ -669,8 +702,113 @@ class SkipBrokenTests(DepsolveTests): self.tsInfo.addUpdate(u7, oldpo=i7) self.assertEquals('ok', *self.resolveCode(skip=True)) # uncomment this line and the test will fail and you can see the output - self.assertResult([i1]) + # self.assertResult([i1]) - ++ + def test_conflict_looping(self): + ''' + Skip-broken is looping @@ -623,9 +1012,107 @@ index 4e6b2c8..36a4a6d 100644 + members.append(u4) + self.assertEquals('ok', *self.resolveCode(skip=True)) + self.assertResult(members) ++ ++ def test_skipbroken_001(self): ++ ''' ++ this will pass ++ https://bugzilla.redhat.com/show_bug.cgi?id=656057 ++ ''' ++ members = [] ++ # Installed package conflicts with ux1 ++ ix0 = self.instString('1:libguestfs-1.6.0-1.fc14.1.i686') ++ ix0.addRequires('/usr/lib/.libssl.so.1.0.0a.hmac') ++ members.append(ix0) ++ ix1 = self.instString('openssl-1.0.0a-2.fc14.i686') ++ ix1.addFile("/usr/lib/.libssl.so.1.0.0a.hmac") ++ ux1 = self.repoString('openssl-1.0.0b-1.fc14.i686') ++ ux1.addFile("/usr/lib/.libssl.so.1.0.0b.hmac") ++ self.tsInfo.addUpdate(ux1, oldpo=ix1) ++ members.append(ix1) ++ self.assertEquals('empty', *self.resolveCode(skip=True)) ++ self.assertResult(members) ++ ++ ++ def test_skipbroken_002(self): ++ ''' ++ this will pass ++ https://bugzilla.redhat.com/show_bug.cgi?id=656057 ++ ''' ++ members = [] ++ # Installed package conflicts with ux1 ++ ix0 = self.instString('1:libguestfs-1.6.0-1.fc14.1.i686') ++ ix0.addRequires('/usr/lib/.libssl.so.1.0.0a.hmac') ++ members.append(ix0) ++ ix1 = self.instString('openssl-1.0.0a-2.fc14.i686') ++ ix1.addFile("/usr/lib/.libssl.so.1.0.0a.hmac") ++ ux1 = self.repoString('openssl-1.0.0b-1.fc14.i686') ++ ux1.addFile("/usr/lib/.libssl.so.1.0.0b.hmac") ++ self.tsInfo.addUpdate(ux1, oldpo=ix1) ++ members.append(ix1) ++ # this is just junk to make the transaction big ++ i1 = self.instString('afoobar-0.4.12-2.fc12.noarch') ++ u1 = self.repoString('afoobar-0.4.14-1.fc14.noarch') ++ self.tsInfo.addUpdate(u1, oldpo=i1) ++ members.append(u1) ++ self.assertEquals('ok', *self.resolveCode(skip=True)) ++ self.assertResult(members) ++ ++ def test_skipbroken_003(self): ++ ''' ++ this will fail, because of a bug in the skip-broken code. ++ it will remove the wrong package (zfoobar) instead of openssl. ++ the problem is that self._working_po is not set with the right value ++ when checking file requires for installed packages after the transaction ++ if resolved. (_resolveRequires) ++ if fails because self._working_po contains the last package processed in the transaction ++ zfoobar, so it will be removed. ++ https://bugzilla.redhat.com/show_bug.cgi?id=656057 + ++ This should not fail anymore, after the the self._working_po is reset in depsolver ++ ''' ++ members = [] ++ # Installed package conflicts with ux1 ++ ix0 = self.instString('1:libguestfs-1.6.0-1.fc14.1.i686') ++ ix0.addRequires('/usr/lib/.libssl.so.1.0.0a.hmac') ++ members.append(ix0) ++ ix1 = self.instString('openssl-1.0.0a-2.fc14.i686') ++ ix1.addFile("/usr/lib/.libssl.so.1.0.0a.hmac") ++ ux1 = self.repoString('openssl-1.0.0b-1.fc14.i686') ++ ux1.addFile("/usr/lib/.libssl.so.1.0.0b.hmac") ++ self.tsInfo.addUpdate(ux1, oldpo=ix1) ++ members.append(ix1) ++ # this is just junk to make the transaction big ++ i1 = self.instString('zfoobar-0.4.12-2.fc12.noarch') ++ u1 = self.repoString('zfoobar-0.4.14-1.fc14.noarch') ++ self.tsInfo.addUpdate(u1, oldpo=i1) ++ members.append(u1) ++ self.assertEquals('ok', *self.resolveCode(skip=True)) ++ self.assertResult(members) def resolveCode(self,skip = False): +diff --git a/test/testbase.py b/test/testbase.py +index d9e23f1..12025ce 100644 +--- a/test/testbase.py ++++ b/test/testbase.py +@@ -18,6 +18,8 @@ from yum.rpmsack import RPMDBPackageSack as _rpmdbsack + import inspect + from rpmUtils import arch + from rpmUtils.transaction import initReadOnlyTransaction ++import rpmUtils.miscutils ++ + + ############################################################# + ### Helper classes ########################################## +@@ -320,6 +322,8 @@ class FakeRpmDb(packageSack.PackageSack): + # convert flags & version for unversioned reqirements + if not version: + version=(None, None, None) ++ if type(version) in (str, type(None), unicode): ++ version = rpmUtils.miscutils.stringToVersion(version) + if flags == '0': + flags=None + for po in self.provides.get(name, []): diff --git a/yum.spec b/yum.spec index a1fbc72..65a2397 100644 --- a/yum.spec @@ -642,7 +1129,7 @@ index a1fbc72..65a2397 100644 %config(noreplace) %{_sysconfdir}/sysconfig/yum-cron diff --git a/yum/__init__.py b/yum/__init__.py -index f6e8a6b..36fc203 100644 +index f6e8a6b..cf4d827 100644 --- a/yum/__init__.py +++ b/yum/__init__.py @@ -349,7 +349,10 @@ class YumBase(depsolve.Depsolve): @@ -693,7 +1180,26 @@ index f6e8a6b..36fc203 100644 elif txmbr.name not in protected: continue if txmbr.name not in bad_togo: -@@ -1435,12 +1445,17 @@ class YumBase(depsolve.Depsolve): +@@ -1115,6 +1125,9 @@ class YumBase(depsolve.Depsolve): + self.rpmdb.transactionReset() + self.installedFileRequires = None # Kind of hacky + self.verbose_logger.debug("SKIPBROKEN: ########### Round %i ################" , count) ++ if count == 30: # Failsafe, to avoid endless looping ++ self.verbose_logger.debug('SKIPBROKEN: Too many loops ') ++ break + self._printTransaction() + depTree = self._buildDepTree() + startTs = set(self.tsInfo) +@@ -1130,7 +1143,7 @@ class YumBase(depsolve.Depsolve): + for skip in skipped: + skipped_po.add(skip) + # make sure we get the compat arch packages skip from pkgSack and up too. +- if skip not in removed_from_sack and skip.repoid == 'installed': ++ if skip not in removed_from_sack and skip.repoid != 'installed': + _remove_from_sack(skip) + # Nothing was removed, so we still got a problem + # the first time we get here we reset the resolved members of +@@ -1435,12 +1448,17 @@ class YumBase(depsolve.Depsolve): # will be we store what we thought, not what happened (so it'll be an # invalid cache). self.rpmdb.transactionResultVersion(frpmdbv) @@ -716,7 +1222,7 @@ index f6e8a6b..36fc203 100644 self._ts_save_file = None errors = self.ts.run(cb.callback, '') -@@ -1485,7 +1500,12 @@ class YumBase(depsolve.Depsolve): +@@ -1485,7 +1503,12 @@ class YumBase(depsolve.Depsolve): # drop out the rpm cache so we don't step on bad hdr indexes @@ -730,7 +1236,7 @@ index f6e8a6b..36fc203 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): -@@ -1674,8 +1694,11 @@ class YumBase(depsolve.Depsolve): +@@ -1674,8 +1697,11 @@ class YumBase(depsolve.Depsolve): def doLock(self, lockfile = YUM_PID_FILE): """perform the yum locking, raise yum-based exceptions, not OSErrors""" @@ -743,7 +1249,7 @@ index f6e8a6b..36fc203 100644 root = self.conf.cachedir # Don't want /var/run/yum.pid ... just: /yum.pid lockfile = os.path.basename(lockfile) -@@ -1690,7 +1713,7 @@ class YumBase(depsolve.Depsolve): +@@ -1690,7 +1716,7 @@ class YumBase(depsolve.Depsolve): fd = open(lockfile, 'r') except (IOError, OSError), e: msg = _("Could not open lock %s: %s") % (lockfile, e) @@ -752,7 +1258,7 @@ index f6e8a6b..36fc203 100644 try: oldpid = int(fd.readline()) except ValueError: -@@ -1707,7 +1730,7 @@ class YumBase(depsolve.Depsolve): +@@ -1707,7 +1733,7 @@ class YumBase(depsolve.Depsolve): else: # Whoa. What the heck happened? msg = _('Unable to check if PID %s is active') % oldpid @@ -761,7 +1267,7 @@ index f6e8a6b..36fc203 100644 else: # Another copy seems to be running. msg = _('Existing lock %s: another copy is running as pid %s.') % (lockfile, oldpid) -@@ -1752,7 +1775,7 @@ class YumBase(depsolve.Depsolve): +@@ -1752,7 +1778,7 @@ class YumBase(depsolve.Depsolve): if not msg.errno == errno.EEXIST: # Whoa. What the heck happened? errmsg = _('Could not create lock at %s: %s ') % (filename, str(msg)) @@ -770,7 +1276,74 @@ index f6e8a6b..36fc203 100644 return 0 else: os.write(fd, contents) -@@ -3417,7 +3440,6 @@ class YumBase(depsolve.Depsolve): +@@ -2807,9 +2833,7 @@ class YumBase(depsolve.Depsolve): + if 'optional' in package_types: + pkgs.extend(thisgroup.optional_packages) + +- if not pkgs: +- self.logger.critical(_('Warning: Group %s does not have any packages.'), thisgroup.groupid) +- ++ old_txmbrs = len(txmbrs_used) + for pkg in pkgs: + self.verbose_logger.log(logginglevels.DEBUG_2, + _('Adding package %s from group %s'), pkg, thisgroup.groupid) +@@ -2827,6 +2851,7 @@ class YumBase(depsolve.Depsolve): + if enable_group_conditionals is not None: # has to be this way so we can set it to False + group_conditionals = enable_group_conditionals + ++ count_cond_test = 0 + if group_conditionals: + for condreq, cond in thisgroup.conditional_packages.iteritems(): + if self.isPackageInstalled(cond): +@@ -2859,10 +2884,15 @@ class YumBase(depsolve.Depsolve): + pkgs = use + + pkgs = packagesNewestByName(pkgs) ++ count_cond_test += len(pkgs) + + if cond not in self.tsInfo.conditionals: + self.tsInfo.conditionals[cond] = [] + self.tsInfo.conditionals[cond].extend(pkgs) ++ if len(txmbrs_used) == old_txmbrs: ++ self.logger.critical(_('Warning: Group %s does not have any packages.'), thisgroup.groupid) ++ if count_cond_test: ++ self.logger.critical(_('Group %s does have %u conditional packages, which may get installed.'), count_cond_test) + return txmbrs_used + + def deselectGroup(self, grpid, force=False): +@@ -2978,9 +3008,28 @@ class YumBase(depsolve.Depsolve): + + if not depstring: + return [] +- results = self.pkgSack.searchProvides(depstring) +- return results +- ++ ++ # parse the string out ++ # either it is 'dep (some operator) e:v-r' ++ # or /file/dep ++ # or packagename ++ if type(depstring) == types.TupleType: ++ (depname, depflags, depver) = depstring ++ else: ++ depname = depstring ++ depflags = None ++ depver = None ++ ++ if depstring[0] != '/': ++ # not a file dep - look at it for being versioned ++ dep_split = depstring.split() ++ if len(dep_split) == 3: ++ depname, flagsymbol, depver = dep_split ++ if not flagsymbol in SYMBOLFLAGS: ++ raise Errors.YumBaseError, _('Invalid version flag from: %s') % str(depstring) ++ depflags = SYMBOLFLAGS[flagsymbol] ++ ++ return self.pkgSack.getProvides(depname, depflags, depver).keys() + + def returnPackageByDep(self, depstring): + """Pass in a generic [build]require string and this function will +@@ -3417,7 +3466,6 @@ class YumBase(depsolve.Depsolve): pkgs = po.obsoletedBy(pkgs, limit=1) if pkgs: already_obs = pkgs[0] @@ -778,7 +1351,64 @@ index f6e8a6b..36fc203 100644 if already_obs: self.verbose_logger.warning(_('Package %s is obsoleted by %s which is already installed'), -@@ -3934,11 +3956,17 @@ class YumBase(depsolve.Depsolve): +@@ -3537,7 +3585,7 @@ class YumBase(depsolve.Depsolve): + txmbr.reason = 'dep' + return txmbr + +- def update(self, po=None, requiringPo=None, **kwargs): ++ def update(self, po=None, requiringPo=None, update_to=False, **kwargs): + """try to mark for update the item(s) specified. + po is a package object - if that is there, mark it for update, + if possible +@@ -3608,26 +3656,37 @@ class YumBase(depsolve.Depsolve): + if kwargs['pattern'] and kwargs['pattern'][0] == '@': + return self._at_groupinstall(kwargs['pattern']) + +- (e, m, u) = self.rpmdb.matchPackageNames([kwargs['pattern']]) +- instpkgs.extend(e) +- instpkgs.extend(m) ++ arg = kwargs['pattern'] ++ if not update_to: ++ instpkgs = self.rpmdb.returnPackages(patterns=[arg]) ++ else: ++ availpkgs = self.pkgSack.returnPackages(patterns=[arg]) + +- if u: ++ if not instpkgs and not availpkgs: + depmatches = [] +- arg = u[0] + try: +- depmatches = self.returnInstalledPackagesByDep(arg) ++ if update_to: ++ depmatches = self.returnPackagesByDep(arg) ++ else: ++ depmatches = self.returnInstalledPackagesByDep(arg) + except yum.Errors.YumBaseError, e: + self.logger.critical(_('%s') % e) +- +- instpkgs.extend(depmatches) ++ ++ if update_to: ++ availpkgs.extend(depmatches) ++ else: ++ instpkgs.extend(depmatches) + + # Always look for available packages, it doesn't seem to do any + # harm (apart from some time). And it fixes weird edge cases where + # "update a" (which requires a new b) is different from "update b" + try: +- pats = [kwargs['pattern']] +- m = self.pkgSack.returnNewestByNameArch(patterns=pats) ++ if update_to: ++ m = [] ++ else: ++ pats = [kwargs['pattern']] ++ # pats += list(set([pkg.name for pkg in instpkgs])) ++ m = self.pkgSack.returnNewestByNameArch(patterns=pats) + except Errors.PackageSackError: + m = [] + availpkgs.extend(m) +@@ -3934,11 +3993,17 @@ class YumBase(depsolve.Depsolve): if (po.arch != installed_pkg.arch and (isMultiLibArch(po.arch) or isMultiLibArch(installed_pkg.arch))): @@ -798,7 +1428,7 @@ index f6e8a6b..36fc203 100644 else: donothingpkgs.append(po) -@@ -4462,17 +4490,20 @@ class YumBase(depsolve.Depsolve): +@@ -4462,17 +4527,20 @@ class YumBase(depsolve.Depsolve): be imported using askcb. @param po: Package object to retrieve the key of. @@ -823,7 +1453,7 @@ index f6e8a6b..36fc203 100644 for keyurl in keyurls: keys = self._retrievePublicKey(keyurl, repo) -@@ -4509,7 +4540,8 @@ class YumBase(depsolve.Depsolve): +@@ -4509,7 +4577,8 @@ class YumBase(depsolve.Depsolve): rc = askcb(po, info['userid'], info['hexkeyid']) if not rc: @@ -833,7 +1463,7 @@ index f6e8a6b..36fc203 100644 # Import the key ts = self.rpmdb.readOnlyTS() -@@ -4520,6 +4552,9 @@ class YumBase(depsolve.Depsolve): +@@ -4520,6 +4589,9 @@ class YumBase(depsolve.Depsolve): self.logger.info(_('Key imported successfully')) key_installed = True @@ -843,7 +1473,7 @@ index f6e8a6b..36fc203 100644 if not key_installed: raise Errors.YumBaseError, \ _('The GPG keys listed for the "%s" repository are ' \ -@@ -4543,11 +4578,13 @@ class YumBase(depsolve.Depsolve): +@@ -4543,11 +4615,13 @@ class YumBase(depsolve.Depsolve): @param destdir: destination of the gpg pub ring @param keyurl_list: list of urls for gpg keys @param is_cakey: bool - are we pulling in a ca key or not @@ -859,7 +1489,7 @@ index f6e8a6b..36fc203 100644 for keyurl in keyurl_list: keys = self._retrievePublicKey(keyurl, repo, getSig=not is_cakey) for info in keys: -@@ -4557,16 +4594,25 @@ class YumBase(depsolve.Depsolve): +@@ -4557,16 +4631,25 @@ class YumBase(depsolve.Depsolve): keyurl, info['hexkeyid'])) key_installed = True continue @@ -890,7 +1520,7 @@ index f6e8a6b..36fc203 100644 self._getKeyImportMessage(info, keyurl, keytype) rc = False if self.conf.assumeyes: -@@ -4579,7 +4625,8 @@ class YumBase(depsolve.Depsolve): +@@ -4579,7 +4662,8 @@ class YumBase(depsolve.Depsolve): if not rc: @@ -900,7 +1530,7 @@ index f6e8a6b..36fc203 100644 # Import the key result = misc.import_key_to_pubring(info['raw_key'], info['hexkeyid'], gpgdir=destdir) -@@ -4587,6 +4634,20 @@ class YumBase(depsolve.Depsolve): +@@ -4587,6 +4671,20 @@ class YumBase(depsolve.Depsolve): raise Errors.YumBaseError, _('Key import failed') self.logger.info(_('Key imported successfully')) key_installed = True @@ -921,7 +1551,7 @@ index f6e8a6b..36fc203 100644 if not key_installed: raise Errors.YumBaseError, \ -@@ -4775,26 +4836,31 @@ class YumBase(depsolve.Depsolve): +@@ -4775,26 +4873,31 @@ class YumBase(depsolve.Depsolve): def _doTestTransaction(self,callback,display=None): ''' Do the RPM test transaction ''' @@ -972,7 +1602,7 @@ index f6e8a6b..36fc203 100644 tsConf = {} for feature in ['diskspacecheck']: # more to come, I'm sure -@@ -4804,14 +4870,7 @@ class YumBase(depsolve.Depsolve): +@@ -4804,14 +4907,7 @@ class YumBase(depsolve.Depsolve): # overwrite the default display class if display: testcb.display = display @@ -987,7 +1617,7 @@ index f6e8a6b..36fc203 100644 tserrors = self.ts.test( testcb, conf=tsConf ) del testcb -@@ -4839,12 +4898,8 @@ class YumBase(depsolve.Depsolve): +@@ -4839,12 +4935,8 @@ class YumBase(depsolve.Depsolve): cb.display = display self.runTransaction( cb=cb ) @@ -1001,7 +1631,7 @@ index f6e8a6b..36fc203 100644 self.ts.check() for prob in self.ts.problems(): # Newer rpm (4.8.0+) has problem objects, older have just strings. -@@ -4852,7 +4907,6 @@ class YumBase(depsolve.Depsolve): +@@ -4852,7 +4944,6 @@ class YumBase(depsolve.Depsolve): # now just be compatible. results.append(to_str(prob)) @@ -1050,7 +1680,7 @@ index 97e5e3d..8c966f8 100644 fp.write(str(ini)) fp.close() diff --git a/yum/depsolve.py b/yum/depsolve.py -index de2849a..388811d 100644 +index de2849a..44ccfd7 100644 --- a/yum/depsolve.py +++ b/yum/depsolve.py @@ -69,6 +69,8 @@ class Depsolve(object): @@ -1077,7 +1707,15 @@ index de2849a..388811d 100644 self.verbose_logger.log(logginglevels.DEBUG_1, _('Adding Package %s in mode %s'), txmbr.po, txmbr.ts_state) if self.dsCallback: -@@ -673,11 +680,12 @@ class Depsolve(object): +@@ -343,6 +350,7 @@ class Depsolve(object): + providers = self.rpmdb.getProvides(needname, needflags, needversion) + + for inst_po in providers: ++ self._working_po = inst_po # store the last provider + inst_str = '%s.%s %s:%s-%s' % inst_po.pkgtup + (i_n, i_a, i_e, i_v, i_r) = inst_po.pkgtup + self.verbose_logger.log(logginglevels.DEBUG_2, +@@ -673,11 +681,12 @@ class Depsolve(object): if len(self.tsInfo) != length and txmbrs: return CheckDeps, errormsgs @@ -1092,7 +1730,23 @@ index de2849a..388811d 100644 return CheckDeps, errormsgs def _undoDepInstalls(self): -@@ -799,9 +807,9 @@ class Depsolve(object): +@@ -745,6 +754,7 @@ class Depsolve(object): + + + # check global FileRequires ++ self._working_po = None # reset the working po + if CheckRemoves: + CheckRemoves = False + for po, dep in self._checkFileRequires(): +@@ -758,6 +768,7 @@ class Depsolve(object): + continue + + # check Conflicts ++ self._working_po = None # reset the working po + if CheckInstalls: + CheckInstalls = False + for conflict in self._checkConflicts(): +@@ -799,9 +810,9 @@ class Depsolve(object): continue done.add((po, err)) self.verbose_logger.log(logginglevels.DEBUG_4, @@ -1136,11 +1790,60 @@ index 15e571f..8e81c34 100644 return '!%u!%s' % (datasize, data.hexdigest(sumtype)) return data.hexdigest(sumtype) +diff --git a/yum/packageSack.py b/yum/packageSack.py +index 153edbb..4af563a 100644 +--- a/yum/packageSack.py ++++ b/yum/packageSack.py +@@ -24,6 +24,7 @@ import re + import fnmatch + import misc + from packages import parsePackages ++import rpmUtils.miscutils + from rpmUtils.miscutils import compareEVR + + class PackageSackVersion: +@@ -702,6 +703,10 @@ class PackageSack(PackageSackBase): + def getProvides(self, name, flags=None, version=(None, None, None)): + """return dict { packages -> list of matching provides }""" + self._checkIndexes(failure='build') ++ if version is None: ++ version = (None, None, None) ++ elif type(version) in (str, type(None), unicode): ++ version = rpmUtils.miscutils.stringToVersion(version) + result = { } + for po in self.provides.get(name, []): + hits = po.matchingPrcos('provides', (name, flags, version)) +@@ -716,6 +721,10 @@ class PackageSack(PackageSackBase): + def getRequires(self, name, flags=None, version=(None, None, None)): + """return dict { packages -> list of matching requires }""" + self._checkIndexes(failure='build') ++ if version is None: ++ version = (None, None, None) ++ elif type(version) in (str, type(None), unicode): ++ version = rpmUtils.miscutils.stringToVersion(version) + result = { } + for po in self.requires.get(name, []): + hits = po.matchingPrcos('requires', (name, flags, version)) diff --git a/yum/packages.py b/yum/packages.py -index 6f61fea..db3e973 100644 +index 6f61fea..264aa9a 100644 --- a/yum/packages.py +++ b/yum/packages.py -@@ -1069,6 +1069,9 @@ class YumAvailablePackage(PackageObject, RpmBase): +@@ -497,11 +497,9 @@ class RpmBase(object): + else: + pri_only = False + +- files = self.returnFileEntries('file', pri_only) + \ +- self.returnFileEntries('dir', pri_only) + \ +- self.returnFileEntries('ghost', pri_only) +- if reqtuple[0] in files: +- return True ++ for ftype in ('file', 'dir', 'ghost'): ++ if reqtuple[0] in self.returnFileEntries(ftype, pri_only): ++ return True + + return False + +@@ -1069,6 +1067,9 @@ class YumAvailablePackage(PackageObject, RpmBase): if self.sourcerpm: msg += """ %s\n""" % misc.to_xml(self.sourcerpm) @@ -1150,6 +1853,28 @@ index 6f61fea..db3e973 100644 msg +=""" """ % (self.hdrstart, self.hdrend) msg += self._dump_pco('provides') +@@ -1129,7 +1130,7 @@ class YumAvailablePackage(PackageObject, RpmBase): + raise NotImplementedError() + + def _dump_requires(self): +- """returns deps in format""" ++ """returns deps in XML format""" + mylist = self._requires_with_pre() + + msg = "" +@@ -1150,8 +1151,10 @@ class YumAvailablePackage(PackageObject, RpmBase): + if name.startswith('rpmlib('): + continue + # this drops out requires that the pkg provides for itself. +- if name in self.provides_names or name in self.filelist + \ +- self.dirlist + self.ghostlist: ++ if name in self.provides_names or \ ++ (name.startswith('/') and \ ++ (name in self.filelist or name in self.dirlist or ++ name in self.ghostlist)): + if not flags: + continue + else: @@ -1243,18 +1246,32 @@ class YumHeaderPackage(YumAvailablePackage): self.ver = self.version self.rel = self.release @@ -1808,7 +2533,7 @@ index 83e56c6..39fa72e 100644 try: un = UpdateNotice(elem) diff --git a/yumcommands.py b/yumcommands.py -index ecce347..41f0092 100644 +index ecce347..fd69f05 100644 --- a/yumcommands.py +++ b/yumcommands.py @@ -46,7 +46,7 @@ def checkRootUID(base): @@ -1820,6 +2545,24 @@ index ecce347..41f0092 100644 msg = _(""" You have enabled checking of packages via GPG keys. This is a good thing. However, you do not have any GPG public keys installed. You need to download +@@ -207,7 +207,7 @@ class InstallCommand(YumCommand): + + class UpdateCommand(YumCommand): + def getNames(self): +- return ['update'] ++ return ['update', 'update-to'] + + def getUsage(self): + return _("[PACKAGE...]") +@@ -223,7 +223,7 @@ class UpdateCommand(YumCommand): + def doCommand(self, base, basecmd, extcmds): + self.doneCommand(base, _("Setting up Update Process")) + try: +- return base.updatePkgs(extcmds) ++ return base.updatePkgs(extcmds, update_to=(basecmd == 'update-to')) + except yum.Errors.YumBaseError, e: + return 1, [str(e)] + @@ -283,7 +283,7 @@ class InfoCommand(YumCommand): return ['info'] @@ -1845,6 +2588,24 @@ index ecce347..41f0092 100644 ypl.obsoletes = typl.obsoletes ypl.obsoletesTuples = typl.obsoletesTuples +@@ -690,7 +691,7 @@ class SearchCommand(YumCommand): + + class UpgradeCommand(YumCommand): + def getNames(self): +- return ['upgrade'] ++ return ['upgrade', 'upgrade-to'] + + def getUsage(self): + return 'PACKAGE...' +@@ -707,7 +708,7 @@ class UpgradeCommand(YumCommand): + base.conf.obsoletes = 1 + self.doneCommand(base, _("Setting up Upgrade Process")) + try: +- return base.updatePkgs(extcmds) ++ return base.updatePkgs(extcmds, update_to=(basecmd == 'upgrade-to')) + except yum.Errors.YumBaseError, e: + return 1, [str(e)] + @@ -972,6 +973,12 @@ class RepoListCommand(YumCommand): elif repo.mirrorlist: out += [base.fmtKeyValFill(_("Repo-mirrors : "), @@ -1859,7 +2620,7 @@ index ecce347..41f0092 100644 if not os.path.exists(repo.metadata_cookie): last = _("Unknown") diff --git a/yummain.py b/yummain.py -index c64b140..d0b8251 100755 +index c64b140..1b94153 100755 --- a/yummain.py +++ b/yummain.py @@ -23,6 +23,7 @@ import os.path @@ -1877,7 +2638,7 @@ index c64b140..d0b8251 100755 + def rpmdb_warn_checks(): + try: + probs = base._rpmdb_warn_checks(out=verbose_logger.info, warn=False) -+ except YumBaseError, e: ++ except Errors.YumBaseError, e: + # This is mainly for PackageSackError from rpmdb. + verbose_logger.info(_(" Yum checks failed: %s"), exception2msg(e)) + probs = [] diff --git a/yum.spec b/yum.spec index 32008e8..c9a905b 100644 --- a/yum.spec +++ b/yum.spec @@ -7,7 +7,7 @@ Summary: RPM package installer/updater/manager Name: yum Version: 3.2.29 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv2+ Group: System Environment/Base Source0: http://yum.baseurl.org/download/3.2/%{name}-%{version}.tar.gz @@ -246,6 +246,10 @@ exit 0 %config(noreplace) %{_sysconfdir}/sysconfig/yum-cron %changelog +* Fri Apr 8 2011 James Antill - 3.2.29-10 +- update to latest HEAD +- Likely last HEAD before 3.2.30. + * Fri Mar 25 2011 Seth Vidal - 3.2.29-9 - update to latest HEAD