@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
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 + \
# $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
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
"""
default_loader = KeyValuePairFileLoader
def __init__(self, filename):
- PortageModules.__init__(self, self.default_loader(filename))
+ super(PortageModulesFile,self).__init__(self.default_loader(filename))
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]
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
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):
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:
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: