[yum-cvs] yum/yum packageSack.py, NONE, 1.1 repoMDObject.py, NONE, 1.1 Errors.py, 1.7, 1.8 __init__.py, 1.203, 1.204 depsolve.py, 1.81, 1.82 misc.py, 1.13, 1.14 packages.py, 1.44, 1.45 repos.py, 1.93, 1.94 sqlitesack.py, 1.34, 1.35 yumRepo.py, 1.7, 1.8

Seth Vidal skvidal at linux.duke.edu
Sun May 28 05:32:51 UTC 2006


Update of /home/groups/yum/cvs/yum/yum
In directory login1.linux.duke.edu:/tmp/cvs-serv5665

Modified Files:
	Errors.py __init__.py depsolve.py misc.py packages.py repos.py 
	sqlitesack.py yumRepo.py 
Added Files:
	packageSack.py repoMDObject.py 
Log Message:

- move files from repomd into yum
- modify lots of things to make this work

--- NEW FILE packageSack.py ---
#!/usr/bin/python -tt
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Copyright 2006 Duke University

from Errors import PackageSackError
import rpmUtils.miscutils

class PackageSackBase:
    """Base class that provides the interface for PackageSacks."""
    def __init__(self):
        self.added = {}

    def __len__(self):
        return len(self.simplePkgList())
        
    def __iter__(self):
        if hasattr(self.returnPackages(), '__iter__'):
            return self.returnPackages().__iter__()
        else:
            return iter(self.returnPackages())

    def setCompatArchs(self, compatArchs):
        raise NotImplementedError()

    def populate(self, repo, with, callback, cacheOnly):
        raise NotImplementedError()
        
    def packagesByTuple(self, pkgtup):
        """return a list of package objects by (n,a,e,v,r) tuple"""
        raise NotImplementedError()
        
    def searchNevra(self, name=None, epoch=None, ver=None, rel=None, arch=None):
        """return list of pkgobjects matching the nevra requested"""
        raise NotImplementedError()
           
    def searchRequires(self, name):
        """return list of package requiring the name (any evr and flag)"""
        raise NotImplementedError()

    def searchProvides(self, name):
        """return list of package providing the name (any evr and flag)"""
        raise NotImplementedError()

    def searchConflicts(self, name):
        """return list of package conflicting with the name (any evr and flag)"""
        raise NotImplementedError()

    def searchObsoletes(self, name):
        """return list of package obsoleting the name (any evr and flag)"""
        raise NotImplementedError()

    def returnObsoletes(self):
        """returns a dict of obsoletes dict[obsoleting pkgtuple] = [list of obs]"""
        raise NotImplementedError()

    def searchFiles(self, file):
        """return list of packages by filename"""
        raise NotImplementedError()

    def addPackage(self, obj):
        """add a pkgobject to the packageSack"""
        raise NotImplementedError()

    def buildIndexes(self):
        """builds the useful indexes for searching/querying the packageSack
           This should be called after all the necessary packages have been
           added/deleted"""
        raise NotImplementedError()

    def delPackage(self, obj):
        """delete a pkgobject"""
        raise NotImplementedError()

    def returnPackages(self):
        """return list of all packages"""
        raise NotImplementedError()

    def returnNewestByNameArch(self, naTup=None):
        """return list of newest packages based on name, arch matching
           this means(in name.arch form): foo.i386 and foo.noarch are not
           compared to each other for highest version only foo.i386 and
           foo.i386 will be compared"""
        raise NotImplementedError()

    def returnNewestByName(self, name=None):
        """return list of newest packages based on name matching
           this means(in name.arch form): foo.i386 and foo.noarch will
           be compared to each other for highest version"""
        raise NotImplementedError()

    def simplePkgList(self):
        """returns a list of pkg tuples (n, a, e, v, r)"""
        raise NotImplementedError()

    def printPackages(self):
        raise NotImplementedError()

    def excludeArchs(self, archlist):
        """exclude incompatible arches. archlist is a list of compatible arches"""
        raise NotImplementedError()

    def searchPackages(self, fields, criteria_re, callback):
        raise NotImplementedError()


