Merged from trunk 6327:6332
authorFabian Groffen <grobian@gentoo.org>
Thu, 5 Apr 2007 15:38:52 +0000 (15:38 -0000)
committerFabian Groffen <grobian@gentoo.org>
Thu, 5 Apr 2007 15:38:52 +0000 (15:38 -0000)
   +------------------------------------------------------------------------+
   | 6328      | After talking to marienz, decide that 1 class is better    |
   | WarnerBro | than 4, also realize that UserDict has most of the dict    |
   |           | methods exposed, so drop them. Also add a LoaderError      |
   |           | Exception. Still to do? add a validation callable into the |
   |           | loader to validate data.                                   |
   |-----------+------------------------------------------------------------|
   | 6329      | drop line_count in favor of izip and count(), itertools    |
   | WarnerBro | FOR THE WIN baby.                                          |
   |-----------+------------------------------------------------------------|
   | 6330      | I consulted the python oracle and it told me enumerate was |
   | WarnerBro | better, so go team enumerate                               |
   |-----------+------------------------------------------------------------|
   | 6332      | For bug #173184, handle the CommandNotFound that is        |
   | zmedico   | produced during uninstallation of prelink.                 |
   +------------------------------------------------------------------------+

svn path=/main/branches/prefix/; revision=6334

pym/portage/checksum.py
pym/portage/env/config.py
pym/portage/env/loaders.py

index 2ae873ca5da6ea5229da31d2e57eaf9ebd7f7ac7..de4be208c7d410ae283b118fc34ac0382f04745a 100644 (file)
@@ -181,6 +181,7 @@ def perform_checksum(filename, hashname="MD5", calc_prelink=0):
        @rtype: Tuple
        @return: The hash and size of the data
        """
+       global prelink_capable
        myfilename      = filename[:]
        prelink_tmpfile = os.path.join("/", PRIVATE_PATH, "prelink-checksum.tmp." + str(os.getpid()))
        mylock          = None
@@ -189,10 +190,14 @@ def perform_checksum(filename, hashname="MD5", calc_prelink=0):
                        mylock = portage.locks.lockfile(prelink_tmpfile, wantnewlockfile=1)
                        # Create non-prelinked temporary file to checksum.
                        # Files rejected by prelink are summed in place.
-                       retval = portage.process.spawn([PRELINK_BINARY, "--undo", "-o",
-                               prelink_tmpfile, filename], fd_pipes={})
-                       if retval == os.EX_OK:
-                               myfilename = prelink_tmpfile
+                       try:
+                               retval = portage.process.spawn([PRELINK_BINARY, "--undo", "-o",
+                                       prelink_tmpfile, filename], fd_pipes={})
+                               if retval == os.EX_OK:
+                                       myfilename = prelink_tmpfile
+                       except portage.exception.CommandNotFound:
+                               # This happens during uninstallation of prelink.
+                               prelink_capable = False
                try:
                        if hashname not in hashfunc_map:
                                raise portage.exception.DigestException(hashname + \
index 3bac9a3a505a9e7d76dcc3b1becc64218454e6d4..62d3d8177b41b2a042fd46be70df60f25c05ef0c 100644 (file)
 # $Id$
 
 from UserDict import UserDict
-from portage.env.loaders import KeyListFileLoader, KeyValuePairFileLoader, AtomFileLoader
+from portage.env.loaders import KeyListFileLoader, KeyValuePairFileLoader, ItemFileLoader
 
-class PackageKeywords(UserDict):
+class UserConfigKlass(UserDict,object):
        """
-       A base class stub for things to inherit from; some people may want a database based package.keywords or something
-       
-       Internally dict has pairs of the form
-       {'cpv':['keyword1','keyword2','keyword3'...]
+       A base class stub for things to inherit from.
+       Users may want a non-file backend.
        """
        
        data = {}
        
        def __init__(self, loader):
+               """
+               @param loader: A class that has a load() that returns two dicts
+                       the first being a data dict, the second being a dict of errors.
+               """
                self._loader = loader
 
        def load(self):
+               """
+               Load the data from the loader.
+
+               @throws LoaderError:
+               """
+
                self.data, self.errors = self._loader.load()
 
-       def iteritems(self):
-               return self.data.iteritems()
-       
-       def keys(self):
-               return self.data.keys()
-       
-       def __contains__(self, other):
-               return other in self.data
-       
-       def __hash__( self ):
-               return self.data.__hash__()
-       
-class PackageKeywordsFile(PackageKeywords):
+class PackageKeywordsFile(UserConfigKlass):
        """
-       Inherits from PackageKeywords; implements a file-based backend.  Doesn't handle recursion yet.
+       Inherits from UserConfigKlass; implements a file-based backend.
        """
 
        default_loader = KeyListFileLoader
 
        def __init__(self, filename):
-               PackageKeywords.__init__(self, self.default_loader(filename))
-       
-class PackageUse(UserDict):
-       """
-       A base class stub for things to inherit from; some people may want a database based package.keywords or something
-       
-       Internally dict has pairs of the form
-       {'cpv':['flag1','flag22','flag3'...]
-       """
-       
-       data = {}
+               super(PackageKeywordsFile,self).__init__(self.default_loader(filename))
        
-       def __init__(self, loader):
-               self._loader = loader
-
-       def load( self):
-               self.data, self.errors = self._loader.load()
-
-       def iteritems(self):
-               return self.data.iteritems()
-       
-       def __hash__(self):
-               return hash(self.data)
-       
-       def __contains__(self, other):
-               return other in self.data
-       
-       def keys(self):
-               return self.data.keys()
-
-class PackageUseFile(PackageUse):
+class PackageUseFile(UserConfigKlass):
        """
        Inherits from PackageUse; implements a file-based backend.  Doesn't handle recursion yet.
        """
 
        default_loader = KeyListFileLoader
        def __init__(self, filename):
-               PackageUse.__init__(self, self.default_loader(filename))
-       
-class PackageMask(UserDict):
-       """
-       A base class for Package.mask functionality
-       """
-       data = {}
+               super(PackageUseFile,self).__init__(self.default_loader(filename))
        
-       def __init__(self, loader):
-               self._loader = loader
-       
-       def load(self):
-               self.data, self.errors = self._loader.load()
-               
-       def iteritems(self):
-               return self.data.iteritems()
-       
-       def __hash__(self):
-               return hash(self.data)
-       
-       def __contains__(self, other):
-               return other in self.data
-       
-       def keys(self):
-               return self.data.keys()
-       
-       def iterkeys(self):
-               return self.data.iterkeys()
-
-class PackageMaskFile(PackageMask):
+class PackageMaskFile(UserConfigKlass):
        """
        A class that implements a file-based package.mask
        
@@ -120,40 +61,12 @@ class PackageMaskFile(PackageMask):
        to revert a previous mask; this only works when masking files are stacked
        """
        
-       default_loader = AtomFileLoader
+       default_loader = ItemFileLoader
 
        def __init__(self, filename):
-               PackageMask.__init__(self, self.default_loader(filename))
-
-class PortageModules(UserDict):
-       """
-       Base Class for user level module over-rides
-       """
-       
-       data = {}
-
-       def __init__(self, loader):
-               self._loader = loader
-
-       def load(self):
-               self.data, self.errors = self._loader.load()
-
-       def iteritems(self):
-               return self.data.iteritems()
-       
-       def __hash__(self):
-               return self.data.__hash__()
-
-       def __contains__(self, key):
-               return key in self.data
-
-       def keys(self):
-               return self.data.keys()
-       
-       def iterkeys(self):
-               return self.data.iterkeys()
+               super(PackageMaskFile,self).__init__(self.default_loader(filename))
 
-class PortageModulesFile(PortageModules):
+class PortageModulesFile(UserConfigKlass):
        """
        File Class for /etc/portage/modules
        """
@@ -161,4 +74,4 @@ class PortageModulesFile(PortageModules):
        default_loader = KeyValuePairFileLoader
        
        def __init__(self, filename):
-               PortageModules.__init__(self, self.default_loader(filename))
+               super(PortageModulesFile,self).__init__(self.default_loader(filename))
index 33a8c3d4f78f33f32d85bd208efee3891430fb84..6bfcce77b45fec1fdbb79c89ceac6eb72d9c9712 100644 (file)
@@ -5,6 +5,22 @@
 
 import os
 
+class LoaderError(Exception):
+       
+       def __init__(self, resource, error_msg):
+               """
+               @param resource: Resource that failed to load (file/sql/etc)
+               @type resource: String
+               @param error_msg: Error from underlying Loader system
+               @type error_msg: String
+               """
+
+               self.resource
+       
+       def __str__(self):
+               return "Failed while loading resource: %s, error was: %s" % (
+                       resource, error_msg)
+
 def RecursiveFileLoader(filename):
        """
        If filename is of type file, return [filename]
@@ -32,21 +48,35 @@ def RecursiveFileLoader(filename):
 
 class DataLoader(object):
 
+       def __init__(self, validator=None):
+               f = validator
+               if f is None:
+                       # if they pass in no validator, just make a fake one
+                       # that always returns true
+                       class AlwaysTrue():
+                               def validate(self, key):
+                                       return True
+                       f = AlwaysTrue()
+               self._validator = f
+
        def load(self):
                """
                Function to do the actual work of a Loader
                """
                pass
 
-class AtomFileLoader(DataLoader):
+class ItemFileLoader(DataLoader):
        """
-       Class to load data from a file full of atoms one per line
+       Class to load data from a file full of items one per line
        
-       >>> atom1
-       >>> atom2
-       >>> atom3
+       >>> item1
+       >>> item2
+       >>> item3
+       >>> item1
        
-       becomes ['atom1', 'atom2', 'atom3']
+       becomes { 'item1':None, 'item2':None, 'item3':None }
+       Note that due to the data store being a dict, duplicates
+       are removed.
        """
        
        _recursive = False
@@ -58,20 +88,23 @@ class AtomFileLoader(DataLoader):
        def load(self):
                data = {}
                errors = {}
-               line_count = 0
                for file in RecursiveFileLoader(self.fname):
                        f = open(file, 'rb')
-                       for line in f:
-                               line_count = line_count + 1
+                       for line_num, line in enumerate(f):
                                if line.startswith('#'):
                                        continue
                                split = line.strip().split()
                                if not len(split):
                                        errors.setdefault(self.fname,[]).append(
                                        "Malformed data at line: %s, data: %s"
-                                       % (line_count, split))
+                                       % (line_num + 1, split))
                                key = split[0]
-                               data[key] = None                        
+                               if not self._validator.validate(key):
+                                       errors.setdefault(self.fname,[]).append(
+                                       "Validation failed at line: %s, data %s"
+                                       % (line_num + 1, split))
+                                       continue
+                               data[key] = None
                return (data,errors)
 
 class KeyListFileLoader(DataLoader):
@@ -92,20 +125,24 @@ class KeyListFileLoader(DataLoader):
        def load(self):
                data = {}
                errors = {}
-               line_count = 0
                for file in RecursiveFileLoader(self.fname):
                        f = open(file, 'rb')
-                       for line in f:
-                               line_count = line_count + 1
+                       for line_num, line in enumerate(f):
                                if line.startswith('#'):
                                        continue
                                split = line.strip().split()
                                if len(split) < 2:
                                        errors.setdefault(self.fname,[]).append(
                                        "Malformed data at line: %s, data: %s"
-                                       % (line_count, split))
+                                       % (line_num + 1, split))
+                                       continue
                                key = split[0]
                                value = split[1:]
+                               if not self._validator.validate(key):
+                                       errors.setdefault(self.fname,[]).append(
+                                       "Validation failed at line: %s, data %s"
+                                       % (line_num + 1, split))
+                                       continue
                                if key in data:
                                        data[key].append(value)
                                else:
@@ -145,20 +182,23 @@ class KeyValuePairFileLoader(DataLoader):
                DataLoader.load(self)
                data = {}
                errors = {}
-               line_count = 0
                for file in RecursiveFileLoader(self.fname):
                        f = open(file, 'rb')
-                       for line in f:
-                               line_count = line_count + 1 # Increment line count
+                       for line_num, line in enumerate(f):
                                if line.startswith('#'):
                                        continue
                                split = line.strip().split('=')
                                if len(split) < 2:
                                        errors.setdefault(self.fname,[]).append(
                                        "Malformed data at line: %s, data %s"
-                                       % (line_count, split))
+                                       % (line_num + 1, split))
                                key = split[0]
                                value = split[1:]
+                               if not self._validator.validate(key):
+                                       errors.setdefault(self.fname,[]).append(
+                                       "Validation failed at line: %s, data %s"
+                                       % (line_num + 1, split))
+                                       continue
                                if key in data:
                                        data[key].append(value)
                                else: