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('%s:%s' % (pack, portage.best(mylist)))
190 print('ERROR: insufficient parameters!', file=sys.stderr)
193 eroot, pkgtype, pkgspec = argv[0:3]
196 'ebuild': 'porttree',
198 'installed': 'vartree'
200 if pkgtype not in type_map:
201 print("Unrecognized package type: '%s'" % pkgtype, file=sys.stderr)
204 repo = portage.dep.dep_getrepo(pkgspec)
205 pkgspec = portage.dep.remove_slot(pkgspec)
207 values = trees[eroot][type_map[pkgtype]].dbapi.aux_get(
208 pkgspec, metakeys, myrepo=repo)
209 writemsg_stdout(''.join('%s\n' % x for x in values), noiselevel=-1)
211 print("Package not found: '%s'" % pkgspec, file=sys.stderr)
214 metadata.__doc__ = """
215 <eroot> <pkgtype> <category/package> [<key>]+
216 Returns metadata values for the specified package.
218 """ % ','.join(sorted(x for x in portage.auxdbkeys \
219 if not x.startswith('UNUSED_')))
224 """<eroot> <category/package>
225 List the files that are installed for a given package, with
226 one file listed on each line. All file names will begin with
230 print("ERROR: expected 2 parameters, got %d!" % len(argv))
234 vartree = portage.db[root]["vartree"]
235 if not vartree.dbapi.cpv_exists(cpv):
236 sys.stderr.write("Package not found: '%s'\n" % cpv)
238 cat, pkg = portage.catsplit(cpv)
239 db = portage.dblink(cat, pkg, root, vartree.settings,
240 treetype="vartree", vartree=vartree)
241 writemsg_stdout(''.join('%s\n' % x for x in sorted(db.getcontents())),
247 """<eroot> [<filename>]+
248 Given a list of files, print the packages that own the files and which
249 files belong to each package. Files owned by a package are listed on
250 the lines below it, indented by a single tab character (\\t). All file
251 paths must either start with <eroot> or be a basename alone.
252 Returns 1 if no owners could be found, and 0 otherwise.
255 sys.stderr.write("ERROR: insufficient parameters!\n")
260 vardb = portage.db[eroot]["vartree"].dbapi
261 root = portage.settings['ROOT']
270 orphan_abs_paths = set()
271 orphan_basenames = set()
273 f = portage.normalize_path(f)
274 is_basename = os.sep not in f
275 if not is_basename and f[:1] != os.sep:
277 sys.stderr.write("ERROR: cwd does not exist!\n")
280 f = os.path.join(cwd, f)
281 f = portage.normalize_path(f)
282 if not is_basename and not f.startswith(eroot):
283 sys.stderr.write("ERROR: file paths must begin with <eroot>!\n")
288 orphan_basenames.add(f)
290 files.append(f[len(root)-1:])
291 orphan_abs_paths.add(f)
293 owners = vardb._owners.get_owners(files)
296 for pkg, owned_files in owners.items():
298 msg.append("%s\n" % cpv)
299 for f in sorted(owned_files):
300 f_abs = os.path.join(root, f.lstrip(os.path.sep))
301 msg.append("\t%s\n" % (f_abs,))
302 orphan_abs_paths.discard(f_abs)
304 orphan_basenames.discard(os.path.basename(f_abs))
306 writemsg_stdout(''.join(msg), noiselevel=-1)
308 if orphan_abs_paths or orphan_basenames:
310 orphans.extend(orphan_abs_paths)
311 orphans.extend(orphan_basenames)
314 msg.append("None of the installed packages claim these files:\n")
316 msg.append("\t%s\n" % (f,))
317 sys.stderr.write("".join(msg))
326 def is_protected(argv):
327 """<eroot> <filename>
328 Given a single filename, return code 0 if it's protected, 1 otherwise.
329 The filename must begin with <eroot>.
332 sys.stderr.write("ERROR: expected 2 parameters, got %d!\n" % len(argv))
336 root, filename = argv
345 f = portage.normalize_path(filename)
346 if not f.startswith(os.path.sep):
348 err.write("ERROR: cwd does not exist!\n")
351 f = os.path.join(cwd, f)
352 f = portage.normalize_path(f)
354 if not f.startswith(root):
355 err.write("ERROR: file paths must begin with <eroot>!\n")
359 from portage.util import ConfigProtect
361 settings = portage.settings
362 protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
363 protect_mask = portage.util.shlex_split(
364 settings.get("CONFIG_PROTECT_MASK", ""))
365 protect_obj = ConfigProtect(root, protect, protect_mask)
367 if protect_obj.isprotected(f):
373 def filter_protected(argv):
375 Read filenames from stdin and write them to stdout if they are protected.
376 All filenames are delimited by \\n and must begin with <eroot>.
379 sys.stderr.write("ERROR: expected 1 parameter, got %d!\n" % len(argv))
392 from portage.util import ConfigProtect
394 settings = portage.settings
395 protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
396 protect_mask = portage.util.shlex_split(
397 settings.get("CONFIG_PROTECT_MASK", ""))
398 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):
421 out.write("%s\n" % filename)
431 def best_visible(argv):
432 """<eroot> [pkgtype] <atom>
433 Returns category/package-version (without .ebuild).
434 The pkgtype argument defaults to "ebuild" if unspecified,
435 otherwise it must be one of ebuild, binary, or installed.
438 writemsg("ERROR: insufficient parameters!\n", noiselevel=-1)
451 "installed":"vartree"}
453 if pkgtype not in type_map:
454 writemsg("Unrecognized package type: '%s'\n" % pkgtype,
459 db = portage.db[eroot][type_map[pkgtype]].dbapi
462 atom = portage.dep_expand(atom, mydb=db, settings=portage.settings)
463 except portage.exception.InvalidAtom:
464 writemsg("ERROR: Invalid atom: '%s'\n" % atom,
468 root_config = RootConfig(portage.settings, portage.db[eroot], None)
470 if hasattr(db, "xmatch"):
471 cpv_list = db.xmatch("match-all-cpv-only", atom)
473 cpv_list = db.match(atom)
476 # reversed, for descending order
478 # verify match, since the atom may match the package
479 # for a given cpv from one repo but not another, and
480 # we can use match-all-cpv-only to avoid redundant
482 atom_set = InternalPackageSet(initial_atoms=(atom,))
484 if atom.repo is None and hasattr(db, "getRepositories"):
485 repo_list = db.getRepositories()
487 repo_list = [atom.repo]
490 for repo in repo_list:
492 metadata = dict(zip(Package.metadata_keys,
493 db.aux_get(cpv, Package.metadata_keys, myrepo=repo)))
496 pkg = Package(built=(pkgtype != "ebuild"), cpv=cpv,
497 installed=(pkgtype=="installed"), metadata=metadata,
498 root_config=root_config, type_name=pkgtype)
499 if not atom_set.findAtomForPackage(pkg):
503 writemsg_stdout("%s\n" % (pkg.cpv,), noiselevel=-1)
506 # No package found, write out an empty line.
507 writemsg_stdout("\n", noiselevel=-1)
513 def mass_best_visible(argv):
514 """<eroot> [<type>] [<category/package>]+
515 Returns category/package-version (without .ebuild).
516 The pkgtype argument defaults to "ebuild" if unspecified,
517 otherwise it must be one of ebuild, binary, or installed.
522 "installed":"vartree"}
525 print("ERROR: insufficient parameters!")
530 if argv[0] in type_map:
531 pkgtype = argv.pop(0)
533 writemsg_stdout("%s:" % pack, noiselevel=-1)
534 best_visible([root, pkgtype, pack])
540 def all_best_visible(argv):
542 Returns all best_visible packages (without .ebuild).
545 sys.stderr.write("ERROR: insufficient parameters!\n")
549 #print portage.db[argv[0]]["porttree"].dbapi.cp_all()
550 for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all():
551 mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
559 Returns a \\n separated list of category/package-version.
560 When given an empty string, all installed packages will
564 print("ERROR: expected 2 parameters, got %d!" % len(argv))
570 vardb = portage.db[root]["vartree"].dbapi
572 atom = portage.dep.Atom(atom, allow_wildcard=True, allow_repo=True)
573 except portage.exception.InvalidAtom:
574 # maybe it's valid but missing category
575 atom = portage.dep_expand(atom, mydb=vardb, settings=vardb.settings)
577 if atom.extended_syntax:
579 results = vardb.cpv_all()
582 require_metadata = atom.slot or atom.repo
583 for cpv in vardb.cpv_all():
585 if not portage.match_from_list(atom, [cpv]):
590 cpv = vardb._pkg_str(cpv, atom.repo)
591 except (KeyError, portage.exception.InvalidData):
593 if not portage.match_from_list(atom, [cpv]):
600 results = vardb.match(atom)
606 def expand_virtual(argv):
608 Returns a \\n separated list of atoms expanded from a
609 given virtual atom (GLEP 37 virtuals only),
610 excluding blocker atoms. Satisfied
611 virtual atoms are not included in the output, since
612 they are expanded to real atoms which are displayed.
613 Unsatisfied virtual atoms are displayed without
614 any expansion. The "match" command can be used to
615 resolve the returned atoms to specific installed
619 writemsg("ERROR: expected 2 parameters, got %d!\n" % len(argv),
626 results = list(expand_new_virt(
627 portage.db[root]["vartree"].dbapi, atom))
628 except portage.exception.InvalidAtom:
629 writemsg("ERROR: Invalid atom: '%s'\n" % atom,
636 writemsg_stdout("%s\n" % (x,))
643 Returns the path used for the var(installed) package database for the
644 set environment/configuration options.
647 out.write(os.path.join(portage.settings["EROOT"], portage.VDB_PATH) + "\n")
651 def gentoo_mirrors(_argv):
653 Returns the mirrors set to use in the portage configuration.
655 print(portage.settings["GENTOO_MIRRORS"])
659 def repositories_configuration(argv):
661 Returns the configuration of repositories.
664 print("ERROR: insufficient parameters!", file=sys.stderr)
666 sys.stdout.write(portage.db[argv[0]]["vartree"].settings.repositories.config_string())
670 def repos_config(argv):
673 This is an alias for the repositories_configuration command.
675 return repositories_configuration(argv)
679 Returns the PORTDIR path.
680 Deprecated in favor of repositories_configuration command.
682 print("WARNING: 'portageq portdir' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
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.
703 Deprecated in favor of repositories_configuration command.
705 print("WARNING: 'portageq portdir_overlay' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
706 print(portage.settings["PORTDIR_OVERLAY"])
711 Returns the PKGDIR path.
713 print(portage.settings["PKGDIR"])
718 Returns the DISTDIR path.
720 print(portage.settings["DISTDIR"])
725 Display the color.map as environment variables.
727 print(portage.output.colormap())
732 Returns a specific environment variable as exists prior to ebuild.sh.
733 Similar to: emerge --verbose --info | egrep '^<variable>='
735 verbose = "-v" in argv
737 argv.pop(argv.index("-v"))
740 print("ERROR: insufficient parameters!")
744 if arg in ("PORTDIR", "PORTDIR_OVERLAY", "SYNC"):
745 print("WARNING: 'portageq envvar %s' is deprecated. Use 'portageq repositories_configuration' instead." % arg, file=sys.stderr)
747 print(arg + "=" + portage._shell_quote(portage.settings[arg]))
749 print(portage.settings[arg])
755 Returns all repos with names (repo_name file) argv[0] = $EROOT
758 print("ERROR: insufficient parameters!")
760 print(" ".join(reversed(portage.db[argv[0]]["vartree"].settings.repositories.prepos_order)))
764 def master_repositories(argv):
765 """<eroot> <repo_id>+
766 Returns space-separated list of master repositories for specified repository.
769 print("ERROR: insufficient parameters!", file=sys.stderr)
772 if portage.dep._repo_name_re.match(arg) is None:
773 print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
776 repo = portage.db[argv[0]]["vartree"].settings.repositories[arg]
781 print(" ".join(x.name for x in repo.masters))
784 def master_repos(argv):
785 """<eroot> <repo_id>+
786 This is an alias for the master_repositories command.
788 return master_repositories(argv)
791 def get_repo_path(argv):
792 """<eroot> <repo_id>+
793 Returns the path to the repo named argv[1], argv[0] = $EROOT
796 print("ERROR: insufficient parameters!", file=sys.stderr)
799 if portage.dep._repo_name_re.match(arg) is None:
800 print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
802 path = portage.db[argv[0]]["vartree"].settings.repositories.treemap.get(arg)
810 def available_eclasses(argv):
811 """<eroot> <repo_id>+
812 Returns space-separated list of available eclasses for specified repository.
815 print("ERROR: insufficient parameters!", file=sys.stderr)
818 if portage.dep._repo_name_re.match(arg) is None:
819 print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
822 repo = portage.db[argv[0]]["vartree"].settings.repositories[arg]
827 print(" ".join(sorted(repo.eclass_db.eclasses)))
831 def eclass_path(argv):
832 """<eroot> <repo_id> <eclass>+
833 Returns the path to specified eclass for specified repository.
836 print("ERROR: insufficient parameters!", file=sys.stderr)
838 if portage.dep._repo_name_re.match(argv[1]) is None:
839 print("ERROR: invalid repository: %s" % argv[1], file=sys.stderr)
842 repo = portage.db[argv[0]]["vartree"].settings.repositories[argv[1]]
850 eclass = repo.eclass_db.eclasses[arg]
855 print(eclass.location)
860 def license_path(argv):
861 """<eroot> <repo_id> <license>+
862 Returns the path to specified license for specified repository.
865 print("ERROR: insufficient parameters!", file=sys.stderr)
867 if portage.dep._repo_name_re.match(argv[1]) is None:
868 print("ERROR: invalid repository: %s" % argv[1], file=sys.stderr)
871 repo = portage.db[argv[0]]["vartree"].settings.repositories[argv[1]]
879 paths = reversed([os.path.join(x.location, 'licenses', arg) for x in list(repo.masters) + [repo]])
881 if os.path.exists(path):
884 if eclass_path == "":
891 def list_preserved_libs(argv):
893 Print a list of libraries preserved during a package update in the form
894 package: path. Returns 1 if no preserved libraries could be found,
899 print("ERROR: wrong number of arguments")
901 mylibs = portage.db[argv[0]]["vartree"].dbapi._plib_registry.getPreservedLibs()
904 for cpv in sorted(mylibs):
906 for path in mylibs[cpv]:
907 msg.append(' ' + path)
910 writemsg_stdout(''.join(msg), noiselevel=-1)
914 class MaintainerEmailMatcher(object):
915 def __init__(self, maintainer_emails):
916 self._re = re.compile("^(%s)$" % "|".join(maintainer_emails))
918 def __call__(self, metadata_xml):
920 matcher = self._re.match
921 for x in metadata_xml.maintainers():
922 if x.email is not None and matcher(x.email) is not None:
927 class HerdMatcher(object):
928 def __init__(self, herds):
929 self._herds = frozenset(herds)
931 def __call__(self, metadata_xml):
933 return any(x in herds for x in metadata_xml.herds())
936 def pquery(parser, opts, args):
938 Emulates a subset of Pkgcore's pquery tool.
941 portdb = portage.db[portage.root]['porttree'].dbapi
942 root_config = RootConfig(portdb.settings,
943 portage.db[portage.root], None)
945 def _pkg(cpv, repo_name):
948 Package.metadata_keys,
950 Package.metadata_keys,
953 raise portage.exception.PackageNotFound(cpv)
954 return Package(built=False, cpv=cpv,
955 installed=False, metadata=metadata,
956 root_config=root_config,
959 need_metadata = False
962 if "/" not in arg.split(":")[0]:
963 atom = insert_category_into_atom(arg, '*')
965 writemsg("ERROR: Invalid atom: '%s'\n" % arg,
972 atom = portage.dep.Atom(atom, allow_wildcard=True, allow_repo=True)
973 except portage.exception.InvalidAtom:
974 writemsg("ERROR: Invalid atom: '%s'\n" % arg,
978 if atom.slot is not None:
985 need_metadata = False
987 if not opts.no_filters:
991 if opts.maintainer_email:
992 maintainer_emails = []
993 for x in opts.maintainer_email:
994 maintainer_emails.extend(x.split(","))
995 xml_matchers.append(MaintainerEmailMatcher(maintainer_emails))
996 if opts.herd is not None:
999 herds.extend(x.split(","))
1000 xml_matchers.append(HerdMatcher(herds))
1004 repos.extend(portdb.repositories.get_repo_for_location(location)
1005 for location in portdb.porttrees)
1006 elif opts.repo is not None:
1007 repos.append(portdb.repositories[opts.repo])
1009 repos.append(portdb.repositories.mainRepo())
1013 categories = list(portdb.categories)
1015 category_wildcard = False
1016 name_wildcard = False
1020 category, name = portage.catsplit(atom.cp)
1021 categories.append(category)
1024 category_wildcard = True
1026 name_wildcard = True
1028 if category_wildcard:
1029 categories = list(portdb.categories)
1031 categories = list(set(categories))
1036 names = sorted(set(names))
1038 no_version = opts.no_version
1041 for category in categories:
1043 cp_list = portdb.cp_all(categories=(category,))
1045 cp_list = [category + "/" + name for name in names]
1051 metadata_xml_path = os.path.join(
1052 repo.location, cp, 'metadata.xml')
1054 metadata_xml = MetaDataXML(metadata_xml_path, None)
1055 except (EnvironmentError, SyntaxError):
1058 for matcher in xml_matchers:
1059 if not matcher(metadata_xml):
1064 cpv_list = portdb.cp_list(cp, mytree=[repo.location])
1066 for cpv in cpv_list:
1069 if atom.repo is not None and \
1070 atom.repo != repo.name:
1072 if not portage.match_from_list(atom, [cpv]):
1077 pkg = _pkg(cpv, repo.name)
1078 except portage.exception.PackageNotFound:
1081 if not (opts.no_filters or pkg.visible):
1083 if not portage.match_from_list(atom, [pkg]):
1087 if no_version and matches:
1089 elif opts.no_filters:
1090 matches.extend(cpv_list)
1092 for cpv in cpv_list:
1094 pkg = _pkg(cpv, repo.name)
1095 except portage.exception.PackageNotFound:
1103 if no_version and matches:
1110 writemsg_stdout("%s\n" % (cp,), noiselevel=-1)
1112 matches = list(set(matches))
1113 portdb._cpv_sort_ascending(matches)
1115 writemsg_stdout("%s\n" % (cpv,), noiselevel=-1)
1120 #-----------------------------------------------------------------------------
1122 # DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
1125 non_commands = frozenset(['elog', 'eval_atom_use', 'exithandler', 'main', 'usage', 'uses_eroot'])
1126 commands = sorted(k for k, v in globals().items() \
1127 if k not in non_commands and isinstance(v, types.FunctionType) and v.__module__ == "__main__")
1130 def add_pquery_arguments(parser):
1131 pquery_option_groups = (
1133 'Repository matching options',
1136 "longopt": "--no-filters",
1137 "action": "store_true",
1138 "help": "no visibility filters (ACCEPT_KEYWORDS, package masking, etc)"
1141 "longopt": "--repo",
1142 "help": "repo to use (default is PORTDIR if omitted)"
1145 "longopt": "--all-repos",
1146 "help": "search all repos"
1151 'Package matching options',
1154 "longopt": "--herd",
1156 "help": "exact match on a herd"
1159 "longopt": "--maintainer-email",
1161 "help": "comma-separated list of maintainer email regexes to search for"
1166 'Output formatting',
1170 "longopt": "--no-version",
1171 "action": "store_true",
1172 "help": "collapse multiple matching versions together"
1178 for group_title, opt_data in pquery_option_groups:
1179 arg_group = parser.add_argument_group(group_title)
1180 for opt_info in opt_data:
1183 pargs.append(opt_info["shortopt"])
1187 pargs.append(opt_info["longopt"])
1193 kwargs["action"] = opt_info["action"]
1197 kwargs["help"] = opt_info["help"]
1200 arg_group.add_argument(*pargs, **portage._native_kwargs(kwargs))
1204 print(">>> Portage information query tool")
1205 print(">>> %s" % portage.VERSION)
1206 print(">>> Usage: portageq <command> [<option> ...]")
1208 print("Available commands:")
1211 # Show our commands -- we do this by scanning the functions in this
1212 # file, and formatting each functions documentation.
1214 help_mode = '--help' in argv
1215 for name in commands:
1216 # Drop non-functions
1217 obj = globals()[name]
1222 print(" MISSING DOCUMENTATION!")
1226 lines = doc.lstrip("\n").split("\n")
1227 print(" " + name + " " + lines[0].strip())
1231 for line in lines[1:]:
1232 print(" " + line.strip())
1235 print('Pkgcore pquery compatible options:')
1237 parser = ArgumentParser(add_help=False,
1238 usage='portageq pquery [options] [atom ...]')
1239 add_pquery_arguments(parser)
1243 print("\nRun portageq with --help for info")
1245 atom_validate_strict = "EBUILD_PHASE" in os.environ
1247 if atom_validate_strict:
1248 eapi = os.environ.get('EAPI')
1250 def elog(elog_funcname, lines):
1251 cmd = "source '%s/isolated-functions.sh' ; " % \
1252 os.environ["PORTAGE_BIN_PATH"]
1254 cmd += "%s %s ; " % (elog_funcname, portage._shell_quote(line))
1255 subprocess.call([portage.const.BASH_BINARY, "-c", cmd])
1258 def elog(elog_funcname, lines):
1263 argv = portage._decode_argv(argv)
1265 nocolor = os.environ.get('NOCOLOR')
1266 if nocolor in ('yes', 'true'):
1267 portage.output.nocolor()
1269 parser = ArgumentParser(add_help=False)
1272 parser.add_argument("-v", dest="verbose", action="store_true")
1274 actions = parser.add_argument_group('Actions')
1275 actions.add_argument("-h", "--help", action="store_true")
1276 actions.add_argument("--version", action="store_true")
1278 add_pquery_arguments(parser)
1280 opts, args = parser.parse_known_args(argv[1:])
1286 print("Portage", portage.VERSION)
1290 if args and args[0] in commands:
1298 return pquery(parser, opts, args)
1304 argv = argv[:1] + args
1308 sys.exit(os.EX_USAGE)
1310 function = globals()[cmd]
1311 uses_eroot = getattr(function, "uses_eroot", False) and len(argv) > 2
1313 if not os.path.isdir(argv[2]):
1314 sys.stderr.write("Not a directory: '%s'\n" % argv[2])
1315 sys.stderr.write("Run portageq with --help for info\n")
1317 sys.exit(os.EX_USAGE)
1318 eprefix = portage.settings["EPREFIX"]
1319 eroot = portage.util.normalize_path(argv[2])
1322 if not eroot.endswith(eprefix):
1323 sys.stderr.write("ERROR: This version of portageq"
1324 " only supports <eroot>s ending in"
1325 " '%s'. The provided <eroot>, '%s',"
1326 " doesn't.\n" % (eprefix, eroot))
1328 sys.exit(os.EX_USAGE)
1329 root = eroot[:1 - len(eprefix)]
1333 os.environ["ROOT"] = root
1339 args[0] = portage.settings['EROOT']
1340 retval = function(args)
1343 except portage.exception.PermissionDenied as e:
1344 sys.stderr.write("Permission denied: '%s'\n" % str(e))
1346 except portage.exception.ParseError as e:
1347 sys.stderr.write("%s\n" % str(e))
1349 except portage.exception.AmbiguousPackageName as e:
1350 # Multiple matches thrown from cpv_expand
1352 # An error has occurred so we writemsg to stderr and exit nonzero.
1353 portage.writemsg("You specified an unqualified atom that matched multiple packages:\n", noiselevel=-1)
1355 portage.writemsg("* %s\n" % pkg, noiselevel=-1)
1356 portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
1359 if __name__ == '__main__':
1360 sys.exit(main(sys.argv))
1362 #-----------------------------------------------------------------------------