2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
6 from __future__ import print_function
9 # This block ensures that ^C interrupts are handled quietly.
13 def exithandler(signum, frame):
14 signal.signal(signal.SIGINT, signal.SIG_IGN)
15 signal.signal(signal.SIGTERM, signal.SIG_IGN)
18 signal.signal(signal.SIGINT, exithandler)
19 signal.signal(signal.SIGTERM, exithandler)
21 except KeyboardInterrupt:
28 # Avoid sandbox violations after python upgrade.
29 pym_path = os.path.join(os.path.dirname(
30 os.path.dirname(os.path.realpath(__file__))), "pym")
31 if os.environ.get("SANDBOX_ON") == "1":
32 sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":")
33 if pym_path not in sandbox_write:
34 sandbox_write.append(pym_path)
35 os.environ["SANDBOX_WRITE"] = \
36 ":".join(filter(None, sandbox_write))
42 sys.path.insert(0, pym_path)
46 from portage import os
47 from portage.util import writemsg, writemsg_stdout
49 #-----------------------------------------------------------------------------
51 # To add functionality to this tool, add a function below.
53 # The format for functions is:
56 # """<list of options for this function>
57 # <description of the function>
61 # "argv" is an array of the command line parameters provided after the command.
63 # Make sure you document the function in the right format. The documentation
64 # is used to display help on the function.
66 # You do not need to add the function to any lists, this tool is introspective,
67 # and will automaticly add a command by the same name as the function!
70 def has_version(argv):
71 """<root> <category/package>
72 Return code 0 if it's available, 1 otherwise.
75 print("ERROR: insufficient parameters!")
77 if atom_validate_strict and not portage.isvalidatom(argv[1]):
78 portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
82 mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
89 has_version.uses_root = True
92 def best_version(argv):
93 """<root> <category/package>
94 Returns category/package-version (without .ebuild).
97 print("ERROR: insufficient parameters!")
99 if atom_validate_strict and not portage.isvalidatom(argv[1]):
100 portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
104 mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
105 print(portage.best(mylist))
108 best_version.uses_root = True
111 def mass_best_version(argv):
112 """<root> [<category/package>]+
113 Returns category/package-version (without .ebuild).
116 print("ERROR: insufficient parameters!")
119 for pack in argv[1:]:
120 mylist=portage.db[argv[0]]["vartree"].dbapi.match(pack)
121 print(pack+":"+portage.best(mylist))
124 mass_best_version.uses_root = True
127 """<root> <pkgtype> <category/package> [<key>]+
128 Returns metadata values for the specified package.
131 print("ERROR: insufficient parameters!", file=sys.stderr)
134 root, pkgtype, pkgspec = argv[0:3]
139 "installed":"vartree"}
140 if pkgtype not in type_map:
141 print("Unrecognized package type: '%s'" % pkgtype, file=sys.stderr)
144 if os.path.realpath(root) == os.path.realpath(portage.settings["ROOT"]):
145 root = portage.settings["ROOT"] # contains the normalized $ROOT
147 values = trees[root][type_map[pkgtype]].dbapi.aux_get(
149 writemsg_stdout(''.join('%s\n' % x for x in values), noiselevel=-1)
151 print("Package not found: '%s'" % pkgspec, file=sys.stderr)
154 metadata.uses_root = True
157 """<root> <category/package>
158 List the files that are installed for a given package, with
159 one file listed on each line. All file names will begin with
163 print("ERROR: expected 2 parameters, got %d!" % len(argv))
167 vartree = portage.db[root]["vartree"]
168 if not vartree.dbapi.cpv_exists(cpv):
169 sys.stderr.write("Package not found: '%s'\n" % cpv)
171 cat, pkg = portage.catsplit(cpv)
172 db = portage.dblink(cat, pkg, root, vartree.settings,
173 treetype="vartree", vartree=vartree)
174 writemsg_stdout(''.join('%s\n' % x for x in sorted(db.getcontents())),
176 contents.uses_root = True
179 """<root> [<filename>]+
180 Given a list of files, print the packages that own the files and which
181 files belong to each package. Files owned by a package are listed on
182 the lines below it, indented by a single tab character (\\t). All file
183 paths must either start with <root> or be a basename alone.
184 Returns 1 if no owners could be found, and 0 otherwise.
187 sys.stderr.write("ERROR: insufficient parameters!\n")
191 from portage import catsplit, dblink
192 settings = portage.settings
193 root = settings["ROOT"]
194 vardb = portage.db[root]["vartree"].dbapi
204 f = portage.normalize_path(f)
205 is_basename = os.sep not in f
206 if not is_basename and f[:1] != os.sep:
208 sys.stderr.write("ERROR: cwd does not exist!\n")
211 f = os.path.join(cwd, f)
212 f = portage.normalize_path(f)
213 if not is_basename and not f.startswith(root):
214 sys.stderr.write("ERROR: file paths must begin with <root>!\n")
220 files.append(f[len(root)-1:])
222 owners = vardb._owners.get_owners(files)
225 for pkg, owned_files in owners.iteritems():
227 msg.append("%s\n" % cpv)
228 for f in sorted(owned_files):
229 msg.append("\t%s\n" % \
230 os.path.join(root, f.lstrip(os.path.sep)))
232 writemsg_stdout(''.join(msg), noiselevel=-1)
237 sys.stderr.write("None of the installed packages claim the file(s).\n")
241 owners.uses_root = True
243 def is_protected(argv):
245 Given a single filename, return code 0 if it's protected, 1 otherwise.
246 The filename must begin with <root>.
249 sys.stderr.write("ERROR: expected 2 parameters, got %d!\n" % len(argv))
253 root, filename = argv
262 f = portage.normalize_path(filename)
263 if not f.startswith(os.path.sep):
265 err.write("ERROR: cwd does not exist!\n")
268 f = os.path.join(cwd, f)
269 f = portage.normalize_path(f)
271 if not f.startswith(root):
272 err.write("ERROR: file paths must begin with <root>!\n")
276 from portage.util import ConfigProtect
278 settings = portage.settings
279 protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
280 protect_mask = portage.util.shlex_split(
281 settings.get("CONFIG_PROTECT_MASK", ""))
282 protect_obj = ConfigProtect(root, protect, protect_mask)
284 if protect_obj.isprotected(f):
288 is_protected.uses_root = True
290 def filter_protected(argv):
292 Read filenames from stdin and write them to stdout if they are protected.
293 All filenames are delimited by \\n and must begin with <root>.
296 sys.stderr.write("ERROR: expected 1 parameter, got %d!\n" % len(argv))
309 from portage.util import ConfigProtect
311 settings = portage.settings
312 protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
313 protect_mask = portage.util.shlex_split(
314 settings.get("CONFIG_PROTECT_MASK", ""))
315 protect_obj = ConfigProtect(root, protect, protect_mask)
320 for line in sys.stdin:
321 filename = line.rstrip("\n")
322 f = portage.normalize_path(filename)
323 if not f.startswith(os.path.sep):
325 err.write("ERROR: cwd does not exist!\n")
329 f = os.path.join(cwd, f)
330 f = portage.normalize_path(f)
332 if not f.startswith(root):
333 err.write("ERROR: file paths must begin with <root>!\n")
338 if protect_obj.isprotected(f):
340 out.write("%s\n" % filename)
348 filter_protected.uses_root = True
350 def best_visible(argv):
351 """<root> [<category/package>]+
352 Returns category/package-version (without .ebuild).
355 print("ERROR: insufficient parameters!")
358 mylist=portage.db[argv[0]]["porttree"].dbapi.match(argv[1])
359 visible=portage.best(mylist)
367 best_visible.uses_root = True
370 def mass_best_visible(argv):
371 """<root> [<category/package>]+
372 Returns category/package-version (without .ebuild).
375 print("ERROR: insufficient parameters!")
378 for pack in argv[1:]:
379 mylist=portage.db[argv[0]]["porttree"].dbapi.match(pack)
380 print(pack+":"+portage.best(mylist))
383 mass_best_visible.uses_root = True
386 def all_best_visible(argv):
388 Returns all best_visible packages (without .ebuild).
391 print("ERROR: insufficient parameters!")
393 #print portage.db[argv[0]]["porttree"].dbapi.cp_all()
394 for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all():
395 mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
398 all_best_visible.uses_root = True
403 Returns a \\n separated list of category/package-version.
404 When given an empty string, all installed packages will
408 print("ERROR: expected 2 parameters, got %d!" % len(argv))
412 if atom_validate_strict and not portage.isvalidatom(atom):
413 portage.writemsg("ERROR: Invalid atom: '%s'\n" % atom,
416 results = portage.db[root]["vartree"].dbapi.match(atom)
418 results = portage.db[root]["vartree"].dbapi.cpv_all()
422 match.uses_root = True
427 Returns the path used for the var(installed) package database for the
428 set environment/configuration options.
431 out.write(os.path.join(portage.settings["ROOT"], portage.VDB_PATH) + "\n")
435 def gentoo_mirrors(argv):
437 Returns the mirrors set to use in the portage configuration.
439 print(portage.settings["GENTOO_MIRRORS"])
444 Returns the PORTDIR path.
446 print(portage.settings["PORTDIR"])
449 def config_protect(argv):
451 Returns the CONFIG_PROTECT paths.
453 print(portage.settings["CONFIG_PROTECT"])
456 def config_protect_mask(argv):
458 Returns the CONFIG_PROTECT_MASK paths.
460 print(portage.settings["CONFIG_PROTECT_MASK"])
463 def portdir_overlay(argv):
465 Returns the PORTDIR_OVERLAY path.
467 print(portage.settings["PORTDIR_OVERLAY"])
472 Returns the PKGDIR path.
474 print(portage.settings["PKGDIR"])
479 Returns the DISTDIR path.
481 print(portage.settings["DISTDIR"])
486 Returns a specific environment variable as exists prior to ebuild.sh.
487 Similar to: emerge --verbose --info | egrep '^<variable>='
489 verbose = "-v" in argv
491 argv.pop(argv.index("-v"))
494 print("ERROR: insufficient parameters!")
499 print(arg +"='"+ portage.settings[arg] +"'")
501 print(portage.settings[arg])
505 Returns all repos with names (repo_name file) argv[0] = $ROOT
508 print("ERROR: insufficient parameters!")
510 print(" ".join(portage.db[argv[0]]["porttree"].dbapi.getRepositories()))
512 def get_repo_path(argv):
514 Returns the path to the repo named argv[1], argv[0] = $ROOT
517 print("ERROR: insufficient parameters!")
520 print(portage.db[argv[0]]["porttree"].dbapi.getRepositoryPath(arg))
522 def list_preserved_libs(argv):
524 Print a list of libraries preserved during a package update in the form
525 package: path. Returns 0 if no preserved libraries could be found,
530 print("ERROR: wrong number of arguments")
532 mylibs = portage.db[argv[0]]["vartree"].dbapi.plib_registry.getPreservedLibs()
535 for cpv in sorted(mylibs):
537 for path in mylibs[cpv]:
538 msg.append(' ' + path)
541 writemsg_stdout(''.join(msg), noiselevel=-1)
543 list_preserved_libs.uses_root = True
545 #-----------------------------------------------------------------------------
547 # DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
551 print(">>> Portage information query tool")
553 print(">>> Usage: portageq <command> [<option> ...]")
555 print("Available commands:")
558 # Show our commands -- we do this by scanning the functions in this
559 # file, and formatting each functions documentation.
561 non_commands = frozenset(['exithandler', 'main',
562 'usage', 'writemsg', 'writemsg_stdout'])
563 commands = sorted(k for k, v in globals().iteritems() \
564 if type(v) is types.FunctionType and k not in non_commands)
566 for name in commands:
568 obj = globals()[name]
573 print(" MISSING DOCUMENTATION!")
577 lines = doc.split("\n")
578 print(" "+name+" "+lines[0].strip())
579 if (len(sys.argv) > 1):
580 if ("--help" not in sys.argv):
582 for line in lines[1:]:
583 print(" "+line.strip())
584 if (len(sys.argv) == 1):
585 print("\nRun portageq with --help for info")
587 atom_validate_strict = "EBUILD_PHASE" in os.environ
590 if "-h" in sys.argv or "--help" in sys.argv:
593 elif len(sys.argv) < 2:
595 sys.exit(os.EX_USAGE)
598 function = globals().get(cmd)
601 sys.exit(os.EX_USAGE)
602 function = globals()[cmd]
603 uses_root = getattr(function, "uses_root", False) and len(sys.argv) > 2
605 if not os.path.isdir(sys.argv[2]):
606 sys.stderr.write("Not a directory: '%s'\n" % sys.argv[2])
607 sys.stderr.write("Run portageq with --help for info\n")
609 sys.exit(os.EX_USAGE)
610 os.environ["ROOT"] = sys.argv[2]
613 if args and sys.hexversion < 0x3000000 and not isinstance(args[0], unicode):
614 for i in range(len(args)):
615 args[i] = portage._unicode_decode(args[i])
619 args[0] = portage.settings["ROOT"]
620 retval = function(args)
623 except portage.exception.PermissionDenied as e:
624 sys.stderr.write("Permission denied: '%s'\n" % str(e))
626 except portage.exception.ParseError as e:
627 sys.stderr.write("%s\n" % str(e))
629 except ValueError as e:
631 not hasattr(e.args[0], "__len__") or \
634 # Multiple matches thrown from cpv_expand
636 # An error has occurred so we writemsg to stderr and exit nonzero.
637 portage.writemsg("You specified an unqualified atom that matched multiple packages:\n", noiselevel=-1)
639 portage.writemsg("* %s\n" % pkg, noiselevel=-1)
640 portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
645 #-----------------------------------------------------------------------------