aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pym/gentoolkit/helpers2.py')
-rw-r--r--pym/gentoolkit/helpers2.py292
1 files changed, 152 insertions, 140 deletions
diff --git a/pym/gentoolkit/helpers2.py b/pym/gentoolkit/helpers2.py
index 1a2530a..f9d0c49 100644
--- a/pym/gentoolkit/helpers2.py
+++ b/pym/gentoolkit/helpers2.py
@@ -13,16 +13,19 @@ query matches one or more packages.
This should be merged into helpers when a clean path is found.
"""
+# Move to Imports section after Python 2.6 is stable
+from __future__ import with_statement
+
__all__ = (
'compare_package_strings',
+ 'do_lookup',
'find_best_match',
'find_installed_packages',
'find_packages',
'get_cpvs',
'get_installed_cpvs',
'get_uninstalled_cpvs',
- 'uses_globbing',
- 'do_lookup'
+ 'uses_globbing'
)
__author__ = 'Douglas Anderson'
__docformat__ = 'epytext'
@@ -40,17 +43,10 @@ from portage.util import unique_array
import gentoolkit
import gentoolkit.pprinter as pp
-from gentoolkit import catpkgsplit, Config
+from gentoolkit import Config, PORTDB, VARDB
from gentoolkit import errors
from gentoolkit.package import Package
-# =======
-# Globals
-# =======
-
-PORTDB = portage.db[portage.root]["porttree"].dbapi
-VARDB = portage.db[portage.root]["vartree"].dbapi
-
# =========
# Functions
# =========
@@ -62,12 +58,12 @@ def compare_package_strings(pkg1, pkg2):
An alternative is to use the Package descriptor from gentoolkit.package
>>> pkgs = [Package(x) for x in package_list]
>>> pkgs.sort()
-
+
@see: >>> help(cmp)
"""
- pkg1 = catpkgsplit(pkg1)
- pkg2 = catpkgsplit(pkg2)
+ pkg1 = portage.versions.catpkgsplit(pkg1)
+ pkg2 = portage.versions.catpkgsplit(pkg2)
# Compare categories
if pkg1[0] != pkg2[0]:
return cmp(pkg1[0], pkg2[0])
@@ -79,75 +75,59 @@ def compare_package_strings(pkg1, pkg2):
return portage.versions.pkgcmp(pkg1[1:], pkg2[1:])
-def find_best_match(query):
- """Return the highest unmasked version of a package matching query.
-
- @type query: str
- @param query: can be of the form: pkg, pkg-ver, cat/pkg, cat/pkg-ver, atom
- @rtype: str or None
- """
-
- match = PORTDB.xmatch("bestmatch-visible", query)
+def do_lookup(query, query_opts):
+ """A high-level wrapper around gentoolkit package-finder functions.
- return Package(match) if match else None
+ @type query: str
+ @param query: pkg, cat/pkg, pkg-ver, cat/pkg-ver, atom or regex
+ @type query_opts: dict
+ @param query_opts: user-configurable options from the calling module
+ Currently supported options are:
+ categoryFilter = str or None
+ includeInstalled = bool
+ includePortTree = bool
+ includeOverlayTree = bool
+ isRegex = bool
+ printMatchInfo = bool # Print info about the search
-def find_installed_packages(query):
- """Return a list of Package objects that matched the search key."""
+ @rtype: list
+ @return: Package objects matching query
+ """
- try:
- matches = VARDB.match(query)
- # catch the ambiguous package Exception
- except ValueError, err:
- if isinstance(err[0], list):
- matches = []
- for pkgkey in err[0]:
- matches.append(VARDB.match(pkgkey))
+ if query_opts["includeInstalled"]:
+ if query_opts["includePortTree"] or query_opts["includeOverlayTree"]:
+ simple_package_finder = partial(find_packages, include_masked=True)
+ complex_package_finder = get_cpvs
else:
- raise ValueError(err)
- except portage.exception.InvalidAtom, err:
- pp.print_warn("Invalid Atom: '%s'" % str(err))
- return []
-
- return [Package(x) for x in matches]
-
-
-def uses_globbing(query):
- """Check the query to see if it is using globbing.
+ simple_package_finder = find_installed_packages
+ complex_package_finder = get_installed_cpvs
+ elif query_opts["includePortTree"] or query_opts["includeOverlayTree"]:
+ simple_package_finder = partial(find_packages, include_masked=True)
+ complex_package_finder = get_uninstalled_cpvs
+ else:
+ pp.die(2, "Not searching in installed, portage tree or overlay."
+ " Nothing to do.")
- @rtype: bool
- @return: True if query uses globbing, else False
- """
+ is_simple_query = True
+ if query_opts["isRegex"] or uses_globbing(query):
+ is_simple_query = False
- if set('!*?[]').intersection(set(query)):
- if portage.dep.get_operator(query):
- # Query may be an atom such as '=sys-apps/portage-2.2*'
- pass
- else:
- return True
+ if is_simple_query:
+ matches = _do_simple_lookup(query, simple_package_finder, query_opts)
+ else:
+ matches = _do_complex_lookup(query, complex_package_finder, query_opts)
- return False
+ return matches
-def _do_complex_lookup(query, query_opts):
+def _do_complex_lookup(query, package_finder, query_opts):
"""Find matches for a query which is a regex or includes globbing."""
# pylint: Too many branches (18/12)
# pylint: disable-message=R0912
result = []
- if query_opts["includeInstalled"]:
- if query_opts["includePortTree"] or query_opts["includeOverlayTree"]:
- package_finder = get_cpvs
- else:
- package_finder = get_installed_cpvs
- elif query_opts["includePortTree"] or query_opts["includeOverlayTree"]:
- package_finder = get_uninstalled_cpvs
- else:
- pp.print_error("Not searching in installed, portage tree or overlay." +
- " Nothing to do.")
- pp.die(2, "This is an internal error. Please report this.")
-
if query_opts["printMatchInfo"] and not Config["piping"]:
print_query_info(query, query_opts)
@@ -194,28 +174,7 @@ def _do_complex_lookup(query, query_opts):
return [Package(x) for x in result]
-def print_query_info(query, query_opts):
- """Print info about the query to the screen."""
-
- cats = prepare_categories(query_opts["categoryFilter"])
- cat, pkg, ver, rev = split_query(query)
- del ver, rev
- if cats:
- cat_str = "in %s " % ', '.join([pp.emph(x) for x in cats])
- elif cat and not query_opts["isRegex"]:
- cat_str = "in %s " % pp.emph(cat)
- else:
- cat_str = ""
-
- if query_opts["isRegex"]:
- pkg_str = query
- else:
- pkg_str = pkg
-
- print " * Searching for %s %s..." % (pp.emph(pkg_str), cat_str)
-
-
-def _do_simple_lookup(query, query_opts):
+def _do_simple_lookup(query, package_finder, query_opts):
"""Find matches for a query which is an atom or string."""
result = []
@@ -223,11 +182,6 @@ def _do_simple_lookup(query, query_opts):
cats = prepare_categories(query_opts["categoryFilter"])
if query_opts["printMatchInfo"] and not Config["piping"]:
print_query_info(query, query_opts)
-
- if query_opts["includePortTree"] or query_opts["includeOverlayTree"]:
- package_finder = find_packages
- else:
- package_finder = find_installed_packages
result = package_finder(query)
if not query_opts["includeInstalled"]:
@@ -239,36 +193,34 @@ def _do_simple_lookup(query, query_opts):
return result
-def do_lookup(query, query_opts):
- """A high-level wrapper around gentoolkit package-finder functions.
-
+def find_best_match(query):
+ """Return the highest unmasked version of a package matching query.
+
@type query: str
- @param query: pkg, cat/pkg, pkg-ver, cat/pkg-ver, atom or regex
- @type query_opts: dict
- @param query_opts: user-configurable options from the calling module
- Currently supported options are:
+ @param query: can be of the form: pkg, pkg-ver, cat/pkg, cat/pkg-ver, atom
+ @rtype: str or None
+ """
- categoryFilter = str or None
- includeInstalled = bool
- includePortTree = bool
- includeOverlayTree = bool
- isRegex = bool
- printMatchInfo = bool # Print info about the search
+ match = PORTDB.xmatch("bestmatch-visible", query)
- @rtype: list
- @return: Package objects matching query
- """
+ return Package(match) if match else None
- is_simple_query = True
- if query_opts["isRegex"] or uses_globbing(query):
- is_simple_query = False
- if is_simple_query:
- matches = _do_simple_lookup(query, query_opts)
- else:
- matches = _do_complex_lookup(query, query_opts)
+def find_installed_packages(query):
+ """Return a list of Package objects that matched the search key."""
- return matches
+ try:
+ matches = VARDB.match(query)
+ # catch the ambiguous package Exception
+ except portage.exception.AmbiguousPackageName, err:
+ matches = []
+ for pkgkey in err[0]:
+ matches.extend(VARDB.match(pkgkey))
+ except portage.exception.InvalidAtom, err:
+ pp.print_warn("Invalid Atom: '%s'" % str(err))
+ return []
+
+ return [Package(x) for x in matches]
def find_packages(query, include_masked=False):
@@ -289,18 +241,6 @@ def find_packages(query, include_masked=False):
else:
matches = PORTDB.match(query)
matches.extend(VARDB.match(query))
- # Catch ambiguous packages
- except ValueError, err:
- if isinstance(err[0], list):
- matches = []
- for pkgkey in err[0]:
- if include_masked:
- matches.extend(PORTDB.xmatch("match-all", pkgkey))
- else:
- matches.extend(PORTDB.match(pkgkey))
- matches.extend(VARDB.match(pkgkey))
- else:
- raise ValueError(err)
except portage.exception.InvalidAtom, err:
raise errors.GentoolkitInvalidAtom(str(err))
@@ -400,6 +340,42 @@ def prepare_categories(category_filter):
return tuple(good_cats)
+def print_query_info(query, query_opts):
+ """Print info about the query to the screen."""
+
+ cats = prepare_categories(query_opts["categoryFilter"])
+ cat, pkg, ver, rev = split_query(query)
+ del ver, rev
+ if cats:
+ cat_str = "in %s " % ', '.join([pp.emph(x) for x in cats])
+ elif cat and not query_opts["isRegex"]:
+ cat_str = "in %s " % pp.emph(cat)
+ else:
+ cat_str = ""
+
+ if query_opts["isRegex"]:
+ pkg_str = query
+ else:
+ pkg_str = pkg
+
+ print " * Searching for %s %s..." % (pp.emph(pkg_str), cat_str)
+
+
+def print_file(path):
+ """Display the contents of a file."""
+
+ with open(path) as open_file:
+ lines = open_file.read()
+ print lines.strip()
+
+
+def print_sequence(seq):
+ """Print every item of a sequence."""
+
+ for item in seq:
+ print item
+
+
def split_query(query):
"""Split a query into category, name, version and revision.
@@ -410,16 +386,52 @@ def split_query(query):
Each tuple element is a string or empty string ("").
"""
- cat = name = ver = rev = ""
+ result = portage.versions.catpkgsplit(query)
- try:
- (cat, name, ver, rev) = gentoolkit.split_package_name(query)
- except ValueError, err:
- # FIXME: Not hitting this error anymore... but we should be?
- if str(err) == 'too many values to unpack':
- pp.print_error("Too many slashes ('/').")
- raise errors.GentoolkitInvalidPackageName(query)
+ if result:
+ result = list(result)
+ if result[0] == 'null':
+ result[0] = ''
+ if result[3] == 'r0':
+ result[3] = ''
+ else:
+ result = query.split("/")
+ if len(result) == 1:
+ result = ['', query, '', '']
else:
- raise ValueError(err)
-
- return (cat, name, ver, rev)
+ result = result + ['', '']
+
+ if len(result) != 4:
+ pp.print_error("Too many slashes ('/').")
+ raise errors.GentoolkitInvalidPackageName(query)
+
+ return tuple(result)
+
+
+def uniqify(seq, preserve_order=True):
+ """Return a uniqified list. Optionally preserve order."""
+
+ if preserve_order:
+ seen = set()
+ result = [x for x in seq if x not in seen and not seen.add(x)]
+ else:
+ result = list(set(seq))
+
+ return result
+
+
+def uses_globbing(query):
+ """Check the query to see if it is using globbing.
+
+ @rtype: bool
+ @return: True if query uses globbing, else False
+ """
+
+ if set('!*?[]').intersection(set(query)):
+ if portage.dep.get_operator(query):
+ # Query may be an atom such as '=sys-apps/portage-2.2*'
+ pass
+ else:
+ return True
+
+ return False