class MetaSack(PackageSackBase):
    """Represents the aggregate of multiple package sacks, such that they can
       all be treated as one unified sack."""

    def __init__(self):
        PackageSackBase.__init__(self)
        self.sacks = {}
        self.compatarchs = None

    def addSack(self, repoid, sack):
        """Adds a repository's packageSack to this MetaSack."""
        self.sacks[repoid] = sack

        # Make sure the new sack follows the same rules we have been given.
        sack.setCompatArchs(self.compatarchs)

    def populate(self, repo, with, callback, cacheOnly):
        self.sacks[repo.id].populate(repo, with, callback, cacheOnly)

    def setCompatArchs(self, compatArchs):
        for sack in self.sacks.values():
            sack.setCompatArchs(compatArchs)

    def packagesByTuple(self, pkgtup):
        """return a list of package objects by (n,a,e,v,r) tuple"""
        return self._computeAggregateListResult("packagesByTuple", pkgtup)

    def searchNevra(self, name=None, epoch=None, ver=None, rel=None, arch=None):
        """return list of pkgobjects matching the nevra requested"""
        return self._computeAggregateListResult("searchNevra", name, epoch, ver, rel, arch)

    def searchRequires(self, name):
        """return list of package requiring the name (any evr and flag)"""
        return self._computeAggregateListResult("searchRequires", name)

    def searchProvides(self, name):
        """return list of package providing the name (any evr and flag)"""
        return self._computeAggregateListResult("searchProvides", name)

    def searchConflicts(self, name):
        """return list of package conflicting with the name (any evr and flag)"""
        return self._computeAggregateListResult("searchConflicts", name)

    def searchObsoletes(self, name):
        """return list of package obsoleting the name (any evr and flag)"""
        return self._computeAggregateListResult("searchObsoletes", name)

    def returnObsoletes(self):
        """returns a dict of obsoletes dict[obsoleting pkgtuple] = [list of obs]"""
        return self._computeAggregateDictResult("returnObsoletes")

    def searchFiles(self, file):
        """return list of packages by filename"""
        return self._computeAggregateListResult("searchFiles", file)

    def addPackage(self, obj):
        """Add a pkgobject to the packageSack.  This is a meaningless operation
           for the MetaSack."""
        pass

    def buildIndexes(self):
        """builds the useful indexes for searching/querying the packageSack
           This should be called after all the necessary packages have been
           added/deleted"""
        for sack in self.sacks.values():
            sack.buildIndexes()

    def delPackage(self, obj):
        """Delete a pkgobject.  This is a meaningless operation for MetaSack."""
        pass

    def returnPackages(self, repoid=None):
        """return list of all packages, takes optional repoid"""
        if not repoid:
            return self._computeAggregateListResult("returnPackages")
        return self.sacks[repoid].returnPackages()

    def returnNewestByNameArch(self, naTup=None):
        """return list of newest packages based on name, arch matching
           this means(in name.arch form): foo.i386 and foo.noarch are not
           compared to each other for highest version only foo.i386 and
           foo.i386 will be compared"""
        return self._computeAggregateListResult("returnNewestByNameArch", naTup)

    def returnNewestByName(self, name=None):
        """return list of newest packages based on name matching
           this means(in name.arch form): foo.i386 and foo.noarch will
           be compared to each other for highest version"""
        return self._computeAggregateListResult("returnNewestByName", name)

    def simplePkgList(self, repoid=None):
        """returns a list of pkg tuples (n, a, e, v, r) optionally from a
           single repoid"""
        if not repoid:
            return self._computeAggregateListResult("simplePkgList")
        return self.sacks[repoid].simplePkgList()

    def printPackages(self):
        for sack in self.sacks.values():
            sack.printPackages()

    def excludeArchs(self, archlist):
        """exclude incompatible arches. archlist is a list of compatible arches"""
        for sack in self.sacks.values():
            sack.excludeArchs(archlist)

    def searchPackages(self, fields, criteria_re, callback):
        return self._computeAggregateDictResult("searchPackages", fields, criteria_re, callback)

    def _computeAggregateListResult(self, methodName, *args):
        result = []
        for sack in self.sacks.values():
            if hasattr(sack, methodName):
                method = getattr(sack, methodName)
                sackResult = apply(method, args)
                if sackResult:
                    result.extend(sackResult)
        return result

    def _computeAggregateDictResult(self, methodName, *args):
        result = {}
        for sack in self.sacks.values():
            if hasattr(sack, methodName):
                method = getattr(sack, methodName)
                sackResult = apply(method, args)
                if sackResult:
                    result.update(sackResult)
        return result



