2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
7 # This block ensures that ^C interrupts are handled quietly.
11 def exithandler(signum, frame):
12 signal.signal(signal.SIGINT, signal.SIG_IGN)
13 signal.signal(signal.SIGTERM, signal.SIG_IGN)
16 signal.signal(signal.SIGINT, exithandler)
17 signal.signal(signal.SIGTERM, exithandler)
19 except KeyboardInterrupt:
26 #-----------------------------------------------------------------------------
28 # To add functionality to this tool, add a function below.
30 # The format for functions is:
33 # """<list of options for this function>
34 # <description of the function>
38 # "argv" is an array of the command line parameters provided after the command.
40 # Make sure you document the function in the right format. The documentation
41 # is used to display help on the function.
43 # You do not need to add the function to any lists, this tool is introspective,
44 # and will automaticly add a command by the same name as the function!
47 def has_version(argv):
48 """<root> <category/package>
49 Return code 0 if it's available, 1 otherwise.
52 print "ERROR: insufficient parameters!"
54 if atom_validate_strict and not portage.isvalidatom(argv[1]):
55 portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
59 mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
66 has_version.uses_root = True
69 def best_version(argv):
70 """<root> <category/package>
71 Returns category/package-version (without .ebuild).
74 print "ERROR: insufficient parameters!"
76 if atom_validate_strict and not portage.isvalidatom(argv[1]):
77 portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
81 mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
82 print portage.best(mylist)
85 best_version.uses_root = True
88 def mass_best_version(argv):
89 """<root> [<category/package>]+
90 Returns category/package-version (without .ebuild).
93 print "ERROR: insufficient parameters!"
97 mylist=portage.db[argv[0]]["vartree"].dbapi.match(pack)
98 print pack+":"+portage.best(mylist)
101 mass_best_version.uses_root = True
104 """<root> <pkgtype> <category/package> [<key>]+
105 Returns metadata values for the specified package.
108 print >> sys.stderr, "ERROR: insufficient parameters!"
111 root, pkgtype, pkgspec = argv[0:3]
116 "installed":"vartree"}
117 if pkgtype not in type_map:
118 print >> sys.stderr, "Unrecognized package type: '%s'" % pkgtype
121 if os.path.realpath(root) == os.path.realpath(portage.settings["ROOT"]):
122 root = portage.settings["ROOT"] # contains the normalized $ROOT
124 values = trees[root][type_map[pkgtype]].dbapi.aux_get(
129 print >> sys.stderr, "Package not found: '%s'" % pkgspec
132 metadata.uses_root = True
135 """<root> <category/package>
136 List the files that are installed for a given package, with
137 one file listed on each line. All file names will begin with
141 print "ERROR: expected 2 parameters, got %d!" % len(argv)
145 vartree = portage.db[root]["vartree"]
146 if not vartree.dbapi.cpv_exists(cpv):
147 sys.stderr.write("Package not found: '%s'\n" % cpv)
149 cat, pkg = portage.catsplit(cpv)
150 db = portage.dblink(cat, pkg, root, vartree.settings,
151 treetype="vartree", vartree=vartree)
152 file_list = db.getcontents().keys()
155 sys.stdout.write("%s\n" % f)
157 contents.uses_root = True
160 """<root> [<filename>]+
161 Given a list of files, print the packages that own the files and which
162 files belong to each package. Files owned by a package are listed on
163 the lines below it, indented by a single tab character (\\t). All file
164 paths must start with <root>. Returns 1 if no owners could be found,
168 sys.stderr.write("ERROR: insufficient parameters!\n")
172 from portage import catsplit, dblink
173 settings = portage.settings
174 root = settings["ROOT"]
175 vardb = portage.db[root]["vartree"].dbapi
185 f = portage.normalize_path(f)
186 if not f.startswith(os.path.sep):
188 sys.stderr.write("ERROR: cwd does not exist!\n")
191 f = os.path.join(cwd, f)
192 f = portage.normalize_path(f)
193 if not f.startswith(root):
194 sys.stderr.write("ERROR: file paths must begin with <root>!\n")
197 files.append(f[len(root):])
199 owners = vardb._owners.get_owners(files)
201 for pkg, owned_files in owners.iteritems():
203 sys.stdout.write("%s\n" % cpv)
204 for f in sorted(owned_files):
205 sys.stdout.write("\t%s\n" % \
206 os.path.join(root, f.lstrip(os.path.sep)))
211 sys.stderr.write("None of the installed packages claim the file(s).\n")
215 owners.uses_root = True
217 def is_protected(argv):
219 Given a single filename, return code 0 if it's protected, 1 otherwise.
220 The filename must begin with <root>.
223 sys.stderr.write("ERROR: expected 2 parameters, got %d!\n" % len(argv))
227 root, filename = argv
236 f = portage.normalize_path(filename)
237 if not f.startswith(os.path.sep):
239 err.write("ERROR: cwd does not exist!\n")
242 f = os.path.join(cwd, f)
243 f = portage.normalize_path(f)
245 if not f.startswith(root):
246 err.write("ERROR: file paths must begin with <root>!\n")
251 from portage.util import ConfigProtect
253 settings = portage.settings
254 protect = shlex.split(settings.get("CONFIG_PROTECT", ""))
255 protect_mask = shlex.split(settings.get("CONFIG_PROTECT_MASK", ""))
256 protect_obj = ConfigProtect(root, protect, protect_mask)
258 if protect_obj.isprotected(f):
262 is_protected.uses_root = True
264 def filter_protected(argv):
266 Read filenames from stdin and write them to stdout if they are protected.
267 All filenames are delimited by \\n and must begin with <root>.
270 sys.stderr.write("ERROR: expected 1 parameters, got %d!\n" % len(argv))
284 from portage.util import ConfigProtect
286 settings = portage.settings
287 protect = shlex.split(settings.get("CONFIG_PROTECT", ""))
288 protect_mask = shlex.split(settings.get("CONFIG_PROTECT_MASK", ""))
289 protect_obj = ConfigProtect(root, protect, protect_mask)
294 for line in sys.stdin:
295 filename = line.rstrip("\n")
296 f = portage.normalize_path(filename)
297 if not f.startswith(os.path.sep):
299 err.write("ERROR: cwd does not exist!\n")
303 f = os.path.join(cwd, f)
304 f = portage.normalize_path(f)
306 if not f.startswith(root):
307 err.write("ERROR: file paths must begin with <root>!\n")
312 if protect_obj.isprotected(f):
314 out.write("%s\n" % filename)
322 filter_protected.uses_root = True
324 def best_visible(argv):
325 """<root> [<category/package>]+
326 Returns category/package-version (without .ebuild).
329 print "ERROR: insufficient parameters!"
332 mylist=portage.db[argv[0]]["porttree"].dbapi.match(argv[1])
333 visible=portage.best(mylist)
341 best_visible.uses_root = True
344 def mass_best_visible(argv):
345 """<root> [<category/package>]+
346 Returns category/package-version (without .ebuild).
349 print "ERROR: insufficient parameters!"
352 for pack in argv[1:]:
353 mylist=portage.db[argv[0]]["porttree"].dbapi.match(pack)
354 print pack+":"+portage.best(mylist)
357 mass_best_visible.uses_root = True
360 def all_best_visible(argv):
362 Returns all best_visible packages (without .ebuild).
365 print "ERROR: insufficient parameters!"
367 #print portage.db[argv[0]]["porttree"].dbapi.cp_all()
368 for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all():
369 mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
372 all_best_visible.uses_root = True
377 Returns a \\n separated list of category/package-version.
378 When given an empty string, all installed packages will
382 print "ERROR: expected 2 parameters, got %d!" % len(argv)
386 if atom_validate_strict and not portage.isvalidatom(atom):
387 portage.writemsg("ERROR: Invalid atom: '%s'\n" % atom,
390 results = portage.db[root]["vartree"].dbapi.match(atom)
392 results = portage.db[root]["vartree"].dbapi.cpv_all()
396 match.uses_root = True
401 Returns the path used for the var(installed) package database for the
402 set environment/configuration options.
405 out.write(os.path.join(portage.settings["ROOT"], portage.VDB_PATH) + "\n")
409 def gentoo_mirrors(argv):
411 Returns the mirrors set to use in the portage configuration.
413 print portage.settings["GENTOO_MIRRORS"]
418 Returns the PORTDIR path.
420 print portage.settings["PORTDIR"]
423 def config_protect(argv):
425 Returns the CONFIG_PROTECT paths.
427 print portage.settings["CONFIG_PROTECT"]
430 def config_protect_mask(argv):
432 Returns the CONFIG_PROTECT_MASK paths.
434 print portage.settings["CONFIG_PROTECT_MASK"]
437 def portdir_overlay(argv):
439 Returns the PORTDIR_OVERLAY path.
441 print portage.settings["PORTDIR_OVERLAY"]
446 Returns the PKGDIR path.
448 print portage.settings["PKGDIR"]
453 Returns the DISTDIR path.
455 print portage.settings["DISTDIR"]
460 Returns a specific environment variable as exists prior to ebuild.sh.
461 Similar to: emerge --verbose --info | egrep '^<variable>='
463 verbose = "-v" in argv
465 argv.pop(argv.index("-v"))
468 print "ERROR: insufficient parameters!"
473 print arg +"='"+ portage.settings[arg] +"'"
475 print portage.settings[arg]
479 Returns all repos with names (repo_name file) argv[0] = $ROOT
482 print "ERROR: insufficient parameters!"
484 print " ".join(portage.db[argv[0]]["porttree"].dbapi.getRepositories())
486 def get_repo_path(argv):
488 Returns the path to the repo named argv[1], argv[0] = $ROOT
491 print "ERROR: insufficient parameters!"
494 print portage.db[argv[0]]["porttree"].dbapi.getRepositoryPath(arg)
496 def list_preserved_libs(argv):
498 Print a list of libraries preserved during a package update in the form
499 package: path. Returns 0 if no preserved libraries could be found,
504 print "ERROR: wrong number of arguments"
506 mylibs = portage.db[argv[0]]["vartree"].dbapi.plib_registry.getPreservedLibs()
510 for path in mylibs[cpv]:
515 list_preserved_libs.uses_root = True
517 #-----------------------------------------------------------------------------
519 # DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
523 print ">>> Portage information query tool"
525 print ">>> Usage: portageq <command> [<option> ...]"
527 print "Available commands:"
530 # Show our commands -- we do this by scanning the functions in this
531 # file, and formatting each functions documentation.
533 commands = [x for x in globals() if x not in \
534 ("usage", "__doc__", "__name__", "main", "os", "portage", \
535 "sys", "__builtins__", "types", "string","exithandler")]
538 for name in commands:
540 obj = globals()[name]
541 if (type(obj) != types.FunctionType):
547 print " MISSING DOCUMENTATION!"
551 lines = doc.split("\n")
552 print " "+name+" "+lines[0].strip()
553 if (len(sys.argv) > 1):
554 if ("--help" not in sys.argv):
556 for line in lines[1:]:
557 print " "+line.strip()
558 if (len(sys.argv) == 1):
559 print "\nRun portageq with --help for info"
561 atom_validate_strict = "EBUILD_PHASE" in os.environ
564 if "-h" in sys.argv or "--help" in sys.argv:
567 elif len(sys.argv) < 2:
569 sys.exit(os.EX_USAGE)
572 function = globals().get(cmd)
575 sys.exit(os.EX_USAGE)
576 function = globals()[cmd]
577 uses_root = getattr(function, "uses_root", False) and len(sys.argv) > 2
579 if not os.path.isdir(sys.argv[2]):
580 sys.stderr.write("Not a directory: '%s'\n" % sys.argv[2])
581 sys.stderr.write("Run portageq with --help for info\n")
583 sys.exit(os.EX_USAGE)
584 os.environ["ROOT"] = sys.argv[2]
586 # Avoid sandbox violations after python upgrade.
587 from os import path as osp
588 pym_path = osp.join(osp.dirname(
589 osp.dirname(osp.realpath(__file__))), "pym")
590 if os.environ.get("SANDBOX_ON") == "1":
591 sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":")
592 if pym_path not in sandbox_write:
593 sandbox_write.append(pym_path)
594 os.environ["SANDBOX_WRITE"] = \
595 ":".join(filter(None, sandbox_write))
601 sys.path.insert(0, pym_path)
606 sys.argv[2] = portage.settings["ROOT"]
607 retval = function(sys.argv[2:])
610 except portage.exception.PermissionDenied, e:
611 sys.stderr.write("Permission denied: '%s'\n" % str(e))
613 except portage.exception.ParseError, e:
614 sys.stderr.write("%s\n" % str(e))
616 except ValueError, e:
618 not hasattr(e.args[0], "__len__") or \
621 # Multiple matches thrown from cpv_expand
623 # An error has occurred so we writemsg to stderr and exit nonzero.
624 portage.writemsg("You specified an unqualified atom that matched multiple packages:\n", noiselevel=-1)
626 portage.writemsg("* %s\n" % pkg, noiselevel=-1)
627 portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
632 #-----------------------------------------------------------------------------