From b264a890cdbee460420f2511c2853d31c116ff7e Mon Sep 17 00:00:00 2001 From: fuzzyray Date: Wed, 9 Dec 2009 22:02:08 +0000 Subject: [PATCH] Merge rev 119 from genscripts repository which contains the first cut at making equery meta output look like epkginfo svn path=/trunk/gentoolkit/; revision=711 --- MANIFEST.in | 1 + pym/gentoolkit/atom.py | 3 +- pym/gentoolkit/dependencies.py | 17 +++--- pym/gentoolkit/equery/meta.py | 88 ++++++++++++++++++++++++------ pym/gentoolkit/metadata.py | 9 ++- pym/gentoolkit/package.py | 32 +++++------ pym/gentoolkit/test/test_syntax.py | 4 +- 7 files changed, 101 insertions(+), 53 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 35297eb..8f26bea 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,6 +2,7 @@ include AUTHORS include ChangeLog include COPYING include CREDITS +include DEVELOPING include NEWS include README include TODO diff --git a/pym/gentoolkit/atom.py b/pym/gentoolkit/atom.py index ff150c0..749b585 100644 --- a/pym/gentoolkit/atom.py +++ b/pym/gentoolkit/atom.py @@ -86,7 +86,8 @@ class Atom(portage.dep.Atom, CPV): ">=dev-lang/python-2.4" and "dev-lang/python" but not "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 """ diff --git a/pym/gentoolkit/equery/meta.py b/pym/gentoolkit/equery/meta.py index bcbbed2..480441c 100644 --- a/pym/gentoolkit/equery/meta.py +++ b/pym/gentoolkit/equery/meta.py @@ -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 {: [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 diff --git a/pym/gentoolkit/metadata.py b/pym/gentoolkit/metadata.py index 9c65fd9..545d4f3 100644 --- a/pym/gentoolkit/metadata.py +++ b/pym/gentoolkit/metadata.py @@ -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): diff --git a/pym/gentoolkit/package.py b/pym/gentoolkit/package.py index e348258..c4e07ab 100644 --- a/pym/gentoolkit/package.py +++ b/pym/gentoolkit/package.py @@ -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.""" diff --git a/pym/gentoolkit/test/test_syntax.py b/pym/gentoolkit/test/test_syntax.py index 5b00fc5..bb7dcb4 100644 --- a/pym/gentoolkit/test/test_syntax.py +++ b/pym/gentoolkit/test/test_syntax.py @@ -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): -- 2.26.2