Hi!
Curiosity killed the cat and the current _requiringFromTransaction(). I
thought that it should be possible to replace the
_requiringFromTransaction() code by calls to .install() and .update. It
turns out that this can be done quite simple although those methods need a
little upgrade.
Although all test cases pass this patch most likely needs a more testing and
checking. Especially cases where there are several possible packages
available are likely to have changed their results.
Have fun
Florian
>From c26b15b6e7d77ecaf485e799258d3a060b0bfb41 Mon Sep 17 00:00:00 2001
From: Florian Festi <[EMAIL PROTECTED]>
Date: Thu, 14 Feb 2008 16:45:28 +0100
Subject: [PATCH] Use update() and install() to implement _requiringFromTransaction()
---
yum/__init__.py | 55 +++++++++++------
yum/depsolve.py | 178 ++++++------------------------------------------------
2 files changed, 56 insertions(+), 177 deletions(-)
diff --git a/yum/__init__.py b/yum/__init__.py
index 2d7c1b6..cdba688 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -2018,7 +2018,7 @@ class YumBase(depsolve.Depsolve):
return returnlist
- def install(self, po=None, **kwargs):
+ def install(self, po=None, requiringPo=None, **kwargs):
"""try to mark for install the item specified. Uses provided package
object, if available. If not it uses the kwargs and gets the best
packages from the keyword options provided
@@ -2060,6 +2060,9 @@ class YumBase(depsolve.Depsolve):
if mypkgs:
pkgs.extend(self.bestPackagesFromList(mypkgs))
+ elif kwargs.has_key('pkgs'):
+ was_pattern = True
+ pkgs = kwargs['pkgs']
else:
nevra_dict = self._nevra_kwarg_parse(kwargs)
@@ -2077,21 +2080,26 @@ class YumBase(depsolve.Depsolve):
if rpmUtils.arch.isMultiLibArch():
if was_pattern or not nevra_dict['arch']: # and only if they
# they didn't specify an arch
- if self.conf.multilib_policy == 'best':
- pkgs_by_name = {}
- use = []
- not_added = []
- for pkg in pkgs:
- if pkg.arch in rpmUtils.arch.legitMultiArchesInSameLib():
- pkgs_by_name[pkg.name] = 1
- use.append(pkg)
- else:
- not_added.append(pkg)
- for pkg in not_added:
- if not pkg.name in pkgs_by_name:
- use.append(pkg)
+
+ if self.conf.multilib_policy == 'best' or requiringPo:
+ pkgs_by_name = {}
+ use = []
+ not_added = []
+ if requiringPo:
+ legitArches = set(rpmUtils.arch.legitMultiArchesInSameLib(requiringPo.arch))
+ else:
+ legitArches = set(rpmUtils.arch.legitMultiArchesInSameLib())
+ for pkg in pkgs:
+ if pkg.arch in legitArches:
+ pkgs_by_name[pkg.name] = 1
+ use.append(pkg)
+ else:
+ not_added.append(pkg)
+ for pkg in not_added:
+ if not pkg.name in pkgs_by_name:
+ use.append(pkg)
- pkgs = use
+ pkgs = use
pkgSack = ListPackageSack(pkgs)
pkgs = pkgSack.returnNewestByName()
@@ -2129,11 +2137,16 @@ class YumBase(depsolve.Depsolve):
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)
+ updated = False
+ for updated_pkg in self.up.updating_dict.get(po.pkgtup, []):
+ if not self.tsInfo.getMembersWithState(updated_pkg, TS_REMOVE_STATES):
+ txmbrs = self.update(po=po)
+ tx_return.extend(txmbrs)
+ updated = True
+ break
+ if updated:
continue
-
+
# make sure it's not already installed
if self.rpmdb.contains(po=po):
if not self.tsInfo.getMembersWithState(po.pkgtup, TS_REMOVE_STATES):
@@ -2151,6 +2164,8 @@ class YumBase(depsolve.Depsolve):
continue
txmbr = self.tsInfo.addInstall(po)
+ if requiringPo:
+ txmbr.setAsDep(requiringPo)
tx_return.append(txmbr)
return tx_return
@@ -2218,6 +2233,8 @@ class YumBase(depsolve.Depsolve):
instpkgs.extend(e)
instpkgs.extend(m)
+ elif kwargs.has_key('pkgs'):
+ availpkgs = kwargs['pkgs']
else: # we have kwargs, sort them out.
nevra_dict = self._nevra_kwarg_parse(kwargs)
diff --git a/yum/depsolve.py b/yum/depsolve.py
index 8c784eb..47a69fa 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -392,173 +392,35 @@ class Depsolve(object):
"""processes the dependency resolution for a dep where requiring
package is in the transaction set"""
- (name, arch, epoch, version, release) = requiringPo.pkgtup
- (needname, needflags, needversion) = requirement
+ needname, needflags, needversion = requirement
checkdeps = 0
missingdep = 0
- upgraded = {}
-
- #~ - if it's not available from some repository:
- #~ - mark as unresolveable.
- #
- #~ - if it's available from some repo:
- #~ - if there is an another version of the package currently installed then
- # - if the other version is marked in the transaction set
- # - if it's marked as erase
- # - mark the dep as unresolveable
-
- # - if it's marked as update or install
- # - check if the version for this requirement:
- # - if it is higher
- # - mark this version to be updated/installed
- # - remove the other version from the transaction set
- # - tell the transaction set to be rebuilt
- # - if it is lower
- # - mark the dep as unresolveable
- # - if they are the same
- # - be confused but continue
-
- provSack = self.whatProvides(needname, needflags, needversion)
-
- # get rid of things that are already in the rpmdb - b/c it's pointless to use them here
-
- for pkg in provSack.returnPackages():
- if pkg.pkgtup in self.rpmdb.simplePkgList(): # is it already installed?
- self.verbose_logger.log(logginglevels.DEBUG_2, _('%s is in providing packages but it is already installed, removing.'), pkg)
- provSack.delPackage(pkg)
- continue
-
- # we need to check to see, if we have anything similar to it (name-wise)
- # installed or in the ts, and this isn't a package that allows multiple installs
- # then if it's newer, fine - continue on, if not, then we're unresolveable
- # cite it and exit
-
- tspkgs = []
- if not self.allowedMultipleInstalls(pkg):
- # from ts
- tspkgs = self.tsInfo.matchNaevr(name=pkg.name, arch=pkg.arch)
- for tspkg in tspkgs:
- if tspkg.po.EVR > pkg.EVR:
- msg = _('Potential resolving package %s has newer instance in ts.') % pkg
- self.verbose_logger.log(logginglevels.DEBUG_2, msg)
- provSack.delPackage(pkg)
- continue
- elif tspkg.po.EVR < pkg.EVR:
- upgraded.setdefault(pkg.pkgtup, []).append(tspkg.pkgtup)
-
- # from rpmdb
- dbpkgs = self.rpmdb.searchNevra(name=pkg.name, arch=pkg.arch)
- for dbpkg in dbpkgs:
- if dbpkg.EVR > pkg.EVR:
- msg = _('Potential resolving package %s has newer instance installed.') % pkg
- self.verbose_logger.log(logginglevels.DEBUG_2, msg)
- provSack.delPackage(pkg)
- continue
- if len(provSack) == 0: # unresolveable
- missingdep = 1
- prob_pkg = "%s (%s)" % (requiringPo,requiringPo.repoid)
- msg = _('Missing Dependency: %s is needed by package %s') % \
- (rpmUtils.miscutils.formatRequire(needname, needversion, needflags),
- prob_pkg)
- errorlist.append(msg)
- return checkdeps, missingdep
-
- # iterate the provSack briefly, if we find the package is already in the
- # tsInfo then just skip this run
- for pkg in provSack.returnPackages():
- (n,a,e,v,r) = pkg.pkgtup
- pkgmode = self.tsInfo.getMode(name=n, arch=a, epoch=e, ver=v, rel=r)
- if pkgmode in ['i', 'u']:
- self.verbose_logger.log(logginglevels.DEBUG_2,
- _('%s already in ts, skipping this one'), pkg)
- # FIXME: Remove this line, if it is not needed ?
- # checkdeps = 1
- return checkdeps, missingdep
-
-
- # find the best one
-
- # try updating the already install pkgs
+ pkgs = self.whatProvides(needname, needflags, needversion).returnPackages()
length = len(self.tsInfo)
- for pkg in provSack.returnNewestByName():
- self.update(requiringPo=requiringPo, name=pkg.name, epoch=pkg.epoch, version=pkg.version, rel=pkg.rel)
- if len(self.tsInfo) != length:
- checkdeps = True
+ if pkgs:
+ txmbrs = self.update(requiringPo=requiringPo, pkgs=pkgs)
+ if length < len(self.tsInfo):
+ self.verbose_logger.debug(_('TSINFO: Marking %s as update for %s') %
+ (txmbrs[0].po, requiringPo))
+ checkdeps = 1
+ return checkdeps, missingdep
+ txmbrs = self.install(requiringPo=requiringPo, pkgs=pkgs)
+ if length < len(self.tsInfo):
+ self.verbose_logger.debug(_('TSINFO: Marking %s as install for %s'),
+ txmbrs[0].po, requiringPo)
+ checkdeps = 1
return checkdeps, missingdep
- # find out which arch of the ones we can choose from is closest
- # to the arch of the requesting pkg
- thisarch = requiringPo.arch
- newest = provSack.returnNewestByNameArch()
- if len(newest) > 1: # there's no way this can be zero
- best = newest[0]
- for po in newest[1:]:
- if thisarch != 'noarch':
- best_dist = archDifference(thisarch, best.arch)
- if isMultiLibArch(): # only go to the next one if we're multilib - i686 can satisfy i386 deps
- if best_dist == 0: # can't really use best's arch anyway...
- best = po # just try the next one - can't be much worse
- continue
-
- po_dist = archDifference(thisarch, po.arch)
- if po_dist > 0 and best_dist > po_dist:
- best = po
- continue
-
- if best_dist == po_dist:
- if len(po.name) < len(best.name):
- best=po
- continue
-
- elif len(po.name) < len(best.name):
- best = po
- elif len(po.name) == len(best.name):
- # compare arch
- arch = rpmUtils.arch.getBestArchFromList([po.arch, best.arch])
- if arch == po.arch:
- best = po
- elif len(newest) == 1:
- best = newest[0]
-
-
- if self.rpmdb.contains(po=best): # is it already installed?
- missingdep = 1
- checkdeps = 0
- prob_pkg = "%s (%s)" % (requiringPo,requiringPo.repoid)
- msg = _('Missing Dependency: %s is needed by package %s') % (needname, prob_pkg)
- errorlist.append(msg)
- return checkdeps, missingdep
-
-
-
- # FIXME - why can't we look up in the transaction set for the requiringPkg
- # and know what needs it that way and provide a more sensible dep structure in the txmbr
- inst = self.rpmdb.searchNevra(name=best.name, arch=best.arch)
- if len(inst) > 0:
- 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"
- else:
- self.verbose_logger.debug(_('TSINFO: Marking %s as install for %s'), best,
- requiringPo)
- txmbr = self.tsInfo.addInstall(best)
- txmbr.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
- # should mark them to be re-checked
- if upgraded.has_key(best.pkgtup):
- map(lambda x: self.tsInfo.remove(x), upgraded[best.pkgtup])
-
- checkdeps = 1
+ missingdep = 1
+ prob_pkg = "%s (%s)" % (requiringPo,requiringPo.repoid)
+ msg = _('Missing Dependency: %s is needed by package %s') % \
+ (rpmUtils.miscutils.formatRequire(needname, needversion, needflags),
+ prob_pkg)
+ errorlist.append(msg)
return checkdeps, missingdep
-
def _processConflict(self, po, conflict):
"""processes a Conflict dep from the resolveDeps() method"""
--
1.5.3.8
_______________________________________________
Yum-devel mailing list
[email protected]
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel