Merge rev 119 from genscripts repository which contains the first cut at making equer...
authorfuzzyray <fuzzyray@gentoo.org>
Wed, 9 Dec 2009 22:02:08 +0000 (22:02 -0000)
committerfuzzyray <fuzzyray@gentoo.org>
Wed, 9 Dec 2009 22:02:08 +0000 (22:02 -0000)
svn path=/trunk/gentoolkit/; revision=711

MANIFEST.in
pym/gentoolkit/atom.py
pym/gentoolkit/dependencies.py
pym/gentoolkit/equery/meta.py
pym/gentoolkit/metadata.py
pym/gentoolkit/package.py
pym/gentoolkit/test/test_syntax.py

index 35297ebb4155d903658eea438bba5138381a38b8..8f26beaf72e0182f7ea3748e113c4a82394f47f2 100644 (file)
@@ -2,6 +2,7 @@ include AUTHORS
 include ChangeLog
 include COPYING
 include CREDITS
+include DEVELOPING
 include NEWS
 include README
 include TODO
index ff150c00ec8551081c7fbf57432f316ae46b0fa3..749b58517f30f540903f2950aa67fab5fc5e7686 100644 (file)
@@ -86,7 +86,8 @@ class Atom(portage.dep.Atom, CPV):
                        ">=dev-lang/python-2.4" and "dev-lang/python" but not
                        "<dev-lang/python-2.3"
 
-               @type other: Any "Intersectable" object
+               @type other: L{gentoolkit.atom.Atom} or
+                       L{gentoolkit.versionmatch.VersionMatch}
                @param other: other package to compare
                @see: L{pkgcore.ebuild.atom}
                """
index 632ca1e8dae6b0419bb3b610b65492e84574a8c0..4321e66ff9772584636321be1a265073e7ad58c6 100644 (file)
@@ -127,11 +127,11 @@ class Dependencies(CPV):
                Optionally gather indirect dependencies.
 
                @type max_depth: int
-               @param max_depth: Maximum depth to recurse if.
+               @keyword max_depth: Maximum depth to recurse if.
                        <1 means no maximum depth
                        >0 means recurse only this depth;
                @type printer_fn: callable
-               @param printer_fn: If None, no effect. If set, it will be applied to
+               @keyword printer_fn: If None, no effect. If set, it will be applied to
                        each result.
                @rtype: list
                @return: [(depth, pkg), ...]
@@ -210,19 +210,18 @@ class Dependencies(CPV):
                        44
 
                @type pkgset: iterable
-               @param pkgset: sorted pkg cpv strings or any 'intersectable' objects to
-                       use for calculate our revdep graph.
+               @keyword pkgset: sorted pkg cpv strings or anything sublassing
+                       L{gentoolkit.cpv.CPV} to use for calculate our revdep graph.
                @type max_depth: int
-               @param max_depth: Maximum depth to recurse if only_direct=False.
+               @keyword max_depth: Maximum depth to recurse if only_direct=False.
                        -1 means no maximum depth;
                         0 is the same as only_direct=True;
                        >0 means recurse only this many times;
                @type only_direct: bool
-               @param only_direct: to recurse or not to recurse
+               @keyword only_direct: to recurse or not to recurse
                @type printer_fn: callable
-               @param printer_fn: If None, no effect. If set, it will be applied to
-                       each L{gentoolkit.atom.Atom} object as it is added to
-                       the results.
+               @keyword printer_fn: If None, no effect. If set, it will be applied to
+                       each L{gentoolkit.atom.Atom} object as it is added to the results.
                @rtype: list
                @return: L{gentoolkit.dependencies.Dependencies} objects
                """
index bcbbed2997a5e5636468c99d516b7bfda9de5f7a..480441cfa39137abf864097b9002a318b50f57d6 100644 (file)
@@ -75,6 +75,36 @@ def print_help(with_description=True, with_usage=True):
        ))
 
 
+def filter_keywords(matches):
+       """Filter non-unique keywords per slot.
+
+       This view apparently makes version bumps easier for package maintainers.
+
+       @type matches: array
+       @param matches: set of L{gentoolkit.package.Package} instances whose
+               'key' are all the same.
+       @rtype: dict
+       @return: a dict with L{gentoolkit.package.Package} instance keys and
+               'array of keywords not found in a higher version of pkg within the
+               same slot' values.
+       """
+
+       result = {}
+       slot_map = {}
+       # Start from the newest
+       rev_matches = reversed(matches)
+       for pkg in rev_matches:
+               keywords_str, slot = pkg.get_env_vars(('KEYWORDS', 'SLOT'))
+               keywords = keywords_str.split()
+               result[pkg] = [x for x in keywords if x not in slot_map.get(slot, [])]
+               try:
+                       slot_map[slot].update(keywords)
+               except KeyError:
+                       slot_map[slot] = set(keywords)
+
+       return result
+
+
 def format_herds(herds):
        """Format herd information for display."""
 
@@ -164,27 +194,41 @@ def format_useflags(useflags):
        return result
 
 
-def format_keywords(match):
-       """Format keywords information for display."""
+def format_keywords(keywords):
+       """Sort and colorize keywords for display."""
+
+       result = []
 
-       kwsplit = match.get_env_var('KEYWORDS').split()
-       ver = match.cpv.fullversion
-       keywords = ''
-       for kw in kwsplit:
-               if kw.startswith('~'):
-                       keywords += " %s" % pp.useflag(kw, enabled=True)
+       for kw in sorted(keywords):
+               if kw.startswith(('~', '-')):
+                       # keyword (~) or arch (-) masked, color red
+                       kw = pp.useflag(kw, enabled=True)
                else:
-                       keywords += " %s" % pp.useflag(kw, enabled=False)
+                       # unmasked, color blue
+                       kw = pp.useflag(kw, enabled=False)
+               result.append(kw)
+
+       return ' '.join(result)
+
+
+def format_keywords_line(pkg, fmtd_keywords):
+       """Format the entire keywords line for display."""
+
+       slot = pkg.get_env_var('SLOT')
+       ver = pkg.cpv.fullversion
+       verstr_len = len(ver) + 1 + len(slot)  # +1 for ':'
 
        if CONFIG['verbose']:
                result = format_line(
-                       keywords, "%s: " % pp.cpv(ver), " " * (len(ver) + 2)
-                       )
+                       fmtd_keywords, "%s:%s: " % (pp.cpv(ver), pp.slot(slot)),
+                       " " * (verstr_len + 2)
+               )
        else:
-               result = "%s:%s" % (ver, keywords)
+               result = "%s:%s: %s" % (ver, slot, fmtd_keywords)
 
        return result
 
+
 # R0912: *Too many branches (%s/%s)*
 # pylint: disable-msg=R0912
 def call_format_functions(matches):
@@ -234,13 +278,20 @@ def call_format_functions(matches):
                print_sequence(upstream)
 
        if QUERY_OPTS["keywords"] or not got_opts:
+               # Get {<Package 'dev-libs/glib-2.20.5'>: [u'ia64', u'm68k', ...], ...}
+               keyword_map = filter_keywords(matches)
+
                for match in matches:
-                       kwds = format_keywords(match)
+                       fmtd_keywords = format_keywords(keyword_map[match])
+                       keywords_line = format_keywords_line(match, fmtd_keywords)
                        if QUERY_OPTS["keywords"]:
-                               print kwds
+                               print keywords_line
                        else:
-                               indent = " " * (15 + len(match.cpv.fullversion))
-                               print format_line(kwds, "Keywords:    ", indent)
+                               # FIXME: duplicate code
+                               slot = match.get_env_var('SLOT')
+                               verstr_len = len(match.cpv.fullversion) + len(slot)
+                               indent = " " * (16 + verstr_len)
+                               print format_line(keywords_line, "Keywords:    ", indent)
 
        if QUERY_OPTS["description"]:
                desc = ref_pkg.metadata.get_descriptions()
@@ -357,8 +408,9 @@ def get_reference_pkg(matches):
        """Find a package in the Portage tree to reference."""
 
        pkg = None
-       while list(reversed(matches)):
-               pkg = matches[-1]
+       rev_matches = list(reversed(matches))
+       while rev_matches:
+               pkg = rev_matches.pop()
                if not pkg.is_overlay():
                        break
 
index 9c65fd951eda94835c81791597b1c6c347bbad4d..545d4f36880d38cbc1acbaba8032bdd32caa1b0b 100644 (file)
@@ -176,8 +176,8 @@ class MetaData(object):
                """Parse a valid metadata.xml file.
 
                @type metadata_path: str
-               @ivar metadata_path: path to a valid metadata.xml file
-               @raise IOError: if C{matadata_path} can not be read
+               @param metadata_path: path to a valid metadata.xml file
+               @raise IOError: if C{metadata_path} can not be read
                """
 
                self.metadata_path = metadata_path
@@ -247,9 +247,8 @@ class MetaData(object):
                if self._descriptions is not None:
                        return self._descriptions
 
-               self._descriptions = [
-                       e.text for e in self._xml_tree.findall("longdescription")
-               ]
+               long_descriptions = self._xml_tree.findall("longdescription")
+               self._descriptions = [e.text for e in long_descriptions]
                return self._descriptions
 
        def get_maintainers(self):
index e3482581150f1611d37cd4cb8fc799541ad08645..c4e07abd92085c44e68102a934caf3488c51a583 100644 (file)
@@ -194,18 +194,6 @@ class Package(CPV):
 
                return result
 
-       def get_provide(self):
-               """Return a list of provides, if any"""
-
-               if self.is_installed():
-                       result = VARDB.get_provide(str(self.cpv))
-               else:
-                       try:
-                               result = [self.get_env_var('PROVIDE')]
-                       except KeyError:
-                               result = []
-               return result
-
        def get_ebuild_path(self, in_vartree=False):
                """Returns the complete path to the .ebuild file.
 
@@ -238,19 +226,25 @@ class Package(CPV):
 
                return self.get_package_path().split(os.sep)[-3]
 
-       def get_env_var(self, var, tree=None):
-               """Returns one of the predefined env vars DEPEND, SRC_URI, etc."""
+       def get_env_vars(self, envvars, tree=None):
+               """Returns one or more of the predefined environment variables.
+
+               @type envvars: array
+               @param envvars: one or more of (DEPEND, SRC_URI, etc.)"""
 
                if tree is None:
                        tree = self._get_trees()[0]
                try:
-                       result = tree.aux_get(str(self.cpv), [var])
-                       if len(result) != 1:
-                               raise errors.GentoolkitFatalError
+                       result = tree.aux_get(str(self.cpv), envvars)
                except (KeyError, errors.GentoolkitFatalError):
                        err = "aux_get returned unexpected results"
                        raise errors.GentoolkitFatalError(err)
-               return result[0]
+               return result
+
+       def get_env_var(self, *args, **kwargs):
+               """Returns one of the predefined environment variables."""
+
+               return self.get_env_vars(args, **kwargs)[0]
 
        def get_use_flags(self):
                """Returns the USE flags active at time of installation."""
@@ -286,7 +280,7 @@ class Package(CPV):
        def is_installed(self):
                """Returns True if this package is installed (merged)"""
 
-               return VARDB.cpv_exists(str(self.cpv))
+               return self.dblink.exists()
 
        def is_overlay(self):
                """Returns True if the package is in an overlay."""
index 5b00fc56916fe84f4724ffcffcce504d2158d751..bb7dcb4167656dcae4e072e4e5e6f2286169f94d 100644 (file)
@@ -3,8 +3,10 @@ import os.path as osp
 import unittest
 import py_compile
 
+"""Does a basic syntax check by compiling all modules. From Portage."""
+
 pym_dirs = os.walk(osp.dirname(osp.dirname(osp.dirname(__file__))))
-blacklist_dirs = frozenset(('.svn', 'tests'))
+blacklist_dirs = frozenset(('.svn', 'test'))
 
 class TestForSyntaxErrors(unittest.TestCase):