# as soon as possible.
if "--fetchonly" not in self.myopts and \
"--fetch-all-uri" not in self.myopts and \
- len(mylist) > 1 and \
"strict" in self.settings.features:
shown_verifying_msg = False
quiet_settings = {}
@rtype: List
@return: A list of licenses that have not been accepted.
"""
+ if "*" in self._accept_license:
+ return []
+ acceptable_licenses = self._accept_license
cpdict = self._plicensedict.get(dep_getkey(cpv), None)
- acceptable_licenses = self._accept_license.copy()
if cpdict:
+ acceptable_licenses = self._accept_license.copy()
for atom in match_to_list(cpv, cpdict.keys()):
acceptable_licenses.update(cpdict[atom])
- if "*" in acceptable_licenses:
- return []
license_struct = portage.dep.paren_reduce(licenses)
license_struct = portage.dep.use_reduce(
license_struct, uselist=uselist)
# forget it and are using ebuild
if not os.path.exists(
os.path.join(mysettings["PORTAGE_BUILDDIR"], ".installed")):
- writemsg("!!! mydo=qmerge, but install phase hasn't been ran\n",
+ writemsg("!!! mydo=qmerge, but the install phase has not been run\n",
noiselevel=-1)
return 1
# qmerge is a special phase that implies noclean.
# Distributed under the terms of the GNU General Public License v2
# $Id$
-import os
from UserDict import UserDict
+from portage.env.loaders import KeyListFileLoader, KeyValuePairFileLoader, AtomFileLoader
class PackageKeywords(UserDict):
"""
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()
"""
Inherits from PackageKeywords; implements a file-based backend. Doesn't handle recursion yet.
"""
- def __init__( self, filename ):
- self.fname = filename
-
- def load(self, recursive):
- """
- Package.keywords files have comments that begin with #.
- The entries are of the form:
- >>> cpv [-~]keyword1 [-~]keyword2 keyword3
- >>> Exceptions include -*, ~*, and ** for keywords.
- """
-
- if os.path.exists( self.fname ):
- f = open(self.fname, 'rb')
- for line in f:
- if line.startswith('#'):
- continue
- split = line.split()
- if len(split):
- # Surprisingly this works for iterables of length 1
- # fex ['sys-apps/portage','x86','amd64'] becomes {'sys-apps/portage':['x86','amd64']}
- key, items = split[0],split[1:]
- # if they specify the same cpv twice; stack the values (append) instead of overwriting.
- if key in self.data:
- self.data[key].append(items)
- else:
- self.data[key] = items
+ 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
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()
"""
Inherits from PackageUse; implements a file-based backend. Doesn't handle recursion yet.
"""
- def __init__(self, filename):
- self.fname = filename
-
- def load(self, recursive):
- """
- Package.keywords files have comments that begin with #.
- The entries are of the form:
- >>> atom useflag1 useflag2 useflag3..
- useflags may optionally be negative with a minus sign (-)
- >>> atom useflag1 -useflag2 useflag3
- """
-
- if os.path.exists( self.fname ):
- f = open(self.fname, 'rb')
- for line in f:
- if line.startswith('#'):
- continue
- split = line.split()
- if len(split):
- # Surprisingly this works for iterables of length 1
- # fex ['sys-apps/portage','foo','bar'] becomes {'sys-apps/portage':['foo','bar']}
- key, items = split[0],split[1:]
- # if they specify the same cpv twice; stack the values (append) instead of overwriting.
- if key in self.data:
- self.data[key].append(items)
- else:
- self.data[key] = items
+ 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 = {}
+ def __init__(self, loader):
+ self._loader = loader
+
+ def load(self):
+ self.data, self.errors = self._loader.load()
+
def iteritems(self):
return self.data.iteritems()
to revert a previous mask; this only works when masking files are stacked
"""
+ default_loader = AtomFileLoader
+
def __init__(self, filename):
- self.fname = filename
-
- def load(self, recursive):
- """
- Package.keywords files have comments that begin with #.
- The entries are of the form:
- >>> atom useflag1 useflag2 useflag3..
- useflags may optionally be negative with a minus sign (-)
- >>> atom useflag1 -useflag2 useflag3
- """
-
- if os.path.exists( self.fname ):
- f = open(self.fname, 'rb')
- for line in f:
- if line.startswith('#'):
- continue
- split = line.split()
- if len(split):
- atom = split[0] # This is an extra assignment, but I think it makes the code more explicit in what goes into the dict
- self.data[atom] = None # we only care about keys in the dict, basically abusing it as a list
+ 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()
+
+class PortageModulesFile(PortageModules):
+ """
+ File Class for /etc/portage/modules
+ """
+
+ default_loader = KeyValuePairFileLoader
+
+ def __init__(self, filename):
+ PortageModules.__init__(self, self.default_loader(filename))
--- /dev/null
+# config.py -- Portage Config
+# Copyright 2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+import os
+
+def RecursiveFileLoader(filename):
+ """
+ If filename is of type file, return [filename]
+ else if filename is of type directory, return an array
+ full of files in that directory to process.
+
+ Ignore files beginning with . or ending in ~.
+ Prune CVS directories.
+
+ @param filename: name of a file/directory to traverse
+ @rtype: list
+ @returns: List of files to process
+ """
+
+ if os.path.isdir(filename):
+ for root, dirs, files in os.walk(self.fname):
+ if 'CVS' in dirs:
+ dirs.remove('CVS')
+ files = filter(files,startswith('.'))
+ files = filter(files,endswith('~'))
+ for file in files:
+ yield file
+ else:
+ yield filename
+
+class DataLoader(object):
+
+ def load(self):
+ """
+ Function to do the actual work of a Loader
+ """
+ pass
+
+class AtomFileLoader(DataLoader):
+ """
+ Class to load data from a file full of atoms one per line
+
+ >>> atom1
+ >>> atom2
+ >>> atom3
+
+ becomes ['atom1', 'atom2', 'atom3']
+ """
+
+ _recursive = False
+
+ def __init__(self, filename):
+ DataLoader.__init__(self)
+ self.fname = filename
+
+ 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
+ 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))
+ key = split[0]
+ data[key] = None
+ return (data,errors)
+
+class KeyListFileLoader(DataLoader):
+ """
+ Class to load data from a file full of key [list] tuples
+
+ >>>>key foo1 foo2 foo3
+ becomes
+ {'key':['foo1','foo2','foo3']}
+ """
+
+ _recursive = False
+
+ def __init__(self, filename):
+ DataLoader.__init__(self)
+ self.fname = filename
+
+ 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
+ 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))
+ key = split[0]
+ value = split[1:]
+ if key in data:
+ data[key].append(value)
+ else:
+ data[key] = value
+ return (data,errors)
+
+class KeyValuePairFileLoader(DataLoader):
+ """
+ Class to load data from a file full of key=value pairs
+
+ >>>>key=value
+ >>>>foo=bar
+ becomes:
+ {'key':'value',
+ 'foo':'bar'}
+ """
+
+ _recursive = False
+
+ def __init__(self, filename):
+ DataLoader.__init__(self)
+ self.fname = filename
+
+ def load(self):
+ """
+ Return the {source: {key: value}} pairs from a file
+ Return the {source: [list of errors] from a load
+
+ @param recursive: If set and self.fname is a directory;
+ load all files in self.fname
+ @type: Boolean
+ @rtype: tuple
+ @returns:
+ Returns (data,errors), both may be empty dicts or populated.
+ """
+
+ 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
+ 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))
+ key = split[0]
+ value = split[1:]
+ if key in data:
+ data[key].append(value)
+ else:
+ data[key] = value
+ return (data,errors)
from setup_env import *
class DoBin(BinTestCase):
- def testBasic(self):
+ def testDoBin(self):
dobin("does-not-exist", 1)
xexists_in_D("does-not-exist")
xexists_in_D("/bin/does-not-exist")
# test_dodir.py -- Portage Unit Testing Functionality
# Copyright 2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Id: test_dep_getcpv.py 6182 2007-03-06 07:35:22Z antarus $
+# $Id: test_dodir.py 6182 2007-03-06 07:35:22Z antarus $
from setup_env import *
class DoDir(BinTestCase):
- def testBasic(self):
+ def testDoDir(self):
dodir("usr /usr")
exists_in_D("/usr")
dodir("/var/lib/moocow")
from portage.tests import TestCase
from portage.env.config import PackageKeywordsFile
+from tempfile import mkstemp
+import os
class PackageKeywordsFileTestCase(TestCase):
- fname = 'package.keywords'
- cpv = 'sys-apps/portage'
+ cpv = ['sys-apps/portage']
keywords = ['~x86', 'amd64', '-mips']
- def testPackageKeywordsLoad(self):
+ def testPackageKeywordsFile(self):
"""
A simple test to ensure the load works properly
"""
self.BuildFile()
try:
f = PackageKeywordsFile(self.fname)
- f.load(recursive=False)
+ f.load()
+ i = 0
for cpv, keyword in f.iteritems():
- self.assertEqual( cpv, self.cpv )
+ self.assertEqual( cpv, self.cpv[i] )
[k for k in keyword if self.assertTrue(k in self.keywords)]
+ i = i + 1
finally:
self.NukeFile()
def BuildFile(self):
- f = open(self.fname, 'wb')
- f.write('%s %s\n' % (self.cpv, ' '.join(self.keywords)))
+ fd, self.fname = mkstemp()
+ f = os.fdopen(fd, 'w')
+ for c in self.cpv:
+ f.write("%s %s\n" % (c,' '.join(self.keywords)))
f.close()
def NukeFile(self):
from portage.env.config import PackageMaskFile
from portage.tests import TestCase
+from tempfile import mkstemp
class PackageMaskFileTestCase(TestCase):
atoms = ['sys-apps/portage','dev-util/diffball','not@va1id@t0m']
- def testPackageMaskLoad(self):
+ def testPackageMaskFile(self):
self.BuildFile()
try:
f = PackageMaskFile(self.fname)
- f.load(recursive=False)
- [atom for atom in f.iterkeys() if self.assertTrue(atom in self.atoms)]
+ f.load()
+ [atom for atom in f.keys() if self.assertTrue(atom in self.atoms)]
finally:
self.NukeFile()
def BuildFile(self):
- from tempfile import mkstemp
fd, self.fname = mkstemp()
f = os.fdopen(fd, 'w')
f.write("\n".join(self.atoms))
# Distributed under the terms of the GNU General Public License v2
# $Id: test_PackageUseFile.py 6182 2007-03-06 07:35:22Z antarus $
+import os
from portage.tests import TestCase
from portage.env.config import PackageUseFile
+from tempfile import mkstemp
+
class PackageUseFileTestCase(TestCase):
- fname = 'package.use'
cpv = 'sys-apps/portage'
useflags = ['cdrom', 'far', 'boo', 'flag', 'blat']
- def testPackageUseLoad(self):
+ def testPackageUseFile(self):
"""
A simple test to ensure the load works properly
"""
self.BuildFile()
try:
f = PackageUseFile(self.fname)
- f.load(recursive=False)
+ f.load()
for cpv, use in f.iteritems():
self.assertEqual( cpv, self.cpv )
[flag for flag in use if self.assertTrue(flag in self.useflags)]
self.NukeFile()
def BuildFile(self):
- f = open(self.fname, 'wb')
+ fd, self.fname = mkstemp()
+ f = os.fdopen(fd, 'wb')
f.write("%s %s" % (self.cpv, ' '.join(self.useflags)))
+ f.close()
def NukeFile(self):
import os
--- /dev/null
+import os
+
+from portage.tests import TestCase
+from portage.env.config import PortageModulesFile
+from tempfile import mkstemp
+from itertools import izip
+
+class PortageModulesFileTestCase(TestCase):
+
+ keys = ['foo.bar','baz','bob','extra_key']
+ modules = ['spanky','zmedico','antarus','ricer']
+
+ def setUp(self):
+ self.items = {}
+ for k,v in izip(self.keys, self.modules):
+ self.items[k] = v
+
+ def testPortageModulesFile(self):
+ self.BuildFile()
+ f = PortageModulesFile(self.fname)
+ for k in f.keys():
+ self.assertEqual( f[k], self.items[k] )
+ self.NukeFile()
+
+ def BuildFile(self):
+ fd, self.fname = mkstemp()
+ f = os.fdopen(fd, 'wb')
+ for k,v in self.items.iteritems():
+ f.write('%s=%s\n' % (k,v))
+ f.close()
+
+ def NukeFile(self):
+ import os
+ os.unlink(self.fname)