class PackageSack(PackageSackBase):
    """represents sets (sacks) of Package Objects"""
    def __init__(self):
        self.nevra = {} #nevra[(Name, Epoch, Version, Release, Arch)] = []
        self.obsoletes = {} #obs[obsoletename] = [pkg1, pkg2, pkg3] 
                 #the package lists are packages that obsolete the key name
        self.requires = {} #req[reqname] = [pkg1, pkg2, pkg3]
                 #the package lists are packages that require the key name
        self.provides = {} #ditto of above but for provides
        self.conflicts = {} #ditto of above but for conflicts
        self.filenames = {} # duh
        self.pkgsByRepo = {} #pkgsByRepo['repoid']= [pkg1, pkg2, pkg3]
        self.pkgsByID = {} #pkgsById[pkgid] = [pkg1, pkg2] (should really only ever be one value but
                           #you might have repos with the same package in them
        self.compatarchs = None # dict of compatible archs for addPackage
        self.indexesBuilt = 0
        
        
    def __len__(self):
        return len(self.simplePkgList())
    
    def __iter__(self):
        if hasattr(self.returnPackages(), '__iter__'):
            return self.returnPackages().__iter__()
        else:
            return iter(self.returnPackages())

    def _checkIndexes(self, failure='error'):
        """check to see if the indexes are built, if not do what failure demands
           either error out or build the indexes, default is to error out"""
           
        if not self.indexesBuilt:
            if failure == 'error':
                raise PackageSackError, 'Indexes not yet built, cannot search'
            elif failure == 'build':
                self.buildIndexes()

    def setCompatArchs(self, compatarchs):
        self.compatarchs = compatarchs

    def packagesByTuple(self, pkgtup):
        """return a list of package objects by (n,a,e,v,r) tuple"""
        (n,a,e,v,r) = pkgtup
        return self.searchNevra(name=n, arch=a, epoch=e, ver=v, rel=r)
        
    def searchNevra(self, name=None, epoch=None, ver=None, rel=None, arch=None):
        """return list of pkgobjects matching the nevra requested"""
        self._checkIndexes(failure='build')
        if self.nevra.has_key((name, epoch, ver, rel, arch)):
            return self.nevra[(name, epoch, ver, rel, arch)]
        else:
            return []
           
    def searchRequires(self, name):
        """return list of package requiring the name (any evr and flag)"""
        self._checkIndexes(failure='build')        
        if self.requires.has_key(name):
            return self.requires[name]
        else:
            return []

    def searchProvides(self, name):
        """return list of package providing the name (any evr and flag)"""
        # FIXME - should this do a pkgobj.checkPrco((name, flag, (e,v,r,))??
        # has to do a searchFiles and a searchProvides for things starting with /
        self._checkIndexes(failure='build')        
        returnList = []
        if name[0] == '/':
             returnList.extend(self.searchFiles(name))
        if self.provides.has_key(name):
            returnList.extend(self.provides[name])
        return returnList

    def searchConflicts(self, name):
        """return list of package conflicting with the name (any evr and flag)"""
        self._checkIndexes(failure='build')        
        if self.conflicts.has_key(name):
            return self.conflicts[name]
        else:
            return []

    def searchObsoletes(self, name):
        """return list of package obsoleting the name (any evr and flag)"""
        self._checkIndexes(failure='build')        
        if self.obsoletes.has_key(name):
            return self.obsoletes[name]
        else:
            return []

    def returnObsoletes(self):
        """returns a dict of obsoletes dict[obsoleting pkgtuple] = [list of obs]"""
        obs = {}
        for po in self.returnPackages():
            pkgtuple = po.returnPackageTuple()
            if len(po.returnPrco('obsoletes')) == 0:
                continue

            if not obs.has_key(pkgtuple):
                obs[pkgtuple] = po.returnPrco('obsoletes')
            else:
                obs[pkgtuple].extend(po.returnPrco('obsoletes'))
        
        return obs
        
    def searchFiles(self, file):
        """return list of packages by filename
           FIXME - need to add regex match against keys in file list
        """
        self._checkIndexes(failure='build')
        if self.filenames.has_key(file):
            return self.filenames[file]
        else:
            return []

    def _addToDictAsList(self, dict, key, data):
        if not dict.has_key(key):
            dict[key] = []
        #if data not in dict[key]: - if I enable this the whole world grinds to a halt
        # need a faster way of looking for the object in any particular list
        dict[key].append(data)

    def _delFromListOfDict(self, dict, key, data):
        if not dict.has_key(key):
            dict[key] = []
        try:
            dict[key].remove(data)
        except ValueError:
            pass
            
        if len(dict[key]) == 0: # if it's an empty list of the dict, then kill it
            del dict[key]
            
            
    def addPackage(self, obj):
        """add a pkgobject to the packageSack"""

        repoid = obj.returnSimple('repoid')
        (name, epoch, ver, rel, arch) = obj.returnNevraTuple()
        
        if self.compatarchs:
            if self.compatarchs.has_key(arch):
                self._addToDictAsList(self.pkgsByRepo, repoid, obj)
        else:
            self._addToDictAsList(self.pkgsByRepo, repoid, obj)


    def buildIndexes(self):
        """builds the useful indexes for searching/querying the packageSack
           This should be called after all the necessary packages have been 
           added/deleted"""
        
        # blank out the indexes
        self.obsoletes = {}
        self.requires = {}
        self.provides = {}
        self.conflicts = {}
        self.filenames = {}
        self.nevra = {}
        self.pkgsByID = {}
        
        for repoid in self.pkgsByRepo.keys():
            for obj in self.pkgsByRepo[repoid]:
            # store the things provided just on name, not the whole require+version
            # this lets us reduce the set of pkgs to search when we're trying to depSolve
                for (n, fl, (e,v,r)) in obj.returnPrco('obsoletes'):
                    self._addToDictAsList(self.obsoletes, n, obj)
                for (n, fl, (e,v,r)) in obj.returnPrco('requires'):
                    self._addToDictAsList(self.requires, n, obj)
                for (n, fl, (e,v,r)) in obj.returnPrco('provides'):
                    self._addToDictAsList(self.provides, n, obj)
                for (n, fl, (e,v,r)) in obj.returnPrco('conflicts'):
                    self._addToDictAsList(self.conflicts, n, obj)
                for ftype in obj.returnFileTypes():
                    for file in obj.returnFileEntries(ftype):
                        self._addToDictAsList(self.filenames, file, obj)
                self._addToDictAsList(self.pkgsByID, obj.returnSimple('id'), obj)
                (name, epoch, ver, rel, arch) = obj.returnNevraTuple()
                self._addToDictAsList(self.nevra, (name, epoch, ver, rel, arch), obj)
                self._addToDictAsList(self.nevra, (name, None, None, None, None), obj)
        
        self.indexesBuilt = 1
        

        
    def delPackage(self, obj):
        """delete a pkgobject"""
        self._delFromListOfDict(self.pkgsByRepo, obj.returnSimple('repoid'), obj)
        if self.indexesBuilt: # if we've built indexes, delete it b/c we've just deleted something
            self.indexesBuilt = 0
        
    def returnPackages(self, repoid=None):
        """return list of all packages, takes optional repoid"""
        returnList = []
        if repoid is None:
            for repo in self.pkgsByRepo.keys():
                returnList.extend(self.pkgsByRepo[repo])
        else:
            try:
                returnList = self.pkgsByRepo[repoid]
            except KeyError:
                # nothing to return
                pass
        
        return returnList

    def returnNewestByNameArch(self, naTup=None):
        """return list of newest packages based on name, arch matching
           this means(in name.arch form): foo.i386 and foo.noarch are not 
           compared to each other for highest version only foo.i386 and 
           foo.i386 will be compared"""
        highdict = {}
        # If naTup is set, only iterate through packages that match that
        # name
        if (naTup):
            where = self.nevra.get((naTup[0],None,None,None,None))
            if (not where):
                raise PackageSackError, 'No Package Matching %s.%s' % naTup
        else:
            where = self.returnPackages()

        for pkg in where:
            (n, e, v ,r, a) = pkg.returnNevraTuple()
            if not highdict.has_key((n, a)):
                highdict[(n, a)] = pkg
            else:
                pkg2 = highdict[(n, a)]
                (e2, v2, r2) = pkg2.returnEVR()
                rc = rpmUtils.miscutils.compareEVR((e,v,r), (e2, v2, r2))
                if rc > 0:
                    highdict[(n, a)] = pkg
        
        if naTup:
            if highdict.has_key(naTup):
                return highdict[naTup]
            else:
                raise PackageSackError, 'No Package Matching %s.%s' % naTup
        
        return highdict.values()
        
    def returnNewestByName(self, name=None):
        """return list of newest packages based on name matching
           this means(in name.arch form): foo.i386 and foo.noarch will
           be compared to each other for highest version"""
        highdict = {}
        for pkg in self.returnPackages():
            (n, e, v ,r, a) = pkg.returnNevraTuple()
            if not highdict.has_key(n):
                highdict[n] = []
                highdict[n].append(pkg)
            else:
                pkg2 = highdict[n][0]
                (e2, v2, r2) = pkg2.returnEVR()
                rc = rpmUtils.miscutils.compareEVR((e,v,r), (e2, v2, r2))
                if rc > 0:
                    highdict[n] = [pkg]
                elif rc == 0:
                    highdict[n].append(pkg)
                
        if name:
            if highdict.has_key(name):
                return highdict[name]
            else:
                raise PackageSackError, 'No Package Matching  %s' % name
                
        return highdict.values()
           
    def simplePkgList(self, repoid=None):
        """returns a list of pkg tuples (n, a, e, v, r) optionally from a single repoid"""
        simplelist = []
        for pkg in self.returnPackages(repoid):
            simplelist.append(pkg.returnPackageTuple())
        return simplelist
                       
    def printPackages(self):
        for pkg in self.returnPackages():
            print pkg.returnNevraPrintable()

    def excludeArchs(self, archlist):
        """exclude incompatible arches. archlist is a list of compatible arches"""
        
        for pkg in self.returnPackages():
            if pkg.arch not in archlist:
                self.delPackage(pkg)

    def searchPackages(self, fields, criteria_re, callback):
        matches = {}

        for po in self.returnPackages():
            tmpvalues = []
            for field in fields:
                value = po.returnSimple(field)
                if value and criteria_re.search(value):
                    tmpvalues.append(value)
            if len(tmpvalues) > 0:
                if callback:
                    callback(po, tmpvalues)
                matches[po] = tmpvalues
 
        return matches

class ListPackageSack(PackageSack):
    """Derived class from PackageSack to build new Sack from list of
       pkgObjects - like one returned from self.returnNewestByNameArch()
       or self.returnNewestByName()"""
       
    def __init__(self, Objlist=None):
        PackageSack.__init__(self)
        if Objlist is not None:
            self.addList(Objlist)
    
    def addList(self, ObjList):
        for pkgobj in ObjList:
            self.addPackage(pkgobj)
    

--- NEW FILE repoMDObject.py ---
#!/usr/bin/python -tt
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Copyright 2006 Duke University

from cElementTree import iterparse
from Errors import RepoMDError

import sys

def ns_cleanup(qn):
    if qn.find('}') == -1: return qn 
    return qn.split('}')[1]

class RepoData:
    """represents anything beneath a <data> tag"""
    def __init__(self, elem):
        self.type = elem.attrib.get('type')
        self.location = (None, None)
        self.checksum = (None,None) # type,value
        self.openchecksum = (None,None) # type,value
        self.timestamp = None
    
        self.parse(elem)

    def parse(self, elem):
        
        for child in elem:
            child_name = ns_cleanup(child.tag)
            if child_name == 'location':
                relative = child.attrib.get('href')
                base = child.attrib.get('base')
                self.location = (base, relative)
            
            elif child_name == 'checksum':
                csum_value = child.text
                csum_type = child.attrib.get('type')
                self.checksum = (csum_type,csum_value)

            elif child_name == 'open-checksum':
                csum_value = child.text
                csum_type = child.attrib.get('type')
                self.openchecksum = (csum_type, csum_value)
            
            elif child_name == 'timestamp':
                self.timestamp = child.text
    
        
class RepoMD:
    """represents the repomd xml file"""
    
    def __init__(self, repoid, srcfile):
        """takes a repoid and a filename for the repomd.xml"""
        
        self.repoid = repoid
        self.repoData = {}
        
        if type(srcfile) == type('str'):
            # srcfile is a filename string
            infile = open(srcfile, 'rt')
        else:
            # srcfile is a file object
            infile = srcfile
        
        parser = iterparse(infile)

        for event, elem in parser:
            elem_name = ns_cleanup(elem.tag)
            
            if elem_name == "data":
                thisdata = RepoData(elem=elem)
                self.repoData[thisdata.type] = thisdata
            
    def fileTypes(self):
        """return list of metadata file types available"""
        return self.repoData.keys()
    
    def getData(self, type):
        if self.repoData.has_key(type):
            return self.repoData[type]
        else:
            raise RepoMDError, "Error: requested datatype %s not available"
            
    def dump(self):
        """dump fun output"""
        
        for ft in self.fileTypes():
            thisdata = self.repoData[ft]
            print 'datatype: %s' % thisdata.type
            print 'location: %s %s' % thisdata.location
            print 'timestamp: %s' % thisdata.timestamp
            print 'checksum: %s -%s' % thisdata.checksum
            print 'open checksum: %s - %s' %  thisdata.openchecksum

def main():

    try:
        print sys.argv[1]
        p = RepoMD('repoid', sys.argv[1])
        p.dump()
        
    except IOError:
        print >> sys.stderr, "newcomps.py: No such file:\'%s\'" % sys.argv[1]
        sys.exit(1)
        
if __name__ == '__main__':
    main()


Index: Errors.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/Errors.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Errors.py	21 Nov 2005 06:16:05 -0000	1.7
+++ Errors.py	28 May 2006 05:32:49 -0000	1.8
@@ -69,3 +69,13 @@
     def __init__(self, args=None):
         YumBaseError.__init__(self)
         self.args = args
+
+class RepoMDError(YumBaseError):
+    def __init__(self, args=None):
+        YumBaseError.__init__(self)
+        self.args = args
+
+class PackageSackError(YumBaseError):
+    def __init__(self, args=None):
+        YumBaseError.__init__(self)
+        self.args = args

Index: __init__.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/__init__.py,v
retrieving revision 1.203
retrieving revision 1.204
diff -u -r1.203 -r1.204
--- __init__.py	24 May 2006 23:23:34 -0000	1.203
+++ __init__.py	28 May 2006 05:32:49 -0000	1.204
@@ -44,9 +44,8 @@
 
 
 from packages import parsePackages, YumAvailablePackage, YumLocalPackage, YumInstalledPackage
-from repomd import mdErrors
 from constants import *
-from repomd.packageSack import ListPackageSack
+from packageSack import ListPackageSack
 
 __version__ = '2.9.0'
 
@@ -330,7 +329,7 @@
                 raise Errors.RepoError, "Repository '%s' not yet setup" % repo
             try:
                 groupremote = repo.getGroupLocation()
-            except mdErrors.RepoMDError, e:
+            except Errors.RepoMDError, e:
                 pass
             else:
                 reposWithGroups.append(repo)

Index: depsolve.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/depsolve.py,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -r1.81 -r1.82
--- depsolve.py	25 May 2006 22:06:19 -0000	1.81
+++ depsolve.py	28 May 2006 05:32:49 -0000	1.82
@@ -25,9 +25,8 @@
 from misc import unique
 import rpm
 
-from repomd.packageSack import ListPackageSack
-from repomd.mdErrors import PackageSackError
-from Errors import DepError, RepoError
+from packageSack import ListPackageSack
+from Errors import DepError, RepoError, PackageSackError
 from constants import *
 import packages
 

Index: misc.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/misc.py,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- misc.py	3 Dec 2005 17:12:39 -0000	1.13
+++ misc.py	28 May 2006 05:32:49 -0000	1.14
@@ -297,3 +297,15 @@
     else:
         return -1
         
+def newestInList(pkgs):
+    # return the newest in the list of packages
+    ret = [ pkgs.pop() ]
+    newest = ret[0].returnEVR()
+    for pkg in pkgs:
+        rc = compareEVR(pkg.returnEVR(), newest)
+        if rc > 0:
+            ret = [ pkg ]
+            newest = pkg.returnEVR()
+        elif rc == 0:
+            ret.append(pkg)
+    return ret

Index: packages.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/packages.py,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- packages.py	11 Apr 2006 21:34:35 -0000	1.44
+++ packages.py	28 May 2006 05:32:49 -0000	1.45
@@ -27,8 +27,6 @@
 import rpmUtils.miscutils
 import Errors
 
-import repomd.packageObject
-
 base=None
 
 def buildPkgRefDict(pkgs):
@@ -107,13 +105,172 @@
 
 # goal for the below is to have a packageobject that can be used by generic
 # functions independent of the type of package - ie: installed or available
