Florian Festi wrote:
Hi!

I'll post the single changes made to the Depsolver to adjust it to the getProvides/Requires interface. All patches of course require the getProvides patch series.

CheckFileRequires now handles problems in updates correctly (ignoring them). Be aware that there is a "check_removes = True" missing if combined with the
"Check transaction members that got removed from transaction set again" patch.

Florian
--- yum/depsolve.py-3	2007-06-14 14:29:06.000000000 +0200
+++ yum/depsolve.py	2007-06-14 18:59:00.000000000 +0200
@@ -759,6 +759,7 @@
 
 
         ret = []
+        check_removes = False
         for txmbr in self.tsInfo.getMembers():
             
             if self._dcobj.already_seen.has_key(txmbr):
@@ -773,10 +774,13 @@
                 thisneeds = self._checkInstall(txmbr)
             elif txmbr.output_state in TS_REMOVE_STATES:
                 thisneeds = self._checkRemove(txmbr)
+                check_removes = True
             if len(thisneeds) == 0:
                 self._dcobj.already_seen[txmbr] = 1
             ret.extend(thisneeds)
 
+        if check_removes:
+            ret.extend(self._checkFileRequires())
         ret.extend(self._checkConflicts())
             
         return ret
@@ -961,93 +965,89 @@
         po = txmbr.po
         provs = po.returnPrco('provides')
 
-        # get the files in the package and express them as "provides"
-        files = po.filelist
-        filesasprovs = map(lambda f: (f, None, (None,None,None)), files)
-        provs.extend(filesasprovs)
-
         # if this is an update, we should check what the new package
         # provides to make things faster
         newpoprovs = {}
         for newpo in txmbr.updated_by:
             for p in newpo.provides:
                 newpoprovs[p] = 1
-            for f in newpo.simpleFiles(): # newpo.filelist:
-                newpoprovs[(f, None, (None, None, None))] = 1
-
         ret = []
-        self._removing = []
-        goneprovs = {}
-        gonefiles = {}
-        removes = {}
         
         # iterate over the provides of the package being removed
         # and see what's actually going away
         for prov in provs:
             if prov[0].startswith('rpmlib('): # ignore rpmlib() provides
                 continue
-            if prov[0].startswith("/usr/share/doc"): # XXX: ignore doc files
-                continue
             if newpoprovs.has_key(prov):
                 continue
-            if not prov[0][0] == "/":
-                goneprovs[prov[0]] = prov
-            else:
-                gonefiles[prov[0]] = prov
+            for pkg, hits in self.tsInfo.getRequires(*prov).iteritems():
+                for rn, rf, rv in hits:
+                    if not self.tsInfo.getProvides(rn, rf, rv):
+                        reqtuple = (rn, version_tuple_to_string(rv), flags[rf])
+                        self._dcobj.addRequires(pkg, [reqtuple])
+                        ret.append(
+                            ((pkg.name, pkg.version, pkg.release),
+                             (rn, version_tuple_to_string(rv)),
+                             flags[rf], None, rpm.RPMDEP_SENSE_REQUIRES) )
+        return ret
 
-        # now see what from the rpmdb really requires these
-        for (provname, prov) in goneprovs.items() + gonefiles.items():
-            instrequirers = []
-            for pkgtup in self.rpmdb.whatRequires(provname, None, None):
-                instpo = self.getInstalledPackageObject(pkgtup)
-                instrequirers.append(instpo)
-            
-            self.verbose_logger.log(logginglevels.DEBUG_4, "looking to see what requires %s of %s", prov, po)
-            removes[prov] = self._requiredByPkg(prov, instrequirers)
+    def _checkFileRequires(self):
+        fileRequires = set()
+        reverselookup = {}
+        ret = []
 
-        # now, let's see if anything that we're installing requires anything
-        # that this provides
-        for txmbr in self.tsInfo.getMembersWithState(None, TS_INSTALL_STATES):
-            for r in txmbr.po.requires_names:
-                prov = None
-                if r in goneprovs.keys():
-                    prov = goneprovs[r]
-                elif r[0] == "/" and r in gonefiles:
-                    prov = gonefiles[r]
-
-                if prov and not removes.has_key(prov):
-                    removes[prov] = self._requiredByPkg(prov, [txmbr.po])
-                elif prov:
-                    removes[prov].extend(self._requiredByPkg(prov, [txmbr.po]))                        
-
-        # now we know what needs to be removed and the provide causing it
-        # to be removed.  let's stick them in the ret list
-        for (prov, removeList) in removes.items():
-            (r, f, v) = prov
-            for po in removeList:
-                flags = {"GT": rpm.RPMSENSE_GREATER,
-                         "GE": rpm.RPMSENSE_EQUAL | rpm.RPMSENSE_GREATER,
-                         "LT": rpm.RPMSENSE_LESS,
-                         "LE": rpm.RPMSENSE_LESS | rpm.RPMSENSE_EQUAL,
-                         "EQ": rpm.RPMSENSE_EQUAL,
-                         None: 0 }
-                f = v = None
-                for (rr, rf, rv) in po.requires:
-                    if rr == r:
-                        f = rf
-                        v = rv
-                        break
+        # generate list of file requirement in rpmdb
+        if self.installedFileRequires is None:
+            self.installedFileRequires = {}
+            self.installedUnresolvedFileRequires = set()
+            resolved = set()
+            for pkg in self.rpmdb.returnPackages():
+                for name, flag, evr in pkg.requires:
+                    if not name.startswith('/'):
+                        continue
+                    self.installedFileRequires.setdefault(pkg, []).append(name)
+                    if name not in resolved:
+                        dep = self.rpmdb.getProvides(name, flag, evr)
+                        resolved.add(name)
+                        if not dep:
+                            self.installedUnresolvedFileRequires.add(name)
+
+        # get file requirements from packages not deleted
+        for po, files in self.installedFileRequires.iteritems():
+            if not self._tsInfo.getMembersWithState(po.pkgtup, output_states=TS_REMOVE_STATES):
+                fileRequires.update(files)
+                for filename in files:
+                    reverselookup.setdefault(filename, []).append(po)
+
+        fileRequires -= self.installedUnresolvedFileRequires
+
+        # get file requirements from new packages
+        for txmbr in self._tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES):
+            for name, flag, evr in txmbr.po.requires:
+                if name.startswith('/'):
+                    # check if file requires was already unresolved in update
+                    if name in self.installedUnresolvedFileRequires:
+                        already_broken = False
+                        for oldpo in txmbr.updates:
+                            if oldpo.checkPrco('requires', (name, None, (None, None, None))):
+                                already_broken = True
+                                break
+                        if already_broken:
+                            continue
+                    fileRequires.add(name)
+                    reverselookup.setdefault(name, []).append(txmbr.po)
 
-                self._removing.append(po.pkgtup)
-                reqtuple = (r, version_tuple_to_string(v), flags[f])
-                self._dcobj.addRequires(po, [reqtuple])
-                
-                ret.append( ((po.name, po.version, po.release),
-                             (r, version_tuple_to_string(v)),
-                             flags[f], None, rpm.RPMDEP_SENSE_REQUIRES) )
+        # check the file requires
+        for filename in fileRequires:
+            if not self.tsInfo.getOldProvides(filename) and not self.tsInfo.getNewProvides(filename):
+                for po in reverselookup[filename]:
+                    ret.append( ((po.name, po.version, po.release),
+                                 (filename, ''), 0, None,
+                                 rpm.RPMDEP_SENSE_REQUIRES) )
 
         return ret
 
+
     def _checkConflicts(self):
         ret = [ ]
         for po in self.rpmdb.returnPackages():
_______________________________________________
Yum-devel mailing list
[email protected]
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel

Reply via email to