2 # Copyright 1999-2013 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
5 from __future__ import print_function, unicode_literals
9 # This block ensures that ^C interrupts are handled quietly.
12 def exithandler(signum, frame):
13 signal.signal(signal.SIGINT, signal.SIG_IGN)
14 signal.signal(signal.SIGTERM, signal.SIG_IGN)
15 sys.exit(128 + signum)
17 signal.signal(signal.SIGINT, exithandler)
18 signal.signal(signal.SIGTERM, exithandler)
20 except KeyboardInterrupt:
21 sys.exit(128 + signal.SIGINT)
26 # Avoid sandbox violations after python upgrade.
27 pym_path = os.path.join(os.path.dirname(
28 os.path.dirname(os.path.realpath(__file__))), "pym")
29 if os.environ.get("SANDBOX_ON") == "1":
30 sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":")
31 if pym_path not in sandbox_write:
32 sandbox_write.append(pym_path)
33 os.environ["SANDBOX_WRITE"] = \
34 ":".join(filter(None, sandbox_write))
37 sys.path.insert(0, pym_path)
39 portage._internal_caller = True
40 from portage import os
41 from portage.eapi import eapi_has_repo_deps
42 from portage.util import writemsg, writemsg_stdout
43 from portage.util._argparse import ArgumentParser
44 portage.proxy.lazyimport.lazyimport(globals(),
47 '_emerge.Package:Package',
48 '_emerge.RootConfig:RootConfig',
49 '_emerge.is_valid_package_atom:insert_category_into_atom',
50 'portage.dbapi._expand_new_virt:expand_new_virt',
51 'portage._sets.base:InternalPackageSet',
52 'portage.xml.metadata:MetaDataXML'
55 def eval_atom_use(atom):
56 if 'USE' in os.environ:
57 use = frozenset(os.environ['USE'].split())
58 atom = atom.evaluate_conditionals(use)
61 def uses_eroot(function):
62 function.uses_eroot = True
65 #-----------------------------------------------------------------------------
67 # To add functionality to this tool, add a function below.
69 # The format for functions is:
72 # """<list of options for this function>
73 # <description of the function>
77 # "argv" is an array of the command line parameters provided after the command.
79 # Make sure you document the function in the right format. The documentation
80 # is used to display help on the function.
82 # You do not need to add the function to any lists, this tool is introspective,
83 # and will automaticly add a command by the same name as the function!
87 def has_version(argv):
88 """<eroot> <category/package>
89 Return code 0 if it's available, 1 otherwise.
92 print("ERROR: insufficient parameters!")
97 allow_repo = atom_validate_strict is False or eapi_has_repo_deps(eapi)
99 atom = portage.dep.Atom(argv[1], allow_repo=allow_repo)
100 except portage.exception.InvalidAtom:
101 if atom_validate_strict:
102 portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
108 if atom_validate_strict:
110 atom = portage.dep.Atom(argv[1], allow_repo=allow_repo, eapi=eapi)
111 except portage.exception.InvalidAtom as e:
112 warnings.append("QA Notice: %s: %s" % ('has_version', e))
113 atom = eval_atom_use(atom)
116 elog('eqawarn', warnings)
119 mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom)
126 except portage.exception.InvalidAtom:
127 portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
133 def best_version(argv):
134 """<eroot> <category/package>
135 Returns category/package-version (without .ebuild).
138 print("ERROR: insufficient parameters!")
143 allow_repo = atom_validate_strict is False or eapi_has_repo_deps(eapi)
145 atom = portage.dep.Atom(argv[1], allow_repo=allow_repo)
146 except portage.exception.InvalidAtom:
147 if atom_validate_strict:
148 portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
154 if atom_validate_strict:
156 atom = portage.dep.Atom(argv[1], allow_repo=allow_repo, eapi=eapi)
157 except portage.exception.InvalidAtom as e:
158 warnings.append("QA Notice: %s: %s" % ('best_version', e))
159 atom = eval_atom_use(atom)
162 elog('eqawarn', warnings)
165 mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom)
166 print(portage.best(mylist))
172 def mass_best_version(argv):
173 """<eroot> [<category/package>]+
174 Returns category/package-version (without .ebuild).
177 print("ERROR: insufficient parameters!")
180 for pack in argv[1:]:
181 mylist=portage.db[argv[0]]["vartree"].dbapi.match(pack)
182 print(pack+":"+portage.best(mylist))
190 print("ERROR: insufficient parameters!", file=sys.stderr)
193 eroot, pkgtype, pkgspec = argv[0:3]
198 "installed":"vartree"}
199 if pkgtype not in type_map:
200 print("Unrecognized package type: '%s'" % pkgtype, file=sys.stderr)
203 repo = portage.dep.dep_getrepo(pkgspec)
204 pkgspec = portage.dep.remove_slot(pkgspec)
206 values = trees[eroot][type_map[pkgtype]].dbapi.aux_get(
207 pkgspec, metakeys, myrepo=repo)
208 writemsg_stdout(''.join('%s\n' % x for x in values), noiselevel=-1)
210 print("Package not found: '%s'" % pkgspec, file=sys.stderr)
213 metadata.__doc__ = """
214 <eroot> <pkgtype> <category/package> [<key>]+
215 Returns metadata values for the specified package.
217 """ % ','.join(sorted(x for x in portage.auxdbkeys \
218 if not x.startswith('UNUSED_')))
223 """<eroot> <category/package>
224 List the files that are installed for a given package, with
225 one file listed on each line. All file names will begin with
229 print("ERROR: expected 2 parameters, got %d!" % len(argv))
233 vartree = portage.db[root]["vartree"]
234 if not vartree.dbapi.cpv_exists(cpv):
235 sys.stderr.write("Package not found: '%s'\n" % cpv)
237 cat, pkg = portage.catsplit(cpv)
238 db = portage.dblink(cat, pkg, root, vartree.settings,
239 treetype="vartree", vartree=vartree)
240 writemsg_stdout(''.join('%s\n' % x for x in sorted(db.getcontents())),
246 """<eroot> [<filename>]+
247 Given a list of files, print the packages that own the files and which
248 files belong to each package. Files owned by a package are listed on
249 the lines below it, indented by a single tab character (\\t). All file
250 paths must either start with <eroot> or be a basename alone.
251 Returns 1 if no owners could be found, and 0 otherwise.
254 sys.stderr.write("ERROR: insufficient parameters!\n")
259 vardb = portage.db[eroot]["vartree"].dbapi
260 root = portage.settings['ROOT']
269 orphan_abs_paths = set()
270 orphan_basenames = set()
272 f = portage.normalize_path(f)
273 is_basename = os.sep not in f
274 if not is_basename and f[:1] != os.sep:
276 sys.stderr.write("ERROR: cwd does not exist!\n")
279 f = os.path.join(cwd, f)
280 f = portage.normalize_path(f)
281 if not is_basename and not f.startswith(eroot):
282 sys.stderr.write("ERROR: file paths must begin with <eroot>!\n")
287 orphan_basenames.add(f)
289 files.append(f[len(root)-1:])
290 orphan_abs_paths.add(f)
292 owners = vardb._owners.get_owners(files)
295 for pkg, owned_files in owners.items():
297 msg.append("%s\n" % cpv)
298 for f in sorted(owned_files):
299 f_abs = os.path.join(root, f.lstrip(os.path.sep))
300 msg.append("\t%s\n" % (f_abs,))
301 orphan_abs_paths.discard(f_abs)
303 orphan_basenames.discard(os.path.basename(f_abs))
305 writemsg_stdout(''.join(msg), noiselevel=-1)
307 if orphan_abs_paths or orphan_basenames:
309 orphans.extend(orphan_abs_paths)
310 orphans.extend(orphan_basenames)
313 msg.append("None of the installed packages claim these files:\n")
315 msg.append("\t%s\n" % (f,))
316 sys.stderr.write("".join(msg))
325 def is_protected(argv):
326 """<eroot> <filename>
327 Given a single filename, return code 0 if it's protected, 1 otherwise.
328 The filename must begin with <eroot>.
331 sys.stderr.write("ERROR: expected 2 parameters, got %d!\n" % len(argv))
335 root, filename = argv
344 f = portage.normalize_path(filename)
345 if not f.startswith(os.path.sep):
347 err.write("ERROR: cwd does not exist!\n")
350 f = os.path.join(cwd, f)
351 f = portage.normalize_path(f)
353 if not f.startswith(root):
354 err.write("ERROR: file paths must begin with <eroot>!\n")
358 from portage.util import ConfigProtect
360 settings = portage.settings
361 protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
362 protect_mask = portage.util.shlex_split(
363 settings.get("CONFIG_PROTECT_MASK", ""))
364 protect_obj = ConfigProtect(root, protect, protect_mask)
366 if protect_obj.isprotected(f):
372 def filter_protected(argv):
374 Read filenames from stdin and write them to stdout if they are protected.
375 All filenames are delimited by \\n and must begin with <eroot>.
378 sys.stderr.write("ERROR: expected 1 parameter, got %d!\n" % len(argv))
391 from portage.util import ConfigProtect
393 settings = portage.settings
394 protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
395 protect_mask = portage.util.shlex_split(
396 settings.get("CONFIG_PROTECT_MASK", ""))
397 protect_obj = ConfigProtect(root, protect, protect_mask)
402 for line in sys.stdin:
403 filename = line.rstrip("\n")
404 f = portage.normalize_path(filename)
405 if not f.startswith(os.path.sep):
407 err.write("ERROR: cwd does not exist!\n")
411 f = os.path.join(cwd, f)
412 f = portage.normalize_path(f)
414 if not f.startswith(root):
415 err.write("ERROR: file paths must begin with <eroot>!\n")
420 if protect_obj.isprotected(f):
422 out.write("%s\n" % filename)
432 def best_visible(argv):
433 """<eroot> [pkgtype] <atom>
434 Returns category/package-version (without .ebuild).
435 The pkgtype argument defaults to "ebuild" if unspecified,
436 otherwise it must be one of ebuild, binary, or installed.
439 writemsg("ERROR: insufficient parameters!\n", noiselevel=-1)
452 "installed":"vartree"}
454 if pkgtype not in type_map:
455 writemsg("Unrecognized package type: '%s'\n" % pkgtype,
460 db = portage.db[eroot][type_map[pkgtype]].dbapi
463 atom = portage.dep_expand(atom, mydb=db, settings=portage.settings)
464 except portage.exception.InvalidAtom:
465 writemsg("ERROR: Invalid atom: '%s'\n" % atom,
469 root_config = RootConfig(portage.settings,
470 portage.db[eroot], None)
472 if hasattr(db, "xmatch"):
473 cpv_list = db.xmatch("match-all-cpv-only", atom)
475 cpv_list = db.match(atom)
478 # reversed, for descending order
480 # verify match, since the atom may match the package
481 # for a given cpv from one repo but not another, and
482 # we can use match-all-cpv-only to avoid redundant
484 atom_set = InternalPackageSet(initial_atoms=(atom,))
486 if atom.repo is None and hasattr(db, "getRepositories"):
487 repo_list = db.getRepositories()
489 repo_list = [atom.repo]
492 for repo in repo_list:
494 metadata = dict(zip(Package.metadata_keys,
495 db.aux_get(cpv, Package.metadata_keys, myrepo=repo)))
498 pkg = Package(built=(pkgtype != "ebuild"), cpv=cpv,
499 installed=(pkgtype=="installed"), metadata=metadata,
500 root_config=root_config, type_name=pkgtype)
501 if not atom_set.findAtomForPackage(pkg):
505 writemsg_stdout("%s\n" % (pkg.cpv,), noiselevel=-1)
508 # No package found, write out an empty line.
509 writemsg_stdout("\n", noiselevel=-1)
515 def mass_best_visible(argv):
516 """<eroot> [<type>] [<category/package>]+
517 Returns category/package-version (without .ebuild).
518 The pkgtype argument defaults to "ebuild" if unspecified,
519 otherwise it must be one of ebuild, binary, or installed.
524 "installed":"vartree"}
527 print("ERROR: insufficient parameters!")
532 if argv[0] in type_map:
533 pkgtype = argv.pop(0)
535 writemsg_stdout("%s:" % pack, noiselevel=-1)
536 best_visible([root, pkgtype, pack])
542 def all_best_visible(argv):
544 Returns all best_visible packages (without .ebuild).
547 sys.stderr.write("ERROR: insufficient parameters!\n")
551 #print portage.db[argv[0]]["porttree"].dbapi.cp_all()
552 for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all():
553 mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
561 Returns a \\n separated list of category/package-version.
562 When given an empty string, all installed packages will
566 print("ERROR: expected 2 parameters, got %d!" % len(argv))
572 vardb = portage.db[root]["vartree"].dbapi
574 atom = portage.dep.Atom(atom, allow_wildcard=True, allow_repo=True)
575 except portage.exception.InvalidAtom:
576 # maybe it's valid but missing category
577 atom = portage.dep_expand(atom, mydb=vardb, settings=vardb.settings)
579 if atom.extended_syntax:
581 results = vardb.cpv_all()
584 require_metadata = atom.slot or atom.repo
585 for cpv in vardb.cpv_all():
587 if not portage.match_from_list(atom, [cpv]):
592 cpv = vardb._pkg_str(cpv, atom.repo)
593 except (KeyError, portage.exception.InvalidData):
595 if not portage.match_from_list(atom, [cpv]):
602 results = vardb.match(atom)
608 def expand_virtual(argv):
610 Returns a \\n separated list of atoms expanded from a
611 given virtual atom (GLEP 37 virtuals only),
612 excluding blocker atoms. Satisfied
613 virtual atoms are not included in the output, since
614 they are expanded to real atoms which are displayed.
615 Unsatisfied virtual atoms are displayed without
616 any expansion. The "match" command can be used to
617 resolve the returned atoms to specific installed
621 writemsg("ERROR: expected 2 parameters, got %d!\n" % len(argv),
628 results = list(expand_new_virt(
629 portage.db[root]["vartree"].dbapi, atom))
630 except portage.exception.InvalidAtom:
631 writemsg("ERROR: Invalid atom: '%s'\n" % atom,
638 writemsg_stdout("%s\n" % (x,))
645 Returns the path used for the var(installed) package database for the
646 set environment/configuration options.
649 out.write(os.path.join(portage.settings["EROOT"], portage.VDB_PATH) + "\n")
653 def gentoo_mirrors(argv):
655 Returns the mirrors set to use in the portage configuration.
657 print(portage.settings["GENTOO_MIRRORS"])
661 def repositories_configuration(argv):
663 Returns the configuration of repositories.
666 print("ERROR: insufficient parameters!", file=sys.stderr)
668 sys.stdout.write(portage.db[argv[0]]["vartree"].settings.repositories.config_string())
672 def repos_config(argv):
675 This is an alias for the repositories_configuration command.
677 return repositories_configuration(argv)
681 Returns the PORTDIR path.
683 print(portage.settings["PORTDIR"])
686 def config_protect(argv):
688 Returns the CONFIG_PROTECT paths.
690 print(portage.settings["CONFIG_PROTECT"])
693 def config_protect_mask(argv):
695 Returns the CONFIG_PROTECT_MASK paths.
697 print(portage.settings["CONFIG_PROTECT_MASK"])
700 def portdir_overlay(argv):
702 Returns the PORTDIR_OVERLAY path.
704 print(portage.settings["PORTDIR_OVERLAY"])
709 Returns the PKGDIR path.
711 print(portage.settings["PKGDIR"])
716 Returns the DISTDIR path.
718 print(portage.settings["DISTDIR"])
723 Display the color.map as environment variables.
725 print(portage.output.colormap())
730 Returns a specific environment variable as exists prior to ebuild.sh.
731 Similar to: emerge --verbose --info | egrep '^<variable>='
733 verbose = "-v" in argv
735 argv.pop(argv.index("-v"))
738 print("ERROR: insufficient parameters!")
743 print(arg +"='"+ portage.settings[arg] +"'")
745 print(portage.settings[arg])
751 Returns all repos with names (repo_name file) argv[0] = $EROOT
754 print("ERROR: insufficient parameters!")
756 print(" ".join(reversed(portage.db[argv[0]]["vartree"].settings.repositories.prepos_order)))
760 def master_repositories(argv):
761 """<eroot> <repo_id>+
762 Returns space-separated list of master repositories for specified repository.
765 print("ERROR: insufficient parameters!", file=sys.stderr)
768 if portage.dep._repo_name_re.match(arg) is None:
769 print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
772 repo = portage.db[argv[0]]["vartree"].settings.repositories[arg]
777 print(" ".join(x.name for x in repo.masters))
780 def master_repos(argv):
781 """<eroot> <repo_id>+
782 This is an alias for the master_repositories command.
784 return master_repositories(argv)
787 def get_repo_path(argv):
788 """<eroot> <repo_id>+
789 Returns the path to the repo named argv[1], argv[0] = $EROOT
792 print("ERROR: insufficient parameters!", file=sys.stderr)
795 if portage.dep._repo_name_re.match(arg) is None:
796 print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
798 path = portage.db[argv[0]]["vartree"].settings.repositories.treemap.get(arg)
806 def available_eclasses(argv):
807 """<eroot> <repo_id>+
808 Returns space-separated list of available eclasses for specified repository.
811 print("ERROR: insufficient parameters!", file=sys.stderr)
814 if portage.dep._repo_name_re.match(arg) is None:
815 print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
818 repo = portage.db[argv[0]]["vartree"].settings.repositories[arg]
823 print(" ".join(sorted(repo.eclass_db.eclasses)))
827 def eclass_path(argv):
828 """<eroot> <repo_id> <eclass>+
829 Returns the path to specified eclass for specified repository.
832 print("ERROR: insufficient parameters!", file=sys.stderr)
834 if portage.dep._repo_name_re.match(argv[1]) is None:
835 print("ERROR: invalid repository: %s" % argv[1], file=sys.stderr)
838 repo = portage.db[argv[0]]["vartree"].settings.repositories[argv[1]]
846 eclass = repo.eclass_db.eclasses[arg]
851 print(eclass.location)
856 def license_path(argv):
857 """<eroot> <repo_id> <license>+
858 Returns the path to specified license for specified repository.
861 print("ERROR: insufficient parameters!", file=sys.stderr)
863 if portage.dep._repo_name_re.match(argv[1]) is None:
864 print("ERROR: invalid repository: %s" % argv[1], file=sys.stderr)
867 repo = portage.db[argv[0]]["vartree"].settings.repositories[argv[1]]
875 paths = reversed([os.path.join(x.location, 'licenses', arg) for x in list(repo.masters) + [repo]])
877 if os.path.exists(path):
880 if eclass_path == "":
887 def list_preserved_libs(argv):
889 Print a list of libraries preserved during a package update in the form
890 package: path. Returns 1 if no preserved libraries could be found,
895 print("ERROR: wrong number of arguments")
897 mylibs = portage.db[argv[0]]["vartree"].dbapi._plib_registry.getPreservedLibs()
900 for cpv in sorted(mylibs):
902 for path in mylibs[cpv]:
903 msg.append(' ' + path)
906 writemsg_stdout(''.join(msg), noiselevel=-1)
910 class MaintainerEmailMatcher(object):
911 def __init__(self, maintainer_emails):
912 self._re = re.compile("^(%s)$" % "|".join(maintainer_emails))
914 def __call__(self, metadata_xml):
916 matcher = self._re.match
917 for x in metadata_xml.maintainers():
918 if x.email is not None and matcher(x.email) is not None:
923 class HerdMatcher(object):
924 def __init__(self, herds):
925 self._herds = frozenset(herds)
927 def __call__(self, metadata_xml):
929 return any(x in herds for x in metadata_xml.herds())
932 def pquery(parser, opts, args):
934 Emulates a subset of Pkgcore's pquery tool.
937 portdb = portage.db[portage.root]['porttree'].dbapi
938 root_config = RootConfig(portdb.settings,
939 portage.db[portage.root], None)
941 def _pkg(cpv, repo_name):
944 Package.metadata_keys,
946 Package.metadata_keys,
949 raise portage.exception.PackageNotFound(cpv)
950 return Package(built=False, cpv=cpv,
951 installed=False, metadata=metadata,
952 root_config=root_config,
955 need_metadata = False
958 if "/" not in arg.split(":")[0]:
959 atom = insert_category_into_atom(arg, '*')
961 writemsg("ERROR: Invalid atom: '%s'\n" % arg,
968 atom = portage.dep.Atom(atom, allow_wildcard=True, allow_repo=True)
969 except portage.exception.InvalidAtom:
970 writemsg("ERROR: Invalid atom: '%s'\n" % arg,
974 if atom.slot is not None:
981 need_metadata = False
983 if not opts.no_filters:
987 if opts.maintainer_email:
988 maintainer_emails = []
989 for x in opts.maintainer_email:
990 maintainer_emails.extend(x.split(","))
991 xml_matchers.append(MaintainerEmailMatcher(maintainer_emails))
992 if opts.herd is not None:
995 herds.extend(x.split(","))
996 xml_matchers.append(HerdMatcher(herds))
1000 repos.extend(portdb.repositories.get_repo_for_location(location)
1001 for location in portdb.porttrees)
1002 elif opts.repo is not None:
1003 repos.append(portdb.repositories[opts.repo])
1005 repos.append(portdb.repositories.mainRepo())
1009 categories = list(portdb.categories)
1011 category_wildcard = False
1012 name_wildcard = False
1016 category, name = portage.catsplit(atom.cp)
1017 categories.append(category)
1020 category_wildcard = True
1022 name_wildcard = True
1024 if category_wildcard:
1025 categories = list(portdb.categories)
1027 categories = list(set(categories))
1032 names = sorted(set(names))
1034 no_version = opts.no_version
1037 for category in categories:
1039 cp_list = portdb.cp_all(categories=(category,))
1041 cp_list = [category + "/" + name for name in names]
1047 metadata_xml_path = os.path.join(
1048 repo.location, cp, 'metadata.xml')
1050 metadata_xml = MetaDataXML(metadata_xml_path, None)
1051 except (EnvironmentError, SyntaxError):
1054 for matcher in xml_matchers:
1055 if not matcher(metadata_xml):
1060 cpv_list = portdb.cp_list(cp, mytree=[repo.location])
1062 for cpv in cpv_list:
1065 if atom.repo is not None and \
1066 atom.repo != repo.name:
1068 if not portage.match_from_list(atom, [cpv]):
1073 pkg = _pkg(cpv, repo.name)
1074 except portage.exception.PackageNotFound:
1077 if not (opts.no_filters or pkg.visible):
1079 if not portage.match_from_list(atom, [pkg]):
1083 if no_version and matches:
1085 elif opts.no_filters:
1086 matches.extend(cpv_list)
1088 for cpv in cpv_list:
1090 pkg = _pkg(cpv, repo.name)
1091 except portage.exception.PackageNotFound:
1099 if no_version and matches:
1106 writemsg_stdout("%s\n" % (cp,), noiselevel=-1)
1108 matches = list(set(matches))
1109 portdb._cpv_sort_ascending(matches)
1111 writemsg_stdout("%s\n" % (cpv,), noiselevel=-1)
1116 #-----------------------------------------------------------------------------
1118 # DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
1121 non_commands = frozenset(['elog', 'eval_atom_use', 'exithandler', 'main', 'usage', 'uses_eroot'])
1122 commands = sorted(k for k, v in globals().items() \
1123 if k not in non_commands and isinstance(v, types.FunctionType) and v.__module__ == "__main__")
1126 def add_pquery_arguments(parser):
1127 pquery_option_groups = (
1129 'Repository matching options',
1132 "longopt": "--no-filters",
1133 "action": "store_true",
1134 "help": "no visibility filters (ACCEPT_KEYWORDS, package masking, etc)"
1137 "longopt": "--repo",
1138 "help": "repo to use (default is PORTDIR if omitted)"
1141 "longopt": "--all-repos",
1142 "help": "search all repos"
1147 'Package matching options',
1150 "longopt": "--herd",
1152 "help": "exact match on a herd"
1155 "longopt": "--maintainer-email",
1157 "help": "comma-separated list of maintainer email regexes to search for"
1162 'Output formatting',
1166 "longopt": "--no-version",
1167 "action": "store_true",
1168 "help": "collapse multiple matching versions together"
1174 for group_title, opt_data in pquery_option_groups:
1175 arg_group = parser.add_argument_group(group_title)
1176 for opt_info in opt_data:
1179 pargs.append(opt_info["shortopt"])
1183 pargs.append(opt_info["longopt"])
1189 kwargs["action"] = opt_info["action"]
1193 kwargs["help"] = opt_info["help"]
1196 arg_group.add_argument(*pargs, **kwargs)
1200 print(">>> Portage information query tool")
1201 print(">>> %s" % portage.VERSION)
1202 print(">>> Usage: portageq <command> [<option> ...]")
1204 print("Available commands:")
1207 # Show our commands -- we do this by scanning the functions in this
1208 # file, and formatting each functions documentation.
1210 help_mode = '--help' in argv
1211 for name in commands:
1212 # Drop non-functions
1213 obj = globals()[name]
1218 print(" MISSING DOCUMENTATION!")
1222 lines = doc.lstrip("\n").split("\n")
1223 print(" " + name + " " + lines[0].strip())
1227 for line in lines[1:]:
1228 print(" " + line.strip())
1231 print('Pkgcore pquery compatible options:')
1233 parser = ArgumentParser(add_help=False,
1234 usage='portageq pquery [options] [atom ...]')
1235 add_pquery_arguments(parser)
1239 print("\nRun portageq with --help for info")
1241 atom_validate_strict = "EBUILD_PHASE" in os.environ
1243 if atom_validate_strict:
1244 eapi = os.environ.get('EAPI')
1246 def elog(elog_funcname, lines):
1247 cmd = "source '%s/isolated-functions.sh' ; " % \
1248 os.environ["PORTAGE_BIN_PATH"]
1250 cmd += "%s %s ; " % (elog_funcname, portage._shell_quote(line))
1251 subprocess.call([portage.const.BASH_BINARY, "-c", cmd])
1254 def elog(elog_funcname, lines):
1259 argv = portage._decode_argv(argv)
1261 nocolor = os.environ.get('NOCOLOR')
1262 if nocolor in ('yes', 'true'):
1263 portage.output.nocolor()
1265 parser = ArgumentParser(add_help=False)
1268 parser.add_argument("-v", dest="verbose", action="store_true")
1270 actions = parser.add_argument_group('Actions')
1271 actions.add_argument("-h", "--help", action="store_true")
1272 actions.add_argument("--version", action="store_true")
1274 add_pquery_arguments(parser)
1276 opts, args = parser.parse_known_args(argv[1:])
1282 print("Portage", portage.VERSION)
1286 if args and args[0] in commands:
1294 return pquery(parser, opts, args)
1300 argv = argv[:1] + args
1304 sys.exit(os.EX_USAGE)
1306 function = globals()[cmd]
1307 uses_eroot = getattr(function, "uses_eroot", False) and len(argv) > 2
1309 if not os.path.isdir(argv[2]):
1310 sys.stderr.write("Not a directory: '%s'\n" % argv[2])
1311 sys.stderr.write("Run portageq with --help for info\n")
1313 sys.exit(os.EX_USAGE)
1314 eprefix = portage.settings["EPREFIX"]
1315 eroot = portage.util.normalize_path(argv[2])
1318 if not eroot.endswith(eprefix):
1319 sys.stderr.write("ERROR: This version of portageq"
1320 " only supports <eroot>s ending in"
1321 " '%s'. The provided <eroot>, '%s',"
1322 " doesn't.\n" % (eprefix, eroot));
1324 sys.exit(os.EX_USAGE)
1325 root = eroot[:1-len(eprefix)]
1329 os.environ["ROOT"] = root
1335 args[0] = portage.settings['EROOT']
1336 retval = function(args)
1339 except portage.exception.PermissionDenied as e:
1340 sys.stderr.write("Permission denied: '%s'\n" % str(e))
1342 except portage.exception.ParseError as e:
1343 sys.stderr.write("%s\n" % str(e))
1345 except portage.exception.AmbiguousPackageName as e:
1346 # Multiple matches thrown from cpv_expand
1348 # An error has occurred so we writemsg to stderr and exit nonzero.
1349 portage.writemsg("You specified an unqualified atom that matched multiple packages:\n", noiselevel=-1)
1351 portage.writemsg("* %s\n" % pkg, noiselevel=-1)
1352 portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
1355 if __name__ == '__main__':
1356 sys.exit(main(sys.argv))
1358 #-----------------------------------------------------------------------------