-class YumAvailablePackage(repomd.packageObject.PackageObject, repomd.packageObject.RpmBase):
-    """derived class for the repomd packageobject and RpmBase packageobject yum
+class PackageObject:
+    """Base Package Object - sets up the default storage dicts and the
+       most common returns"""
+       
+    def __init__(self):
+        self.simple = {} # simple things, name, arch, e,v,r, size, etc
+        self.checksums = [] # (type, checksum, id(0,1)
+
+    def __str__(self):
+        return self.returnNevraPrintable()
+
+    def returnSimple(self, varname):
+        return self.simple[varname]
+
+    def simpleItems(self):
+        return self.simple.keys()            
+
+    def returnID(self):
+        return self.returnSimple('id')
+
+    def returnPackageTuple(self):
+        return (self.returnSimple('name'), self.returnSimple('arch'), 
+                self.returnSimple('epoch'),self.returnSimple('version'), 
+                self.returnSimple('release'))
+        
+    def returnNevraTuple(self):
+        return (self.returnSimple('name'), self.returnSimple('epoch'), 
+                self.returnSimple('version'),self.returnSimple('release'), 
+                self.returnSimple('arch'))
+    
+    def returnNevraPrintable(self):
+        """return printable string for the pkgname/object
+           name - epoch:ver-rel.arch"""
+        if self.returnSimple('epoch') == '0':
+            string = '%s - %s-%s.%s' % (self.returnSimple('name'), 
+                                        self.returnSimple('version'),
+                                        self.returnSimple('release'), 
+                                        self.returnSimple('arch'))
+        else:
+            string = '%s - %s:%s-%s.%s' % (self.returnSimple('name'), 
+                                           self.returnSimple('epoch'), 
+                                           self.returnSimple('version'), 
+                                           self.returnSimple('release'), 
+                                           self.returnSimple('arch'))
+        return string                                           
+
+    def returnEVR(self):
+        """returns a tuple of epoch, ver, rel"""
+        return (self.returnSimple('epoch'), self.returnSimple('version'), self.returnSimple('release'))
+        
+        return                            
+
+    def returnChangelog(self):
+        """return changelog entries"""
+        return self.changelog
+
+
+class RpmBase:
+    """return functions and storage for rpm-specific data"""
+
+    def __init__(self):
+        self.prco = {}
+        self.prco['obsoletes'] = [] # (name, flag, (e,v,r))
+        self.prco['conflicts'] = [] # (name, flag, (e,v,r))
+        self.prco['requires'] = [] # (name, flag, (e,v,r))
+        self.prco['provides'] = [] # (name, flag, (e,v,r))
+        self.files = {}
+        self.files['file'] = []
+        self.files['dir'] = []
+        self.files['ghost'] = []
+        self.changelog = [] # (ctime, cname, ctext)
+        self.licenses = []
+    
+    def returnPrco(self, prcotype):
+        """return list of provides, requires, conflicts or obsoletes"""
+        if self.prco.has_key(prcotype):
+            return self.prco[prcotype]
+        else:
+            return []
+
+    def checkPrco(self, prcotype, prcotuple):
+        """returns 1 or 0 if the pkg contains the requested tuple/tuple range"""
+        # get rid of simple cases - nothing
+        if not self.prco.has_key(prcotype):
+            return 0
+        # exact match    
+        if prcotuple in self.prco[prcotype]:
+            return 1
+        else:
+            # make us look it up and compare
+            (reqn, reqf, (reqe, reqv ,reqr)) = prcotuple
+            if reqf is not None:
+                if self.inPrcoRange(prcotype, prcotuple):
+                    return 1
+                else:
+                    return 0
+            else:
+                for (n, f, (e, v, r)) in self.returnPrco(prcotype):
+                    if reqn == n:
+                        return 1
+
+        return 0
+                
+    def inPrcoRange(self, prcotype, reqtuple):
+        """returns true if the package has a the prco that satisfies 
+           the reqtuple range, assume false.
+           Takes: prcotype, requested prco tuple"""
+        # we only ever get here if we have a versioned prco
+        # nameonly shouldn't ever raise it
+        (reqn, reqf, (reqe, reqv, reqr)) = reqtuple
+        # find the named entry in pkgobj, do the comparsion
+        for (n, f, (e, v, r)) in self.returnPrco(prcotype):
+            if reqn == n:
+                # found it
+                if f != 'EQ':
+                    # isn't this odd, it's not 'EQ' - it really should be
+                    # use the pkgobj's evr for the comparison
+                    (e, v, r) = self.returnEVR()
+                # and you thought we were done having fun
+                # if the requested release is left out then we have
+                # to remove release from the package prco to make sure the match
+                # is a success - ie: if the request is EQ foo 1:3.0.0 and we have 
+                # foo 1:3.0.0-15 then we have to drop the 15 so we can match
+                if reqr is None:
+                    r = None
+                if reqe is None:
+                    e = None
+                if reqv is None: # just for the record if ver is None then we're going to segfault
+                    v = None
+                rc = mdUtils.compareEVR((e, v, r), (reqe, reqv, reqr))
+                
+                if rc >= 1:
+                    if reqf in ['GT', 'GE', 4, 12]:
+                        return 1
+                if rc == 0:
+                    if reqf in ['GE', 'LE', 'EQ', 8, 10, 12]:
+                        return 1
+                if rc <= -1:
+                    if reqf in ['LT', 'LE', 2, 10]:
+                        return 1
+        return 0
+        
+    def returnChangelog(self):
+        """return changelog entries"""
+        return self.changelog
+        
+    def returnFileEntries(self, ftype='file'):
+        """return list of files based on type"""
+        if self.files.has_key(ftype):
+            return self.files[ftype]
+        else:
+            return []
+            
+    def returnFileTypes(self):
+        """return list of types of files in the package"""
+        return self.files.keys()
+    
+
+
+class YumAvailablePackage(PackageObject, RpmBase):
+    """derived class for the  packageobject and RpmBase packageobject yum
        uses this for dealing with packages in a repository"""
 
     def __init__(self, repoid, pkgdict = None):
-        repomd.packageObject.PackageObject.__init__(self)
-        repomd.packageObject.RpmBase.__init__(self)
+        PackageObject.__init__(self)
+        RpmBase.__init__(self)
         
         self.simple['repoid'] = repoid
         self.repoid = repoid
@@ -446,10 +603,3 @@
     def localPkg(self):
         return self.localpath
     
-        
-
-
-            
-        
-    
-    

Index: repos.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/repos.py,v
retrieving revision 1.93
retrieving revision 1.94
diff -u -r1.93 -r1.94
--- repos.py	24 May 2006 21:42:31 -0000	1.93
+++ repos.py	28 May 2006 05:32:49 -0000	1.94
@@ -26,10 +26,7 @@
 from urlgrabber.grabber import URLGrabber
 import urlgrabber.mirror
 from urlgrabber.grabber import URLGrabError
-from repomd import repoMDObject
-from repomd import mdErrors
-from repomd import packageSack
-from repomd.packageSack import MetaSack
+from packageSack import MetaSack
 from packages import YumAvailablePackage
 
 _is_fnmatch_pattern = re.compile(r"[*?[]").search

Index: sqlitesack.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/sqlitesack.py,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- sqlitesack.py	25 May 2006 22:06:19 -0000	1.34
+++ sqlitesack.py	28 May 2006 05:32:49 -0000	1.35
@@ -26,7 +26,8 @@
 import repos
 import yumRepo
 from packages import YumAvailablePackage
-from repomd import mdUtils, mdErrors
+import Errors
+import misc
 
 # Simple subclass of YumAvailablePackage that can load 'simple headers' from
 # the database when they are requested
@@ -443,8 +444,8 @@
         
         # if we've got zilch then raise
         if not allpkg:
-            raise mdErrors.PackageSackError, 'No Package Matching %s.%s' % naTup
-        return mdUtils.newestInList(allpkg)
+            raise Errors.PackageSackError, 'No Package Matching %s.%s' % naTup
+        return misc.newestInList(allpkg)
 
     def returnNewestByName(self, name=None):
         # If name is set do it from the database otherwise use our parent's
@@ -464,8 +465,8 @@
         
         # if we've got zilch then raise
         if not allpkg:
-            raise mdErrors.PackageSackError, 'No Package Matching %s' % name
-        return mdUtils.newestInList(allpkg)
+            raise Errors.PackageSackError, 'No Package Matching %s' % name
+        return misc.newestInList(allpkg)
 
     def returnPackages(self, repoid=None):
         """Returns a list of packages, only containing nevra information """

Index: yumRepo.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/yumRepo.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- yumRepo.py	25 May 2006 14:33:34 -0000	1.7
+++ yumRepo.py	28 May 2006 05:32:49 -0000	1.8
@@ -8,9 +8,8 @@
 from urlgrabber.grabber import URLGrabber
 import urlgrabber.mirror
 from urlgrabber.grabber import URLGrabError
-from repomd import repoMDObject
-from repomd import mdErrors
-from repomd import packageSack
+import repoMDObject
+import packageSack
 from repos import Repository
 from packages import YumAvailablePackage
 import parser
@@ -566,7 +565,7 @@
 
         try:
             self.repoXML = repoMDObject.RepoMD(self.id, result)
-        except mdErrors.RepoMDError, e:
+        except Errors.RepoMDError, e:
             raise Errors.RepoError, 'Error importing repomd.xml from %s: %s' % (self, e)
 
     def _checkRepoXML(self, fo):
@@ -577,7 +576,7 @@
 
         try:
             foo = repoMDObject.RepoMD(self.id, filepath)
-        except mdErrors.RepoMDError, e:
+        except Errors.RepoMDError, e:
             raise URLGrabError(-1, 'Error importing repomd.xml for %s: %s' % (self, e))
 
 




More information about the Yum-cvs-commits mailing list