aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pym/gentoolkit/equery/meta.py')
-rw-r--r--pym/gentoolkit/equery/meta.py955
1 files changed, 490 insertions, 465 deletions
diff --git a/pym/gentoolkit/equery/meta.py b/pym/gentoolkit/equery/meta.py
index 2e632d5..7747893 100644
--- a/pym/gentoolkit/equery/meta.py
+++ b/pym/gentoolkit/equery/meta.py
@@ -4,7 +4,7 @@
"""Display metadata about a given package."""
-__docformat__ = 'epytext'
+__docformat__ = "epytext"
# =======
# Imports
@@ -28,533 +28,558 @@ from gentoolkit.query import Query
# =======
QUERY_OPTS = {
- 'current': False,
- 'description': False,
- 'herd': False,
- 'keywords': False,
- 'license': False,
- 'maintainer': False,
- 'stablereq': False,
- 'useflags': False,
- 'upstream': False,
- 'xml': False
+ "current": False,
+ "description": False,
+ "herd": False,
+ "keywords": False,
+ "license": False,
+ "maintainer": False,
+ "stablereq": False,
+ "useflags": False,
+ "upstream": False,
+ "xml": False,
}
STABLEREQ_arches = {
- 'alpha': 'alpha@gentoo.org',
- 'amd64': 'amd64@gentoo.org',
- 'arm': 'arm@gentoo.org',
- 'hppa': 'hppa@gentoo.org',
- 'ia64': 'ia64@gentoo.org',
- 'm68k': 'm68k@gentoo.org',
- 'ppc64': 'ppc64@gentoo.org',
- 'ppc': 'ppc@gentoo.org',
- 's390': 's390@gentoo.org',
- 'sh': 'sh@gentoo.org',
- 'sparc': 'sparc@gentoo.org',
- 'x86': 'x86@gentoo.org',
+ "alpha": "alpha@gentoo.org",
+ "amd64": "amd64@gentoo.org",
+ "arm": "arm@gentoo.org",
+ "hppa": "hppa@gentoo.org",
+ "ia64": "ia64@gentoo.org",
+ "m68k": "m68k@gentoo.org",
+ "ppc64": "ppc64@gentoo.org",
+ "ppc": "ppc@gentoo.org",
+ "s390": "s390@gentoo.org",
+ "sh": "sh@gentoo.org",
+ "sparc": "sparc@gentoo.org",
+ "x86": "x86@gentoo.org",
}
# =========
# Functions
# =========
+
def print_help(with_description=True, with_usage=True):
- """Print description, usage and a detailed help message.
-
- @type with_description: bool
- @param with_description: if true, print module's __doc__ string
- """
-
- if with_description:
- print(__doc__.strip())
- print()
- if with_usage:
- print(mod_usage(mod_name="meta"))
- print()
- print(pp.command("options"))
- print(format_options((
- (" -h, --help", "display this help message"),
- (" -d, --description", "show an extended package description"),
- (" -H, --herd", "show the herd(s) for the package"),
- (" -k, --keywords", "show keywords for all matching package versions"),
- (" -l, --license", "show licenses for the best maching version"),
- (" -m, --maintainer", "show the maintainer(s) for the package"),
- (" -r, --reverse", "show the output in reverse order if applicable"),
- (" -S, --stablreq", "show STABLEREQ arches (cc's) for all matching package versions"),
- (" -u, --useflags", "show per-package USE flag descriptions"),
- (" -U, --upstream", "show package's upstream information"),
- (" -x, --xml", "show the plain metadata.xml file")
- )))
+ """Print description, usage and a detailed help message.
+
+ @type with_description: bool
+ @param with_description: if true, print module's __doc__ string
+ """
+
+ if with_description:
+ print(__doc__.strip())
+ print()
+ if with_usage:
+ print(mod_usage(mod_name="meta"))
+ print()
+ print(pp.command("options"))
+ print(
+ format_options(
+ (
+ (" -h, --help", "display this help message"),
+ (" -d, --description", "show an extended package description"),
+ (" -H, --herd", "show the herd(s) for the package"),
+ (" -k, --keywords", "show keywords for all matching package versions"),
+ (" -l, --license", "show licenses for the best maching version"),
+ (" -m, --maintainer", "show the maintainer(s) for the package"),
+ (" -r, --reverse", "show the output in reverse order if applicable"),
+ (
+ " -S, --stablreq",
+ "show STABLEREQ arches (cc's) for all matching package versions",
+ ),
+ (" -u, --useflags", "show per-package USE flag descriptions"),
+ (" -U, --upstream", "show package's upstream information"),
+ (" -x, --xml", "show the plain metadata.xml file"),
+ )
+ )
+ )
+
def stablereq(matches):
- """Produce the list of cc's for a STABLREQ bug
- @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 cc's to be added to a STABLEREQ bug.
- """
- result = {}
- for pkg in matches:
- keywords_str = pkg.environment(('KEYWORDS'), prefer_vdb=False)
- # get any unstable keywords
- keywords = set([x.lstrip('~') for x in keywords_str.split() if'~' in x])
- stable_arches = set(list(STABLEREQ_arches))
- cc_keywords = stable_arches.intersection(keywords)
- # add cc's
- result[pkg] = [STABLEREQ_arches[x] for x in cc_keywords]
- return result
+ """Produce the list of cc's for a STABLREQ bug
+ @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 cc's to be added to a STABLEREQ bug.
+ """
+ result = {}
+ for pkg in matches:
+ keywords_str = pkg.environment(("KEYWORDS"), prefer_vdb=False)
+ # get any unstable keywords
+ keywords = set([x.lstrip("~") for x in keywords_str.split() if "~" in x])
+ stable_arches = set(list(STABLEREQ_arches))
+ cc_keywords = stable_arches.intersection(keywords)
+ # add cc's
+ result[pkg] = [STABLEREQ_arches[x] for x in cc_keywords]
+ return result
+
def filter_keywords(matches):
- """Filters non-unique keywords per slot.
-
- Does not filter arch mask keywords (-). Besides simple non-unique keywords,
- also remove unstable keywords (~) if a higher version in the same slot is
- stable. This view 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.
- """
- def del_archmask(keywords):
- """Don't add arch_masked to filter set."""
- return [x for x in keywords if not x.startswith('-')]
-
- def add_unstable(keywords):
- """Add unstable keyword for all stable keywords to filter set."""
- result = list(keywords)
- result.extend(
- ['~%s' % x for x in keywords if not x.startswith(('-', '~'))]
- )
- return result
-
- result = {}
- slot_map = {}
- # Start from the newest
- rev_matches = reversed(matches)
- for pkg in rev_matches:
- keywords_str, slot = pkg.environment(('KEYWORDS', 'SLOT'),
- prefer_vdb=False)
- keywords = keywords_str.split()
- result[pkg] = [x for x in keywords if x not in slot_map.get(slot, [])]
- try:
- slot_map[slot].update(del_archmask(add_unstable(keywords)))
- except KeyError:
- slot_map[slot] = set(del_archmask(add_unstable(keywords)))
-
- return result
+ """Filters non-unique keywords per slot.
+
+ Does not filter arch mask keywords (-). Besides simple non-unique keywords,
+ also remove unstable keywords (~) if a higher version in the same slot is
+ stable. This view 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.
+ """
+
+ def del_archmask(keywords):
+ """Don't add arch_masked to filter set."""
+ return [x for x in keywords if not x.startswith("-")]
+
+ def add_unstable(keywords):
+ """Add unstable keyword for all stable keywords to filter set."""
+ result = list(keywords)
+ result.extend(["~%s" % x for x in keywords if not x.startswith(("-", "~"))])
+ return result
+
+ result = {}
+ slot_map = {}
+ # Start from the newest
+ rev_matches = reversed(matches)
+ for pkg in rev_matches:
+ keywords_str, slot = pkg.environment(("KEYWORDS", "SLOT"), prefer_vdb=False)
+ keywords = keywords_str.split()
+ result[pkg] = [x for x in keywords if x not in slot_map.get(slot, [])]
+ try:
+ slot_map[slot].update(del_archmask(add_unstable(keywords)))
+ except KeyError:
+ slot_map[slot] = set(del_archmask(add_unstable(keywords)))
+
+ return result
def format_herds(herds):
- """Format herd information for display."""
+ """Format herd information for display."""
- result = []
- for herd in herds:
- herdstr = ''
- email = "(%s)" % herd[1] if herd[1] else ''
- herdstr = herd[0]
- if CONFIG['verbose']:
- herdstr += " %s" % (email,)
- result.append(herdstr)
+ result = []
+ for herd in herds:
+ herdstr = ""
+ email = "(%s)" % herd[1] if herd[1] else ""
+ herdstr = herd[0]
+ if CONFIG["verbose"]:
+ herdstr += " %s" % (email,)
+ result.append(herdstr)
- return result
+ return result
def format_maintainers(maints):
- """Format maintainer information for display."""
+ """Format maintainer information for display."""
- result = []
- for maint in maints:
- maintstr = maint.email or ''
- if CONFIG['verbose']:
- maintstr += " (%s)" % (maint.name,) if maint.name else ''
- maintstr += " - %s" % (maint.restrict,) if maint.restrict else ''
- maintstr += "\n%s" % (maint.description,) if maint.description else ''
- result.append(maintstr)
+ result = []
+ for maint in maints:
+ maintstr = maint.email or ""
+ if CONFIG["verbose"]:
+ maintstr += " (%s)" % (maint.name,) if maint.name else ""
+ maintstr += " - %s" % (maint.restrict,) if maint.restrict else ""
+ maintstr += "\n%s" % (maint.description,) if maint.description else ""
+ result.append(maintstr)
- return result
+ return result
def format_upstream(upstream):
- """Format upstream information for display."""
-
- def _format_upstream_docs(docs):
- result = []
- for doc in docs:
- doc_location = doc[0]
- doc_lang = doc[1]
- docstr = doc_location
- if doc_lang is not None:
- docstr += " (%s)" % (doc_lang,)
- result.append(docstr)
- return result
-
- def _format_upstream_ids(ids):
- result = []
- for id_ in ids:
- site = id_[0]
- proj_id = id_[1]
- idstr = "%s ID: %s" % (site, proj_id)
- result.append(idstr)
- return result
-
- result = []
- for up in upstream:
- upmaints = format_maintainers(up.maintainers)
- for upmaint in upmaints:
- result.append(format_line(upmaint, "Maintainer: ", " " * 13))
-
- for upchange in up.changelogs:
- result.append(format_line(upchange, "ChangeLog: ", " " * 13))
-
- updocs = _format_upstream_docs(up.docs)
- for updoc in updocs:
- result.append(format_line(updoc, "Docs: ", " " * 13))
-
- for upbug in up.bugtrackers:
- result.append(format_line(upbug, "Bugs-to: ", " " * 13))
-
- upids = _format_upstream_ids(up.remoteids)
- for upid in upids:
- result.append(format_line(upid, "Remote-ID: ", " " * 13))
-
- return result
+ """Format upstream information for display."""
+
+ def _format_upstream_docs(docs):
+ result = []
+ for doc in docs:
+ doc_location = doc[0]
+ doc_lang = doc[1]
+ docstr = doc_location
+ if doc_lang is not None:
+ docstr += " (%s)" % (doc_lang,)
+ result.append(docstr)
+ return result
+
+ def _format_upstream_ids(ids):
+ result = []
+ for id_ in ids:
+ site = id_[0]
+ proj_id = id_[1]
+ idstr = "%s ID: %s" % (site, proj_id)
+ result.append(idstr)
+ return result
+
+ result = []
+ for up in upstream:
+ upmaints = format_maintainers(up.maintainers)
+ for upmaint in upmaints:
+ result.append(format_line(upmaint, "Maintainer: ", " " * 13))
+
+ for upchange in up.changelogs:
+ result.append(format_line(upchange, "ChangeLog: ", " " * 13))
+
+ updocs = _format_upstream_docs(up.docs)
+ for updoc in updocs:
+ result.append(format_line(updoc, "Docs: ", " " * 13))
+
+ for upbug in up.bugtrackers:
+ result.append(format_line(upbug, "Bugs-to: ", " " * 13))
+
+ upids = _format_upstream_ids(up.remoteids)
+ for upid in upids:
+ result.append(format_line(upid, "Remote-ID: ", " " * 13))
+
+ return result
def format_useflags(useflags):
- """Format USE flag information for display."""
+ """Format USE flag information for display."""
- result = []
- for flag in useflags:
- result.append(pp.useflag(flag.name))
- result.append(flag.description)
- result.append("")
+ result = []
+ for flag in useflags:
+ result.append(pp.useflag(flag.name))
+ result.append(flag.description)
+ result.append("")
- return result
+ return result
def format_keywords(keywords):
- """Sort and colorize keywords for display."""
+ """Sort and colorize keywords for display."""
- result = []
+ result = []
- for kw in sorted(keywords, key=Keyword):
- if kw.startswith('-'):
- # arch masked
- kw = pp.keyword(kw, stable=False, hard_masked=True)
- elif kw.startswith('~'):
- # keyword masked
- kw = pp.keyword(kw, stable=False, hard_masked=False)
- else:
- # stable
- kw = pp.keyword(kw, stable=True, hard_masked=False)
- result.append(kw)
+ for kw in sorted(keywords, key=Keyword):
+ if kw.startswith("-"):
+ # arch masked
+ kw = pp.keyword(kw, stable=False, hard_masked=True)
+ elif kw.startswith("~"):
+ # keyword masked
+ kw = pp.keyword(kw, stable=False, hard_masked=False)
+ else:
+ # stable
+ kw = pp.keyword(kw, stable=True, hard_masked=False)
+ result.append(kw)
- return ' '.join(result)
+ return " ".join(result)
def format_keywords_line(pkg, fmtd_keywords, slot, verstr_len):
- """Format the entire keywords line for display."""
+ """Format the entire keywords line for display."""
- ver = pkg.fullversion
- result = "%s:%s: %s" % (ver, pp.slot(slot), fmtd_keywords)
- if CONFIG['verbose'] and fmtd_keywords:
- result = format_line(fmtd_keywords, "%s:%s: " % (ver, pp.slot(slot)),
- " " * (verstr_len + 2))
+ ver = pkg.fullversion
+ result = "%s:%s: %s" % (ver, pp.slot(slot), fmtd_keywords)
+ if CONFIG["verbose"] and fmtd_keywords:
+ result = format_line(
+ fmtd_keywords, "%s:%s: " % (ver, pp.slot(slot)), " " * (verstr_len + 2)
+ )
- return result
+ return result
def format_stablereq_line(pkg, fmtd_ccs, slot):
- """Format the entire stablereq line for display (no indented linewrapping)
- """
- return "%s:%s: %s" % (pkg.fullversion, pp.slot(slot), fmtd_ccs)
+ """Format the entire stablereq line for display (no indented linewrapping)"""
+ return "%s:%s: %s" % (pkg.fullversion, pp.slot(slot), fmtd_ccs)
def format_homepage(homepage):
- """format the homepage(s) entries for dispaly"""
- result = []
- for page in homepage.split():
- result.append(format_line(page, "Homepage: ", " " * 13))
- return result
+ """format the homepage(s) entries for dispaly"""
+ result = []
+ for page in homepage.split():
+ result.append(format_line(page, "Homepage: ", " " * 13))
+ return result
def call_format_functions(best_match, matches):
- """Call information gathering functions and display the results."""
-
- if CONFIG['verbose']:
- repo = best_match.repo_name()
- pp.uprint(" * %s [%s]" % (pp.cpv(best_match.cp), pp.section(repo)))
-
- got_opts = False
- if any(QUERY_OPTS.values()):
- # Specific information requested, less formatting
- got_opts = True
-
- if QUERY_OPTS["herd"] or not got_opts:
- herds = best_match.metadata.herds(include_email=True)
- if any(not h[0] for h in herds):
- print(pp.warn("The packages metadata.xml has an empty <herd> tag"),
- file = sys.stderr)
- herds = [x for x in herds if x[0]]
- herds = format_herds(herds)
- if QUERY_OPTS["herd"]:
- print_sequence(format_list(herds))
- else:
- for herd in herds:
- pp.uprint(format_line(herd, "Herd: ", " " * 13))
-
- if QUERY_OPTS["maintainer"] or not got_opts:
- maints = format_maintainers(best_match.metadata.maintainers())
- if QUERY_OPTS["maintainer"]:
- print_sequence(format_list(maints))
- else:
- if not maints:
- pp.uprint(format_line([], "Maintainer: ", " " * 13))
- else:
- for maint in maints:
- pp.uprint(format_line(maint, "Maintainer: ", " " * 13))
-
- if QUERY_OPTS["upstream"] or not got_opts:
- upstream = format_upstream(best_match.metadata.upstream())
- homepage = format_homepage(best_match.environment("HOMEPAGE"))
- if QUERY_OPTS["upstream"]:
- upstream = format_list(upstream)
- else:
- upstream = format_list(upstream, "Upstream: ", " " * 13)
- print_sequence(upstream)
- print_sequence(homepage)
-
- if not got_opts:
- pkg_loc = best_match.package_path()
- pp.uprint(format_line(pkg_loc, "Location: ", " " * 13))
-
- 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:
- slot = match.environment('SLOT')
- verstr_len = len(match.fullversion) + len(slot)
- fmtd_keywords = format_keywords(keyword_map[match])
- keywords_line = format_keywords_line(
- match, fmtd_keywords, slot, verstr_len
- )
- if QUERY_OPTS["keywords"]:
- pp.uprint(keywords_line)
- else:
- indent = " " * (16 + verstr_len)
- pp.uprint(format_line(keywords_line, "Keywords: ", indent))
-
- if QUERY_OPTS["description"]:
- desc = best_match.metadata.descriptions()
- print_sequence(format_list(desc))
-
- if QUERY_OPTS["useflags"]:
- useflags = format_useflags(best_match.metadata.use())
- print_sequence(format_list(useflags))
-
- if QUERY_OPTS["license"] or not got_opts:
- _license = best_match.environment(["LICENSE"])
- if QUERY_OPTS["license"]:
- _license = format_list(_license)
- else:
- _license = format_list(_license, "License: ", " " * 13)
- print_sequence(_license)
-
- if QUERY_OPTS["stablereq"]:
- # Get {<Package 'dev-libs/glib-2.20.5'>: [u'ia64', u'm68k', ...], ...}
- stablereq_map = stablereq(matches)
- for match in matches:
- slot = match.environment('SLOT')
- verstr_len = len(match.fullversion) + len(slot)
- fmtd_ccs = ','.join(sorted(stablereq_map[match]))
- stablereq_line = format_stablereq_line(
- match, fmtd_ccs, slot
- )
- #print("STABLEREQ:", )
- pp.uprint(stablereq_line)
-
- if QUERY_OPTS["xml"]:
- print_file(os.path.join(best_match.package_path(), 'metadata.xml'))
+ """Call information gathering functions and display the results."""
+
+ if CONFIG["verbose"]:
+ repo = best_match.repo_name()
+ pp.uprint(" * %s [%s]" % (pp.cpv(best_match.cp), pp.section(repo)))
+
+ got_opts = False
+ if any(QUERY_OPTS.values()):
+ # Specific information requested, less formatting
+ got_opts = True
+
+ if QUERY_OPTS["herd"] or not got_opts:
+ herds = best_match.metadata.herds(include_email=True)
+ if any(not h[0] for h in herds):
+ print(
+ pp.warn("The packages metadata.xml has an empty <herd> tag"),
+ file=sys.stderr,
+ )
+ herds = [x for x in herds if x[0]]
+ herds = format_herds(herds)
+ if QUERY_OPTS["herd"]:
+ print_sequence(format_list(herds))
+ else:
+ for herd in herds:
+ pp.uprint(format_line(herd, "Herd: ", " " * 13))
+
+ if QUERY_OPTS["maintainer"] or not got_opts:
+ maints = format_maintainers(best_match.metadata.maintainers())
+ if QUERY_OPTS["maintainer"]:
+ print_sequence(format_list(maints))
+ else:
+ if not maints:
+ pp.uprint(format_line([], "Maintainer: ", " " * 13))
+ else:
+ for maint in maints:
+ pp.uprint(format_line(maint, "Maintainer: ", " " * 13))
+
+ if QUERY_OPTS["upstream"] or not got_opts:
+ upstream = format_upstream(best_match.metadata.upstream())
+ homepage = format_homepage(best_match.environment("HOMEPAGE"))
+ if QUERY_OPTS["upstream"]:
+ upstream = format_list(upstream)
+ else:
+ upstream = format_list(upstream, "Upstream: ", " " * 13)
+ print_sequence(upstream)
+ print_sequence(homepage)
+
+ if not got_opts:
+ pkg_loc = best_match.package_path()
+ pp.uprint(format_line(pkg_loc, "Location: ", " " * 13))
+
+ 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:
+ slot = match.environment("SLOT")
+ verstr_len = len(match.fullversion) + len(slot)
+ fmtd_keywords = format_keywords(keyword_map[match])
+ keywords_line = format_keywords_line(match, fmtd_keywords, slot, verstr_len)
+ if QUERY_OPTS["keywords"]:
+ pp.uprint(keywords_line)
+ else:
+ indent = " " * (16 + verstr_len)
+ pp.uprint(format_line(keywords_line, "Keywords: ", indent))
+
+ if QUERY_OPTS["description"]:
+ desc = best_match.metadata.descriptions()
+ print_sequence(format_list(desc))
+
+ if QUERY_OPTS["useflags"]:
+ useflags = format_useflags(best_match.metadata.use())
+ print_sequence(format_list(useflags))
+
+ if QUERY_OPTS["license"] or not got_opts:
+ _license = best_match.environment(["LICENSE"])
+ if QUERY_OPTS["license"]:
+ _license = format_list(_license)
+ else:
+ _license = format_list(_license, "License: ", " " * 13)
+ print_sequence(_license)
+
+ if QUERY_OPTS["stablereq"]:
+ # Get {<Package 'dev-libs/glib-2.20.5'>: [u'ia64', u'm68k', ...], ...}
+ stablereq_map = stablereq(matches)
+ for match in matches:
+ slot = match.environment("SLOT")
+ verstr_len = len(match.fullversion) + len(slot)
+ fmtd_ccs = ",".join(sorted(stablereq_map[match]))
+ stablereq_line = format_stablereq_line(match, fmtd_ccs, slot)
+ # print("STABLEREQ:", )
+ pp.uprint(stablereq_line)
+
+ if QUERY_OPTS["xml"]:
+ print_file(os.path.join(best_match.package_path(), "metadata.xml"))
def format_line(line, first="", subsequent="", force_quiet=False):
- """Wrap a string at word boundaries and optionally indent the first line
- and/or subsequent lines with custom strings.
-
- Preserve newlines if the longest line is not longer than
- CONFIG['termWidth']. To force the preservation of newlines and indents,
- split the string into a list and feed it to format_line via format_list.
-
- @see: format_list()
- @type line: string
- @param line: text to format
- @type first: string
- @param first: text to prepend to the first line
- @type subsequent: string
- @param subsequent: text to prepend to subsequent lines
- @type force_quiet: boolean
- @rtype: string
- @return: A wrapped line
- """
-
- if line:
- line = line.expandtabs().strip("\n").splitlines()
- else:
- if force_quiet:
- return
- else:
- return first + "None specified"
-
- if len(first) > len(subsequent):
- wider_indent = first
- else:
- wider_indent = subsequent
-
- widest_line_len = len(max(line, key=len)) + len(wider_indent)
-
- if widest_line_len > CONFIG['termWidth']:
- twrap = TextWrapper(width=CONFIG['termWidth'], expand_tabs=False,
- initial_indent=first, subsequent_indent=subsequent)
- line = " ".join(line)
- line = re.sub(r"\s+", " ", line)
- line = line.lstrip()
- result = twrap.fill(line)
- else:
- # line will fit inside CONFIG['termWidth'], so preserve whitespace and
- # newlines
- line[0] = first + line[0] # Avoid two newlines if len == 1
-
- if len(line) > 1:
- line[0] = line[0] + "\n"
- for i in range(1, (len(line[1:-1]) + 1)):
- line[i] = subsequent + line[i] + "\n"
- line[-1] = subsequent + line[-1] # Avoid two newlines on last line
-
- if line[-1].isspace():
- del line[-1] # Avoid trailing blank lines
-
- result = "".join(line)
-
- return result
+ """Wrap a string at word boundaries and optionally indent the first line
+ and/or subsequent lines with custom strings.
+
+ Preserve newlines if the longest line is not longer than
+ CONFIG['termWidth']. To force the preservation of newlines and indents,
+ split the string into a list and feed it to format_line via format_list.
+
+ @see: format_list()
+ @type line: string
+ @param line: text to format
+ @type first: string
+ @param first: text to prepend to the first line
+ @type subsequent: string
+ @param subsequent: text to prepend to subsequent lines
+ @type force_quiet: boolean
+ @rtype: string
+ @return: A wrapped line
+ """
+
+ if line:
+ line = line.expandtabs().strip("\n").splitlines()
+ else:
+ if force_quiet:
+ return
+ else:
+ return first + "None specified"
+
+ if len(first) > len(subsequent):
+ wider_indent = first
+ else:
+ wider_indent = subsequent
+
+ widest_line_len = len(max(line, key=len)) + len(wider_indent)
+
+ if widest_line_len > CONFIG["termWidth"]:
+ twrap = TextWrapper(
+ width=CONFIG["termWidth"],
+ expand_tabs=False,
+ initial_indent=first,
+ subsequent_indent=subsequent,
+ )
+ line = " ".join(line)
+ line = re.sub(r"\s+", " ", line)
+ line = line.lstrip()
+ result = twrap.fill(line)
+ else:
+ # line will fit inside CONFIG['termWidth'], so preserve whitespace and
+ # newlines
+ line[0] = first + line[0] # Avoid two newlines if len == 1
+
+ if len(line) > 1:
+ line[0] = line[0] + "\n"
+ for i in range(1, (len(line[1:-1]) + 1)):
+ line[i] = subsequent + line[i] + "\n"
+ line[-1] = subsequent + line[-1] # Avoid two newlines on last line
+
+ if line[-1].isspace():
+ del line[-1] # Avoid trailing blank lines
+
+ result = "".join(line)
+
+ return result
def format_list(lst, first="", subsequent="", force_quiet=False):
- """Feed elements of a list to format_line().
-
- @see: format_line()
- @type lst: list
- @param lst: list to format
- @type first: string
- @param first: text to prepend to the first line
- @type subsequent: string
- @param subsequent: text to prepend to subsequent lines
- @rtype: list
- @return: list with element text wrapped at CONFIG['termWidth']
- """
-
- result = []
- if lst:
- # Format the first line
- line = format_line(lst[0], first, subsequent, force_quiet)
- result.append(line)
- # Format subsequent lines
- for elem in lst[1:]:
- if elem:
- result.append(format_line(elem, subsequent, subsequent,
- force_quiet))
- else:
- # We don't want to send a blank line to format_line()
- result.append("")
- else:
- if CONFIG['verbose']:
- if force_quiet:
- result = None
- else:
- # Send empty list, we'll get back first + `None specified'
- result.append(format_line(lst, first, subsequent))
-
- return result
+ """Feed elements of a list to format_line().
+
+ @see: format_line()
+ @type lst: list
+ @param lst: list to format
+ @type first: string
+ @param first: text to prepend to the first line
+ @type subsequent: string
+ @param subsequent: text to prepend to subsequent lines
+ @rtype: list
+ @return: list with element text wrapped at CONFIG['termWidth']
+ """
+
+ result = []
+ if lst:
+ # Format the first line
+ line = format_line(lst[0], first, subsequent, force_quiet)
+ result.append(line)
+ # Format subsequent lines
+ for elem in lst[1:]:
+ if elem:
+ result.append(format_line(elem, subsequent, subsequent, force_quiet))
+ else:
+ # We don't want to send a blank line to format_line()
+ result.append("")
+ else:
+ if CONFIG["verbose"]:
+ if force_quiet:
+ result = None
+ else:
+ # Send empty list, we'll get back first + `None specified'
+ result.append(format_line(lst, first, subsequent))
+
+ return result
def parse_module_options(module_opts):
- """Parse module options and update QUERY_OPTS"""
-
- opts = (x[0] for x in module_opts)
- for opt in opts:
- if opt in ('-h', '--help'):
- print_help()
- sys.exit(0)
- elif opt in ('-d', '--description'):
- QUERY_OPTS["description"] = True
- elif opt in ('-H', '--herd'):
- QUERY_OPTS["herd"] = True
- elif opt in ('-l', '--license'):
- QUERY_OPTS["license"] = True
- elif opt in ('-m', '--maintainer'):
- QUERY_OPTS["maintainer"] = True
- elif opt in ('-k', '--keywords'):
- QUERY_OPTS["keywords"] = True
- elif opt in ('-S', '--stablereq'):
- QUERY_OPTS["stablereq"] = True
- elif opt in ('-u', '--useflags'):
- QUERY_OPTS["useflags"] = True
- elif opt in ('-U', '--upstream'):
- QUERY_OPTS["upstream"] = True
- elif opt in ('-x', '--xml'):
- QUERY_OPTS["xml"] = True
+ """Parse module options and update QUERY_OPTS"""
+
+ opts = (x[0] for x in module_opts)
+ for opt in opts:
+ if opt in ("-h", "--help"):
+ print_help()
+ sys.exit(0)
+ elif opt in ("-d", "--description"):
+ QUERY_OPTS["description"] = True
+ elif opt in ("-H", "--herd"):
+ QUERY_OPTS["herd"] = True
+ elif opt in ("-l", "--license"):
+ QUERY_OPTS["license"] = True
+ elif opt in ("-m", "--maintainer"):
+ QUERY_OPTS["maintainer"] = True
+ elif opt in ("-k", "--keywords"):
+ QUERY_OPTS["keywords"] = True
+ elif opt in ("-S", "--stablereq"):
+ QUERY_OPTS["stablereq"] = True
+ elif opt in ("-u", "--useflags"):
+ QUERY_OPTS["useflags"] = True
+ elif opt in ("-U", "--upstream"):
+ QUERY_OPTS["upstream"] = True
+ elif opt in ("-x", "--xml"):
+ QUERY_OPTS["xml"] = True
def main(input_args):
- """Parse input and run the program."""
-
- short_opts = "hdHklmrSuUx"
- long_opts = ('help', 'description', 'herd', 'keywords', 'license',
- 'maintainer', 'reverse', 'stablereq', 'useflags', 'upstream', 'xml')
-
- try:
- module_opts, queries = gnu_getopt(input_args, short_opts, long_opts)
- except GetoptError as err:
- sys.stderr.write(pp.error("Module %s" % err))
- print()
- print_help(with_description=False)
- sys.exit(2)
-
- parse_module_options(module_opts)
-
- # Find queries' Portage directory and throw error if invalid
- if not queries:
- print_help()
- sys.exit(2)
-
- first_run = True
- for query in (Query(x) for x in queries):
- best_match = query.find_best()
- matches = query.find(include_masked=True)
- if best_match is None or not matches:
- raise errors.GentoolkitNoMatches(query)
-
- if best_match.metadata is None:
- print(pp.warn("Package {0} is missing "
- "metadata.xml".format(best_match.cpv)),
- file = sys.stderr)
- continue
-
- if not first_run:
- print()
-
- matches.sort()
- matches.sort(reverse=any(name in ('-r', '--reverse')
- for name, opt in module_opts))
- call_format_functions(best_match, matches)
-
- first_run = False
+ """Parse input and run the program."""
+
+ short_opts = "hdHklmrSuUx"
+ long_opts = (
+ "help",
+ "description",
+ "herd",
+ "keywords",
+ "license",
+ "maintainer",
+ "reverse",
+ "stablereq",
+ "useflags",
+ "upstream",
+ "xml",
+ )
+
+ try:
+ module_opts, queries = gnu_getopt(input_args, short_opts, long_opts)
+ except GetoptError as err:
+ sys.stderr.write(pp.error("Module %s" % err))
+ print()
+ print_help(with_description=False)
+ sys.exit(2)
+
+ parse_module_options(module_opts)
+
+ # Find queries' Portage directory and throw error if invalid
+ if not queries:
+ print_help()
+ sys.exit(2)
+
+ first_run = True
+ for query in (Query(x) for x in queries):
+ best_match = query.find_best()
+ matches = query.find(include_masked=True)
+ if best_match is None or not matches:
+ raise errors.GentoolkitNoMatches(query)
+
+ if best_match.metadata is None:
+ print(
+ pp.warn(
+ "Package {0} is missing " "metadata.xml".format(best_match.cpv)
+ ),
+ file=sys.stderr,
+ )
+ continue
+
+ if not first_run:
+ print()
+
+ matches.sort()
+ matches.sort(
+ reverse=any(name in ("-r", "--reverse") for name, opt in module_opts)
+ )
+ call_format_functions(best_match, matches)
+
+ first_run = False
+
# vim: set ts=4 sw=4 tw=79: