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!"
55 mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
62 has_version.uses_root = True
65 def best_version(argv):
66 """<root> <category/package>
67 Returns category/package-version (without .ebuild).
70 print "ERROR: insufficient parameters!"
73 mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
74 print portage.best(mylist)
77 best_version.uses_root = True
80 def mass_best_version(argv):
81 """<root> [<category/package>]+
82 Returns category/package-version (without .ebuild).
85 print "ERROR: insufficient parameters!"
89 mylist=portage.db[argv[0]]["vartree"].dbapi.match(pack)
90 print pack+":"+portage.best(mylist)
93 mass_best_version.uses_root = True
96 """<root> <pkgtype> <category/package> [<key>]+
97 Returns metadata values for the specified package.
100 print >> sys.stderr, "ERROR: insufficient parameters!"
103 root, pkgtype, pkgspec = argv[0:3]
108 "installed":"vartree"}
109 if pkgtype not in type_map:
110 print >> sys.stderr, "Unrecognized package type: '%s'" % pkgtype
113 if os.path.realpath(root) == os.path.realpath(portage.settings["ROOT"]):
114 root = portage.settings["ROOT"] # contains the normalized $ROOT
116 values = trees[root][type_map[pkgtype]].dbapi.aux_get(
121 print >> sys.stderr, "Package not found: '%s'" % pkgspec
124 metadata.uses_root = True
127 """<root> <category/package>
128 List the files that are installed for a given package, with
129 one file listed on each line. All file names will begin with
133 print "ERROR: expected 2 parameters, got %d!" % len(argv)
137 vartree = portage.db[root]["vartree"]
138 if not vartree.dbapi.cpv_exists(cpv):
139 sys.stderr.write("Package not found: '%s'\n" % cpv)
141 cat, pkg = portage.catsplit(cpv)
142 db = portage.dblink(cat, pkg, root, vartree.settings,
143 treetype="vartree", vartree=vartree)
144 file_list = db.getcontents().keys()
147 sys.stdout.write("%s\n" % f)
149 contents.uses_root = True
152 """<root> [<filename>]+
153 Given a list of files, print the packages that own the files and which
154 files belong to each package. Files owned by a package are listed on
155 the lines below it, indented by a single tab character (\\t). All file
156 paths must start with <root>. Returns 1 if no owners could be found,
160 sys.stderr.write("ERROR: insufficient parameters!\n")
164 from portage import catsplit, dblink
165 settings = portage.settings
166 root = settings["ROOT"]
167 vardb = portage.db[root]["vartree"].dbapi
177 f = portage.normalize_path(f)
178 if not f.startswith(os.path.sep):
180 sys.stderr.write("ERROR: cwd does not exist!\n")
183 f = os.path.join(cwd, f)
184 f = portage.normalize_path(f)
185 if not f.startswith(root):
186 sys.stderr.write("ERROR: file paths must begin with <root>!\n")
189 files.append(f[len(root):])
191 owners = vardb._owners.get_owners(files)
193 for pkg, owned_files in owners.iteritems():
195 sys.stdout.write("%s\n" % cpv)
196 for f in sorted(owned_files):
197 sys.stdout.write("\t%s\n" % \
198 os.path.join(root, f.lstrip(os.path.sep)))
203 sys.stderr.write("None of the installed packages claim the file(s).\n")
207 owners.uses_root = True
209 def best_visible(argv):
210 """<root> [<category/package>]+
211 Returns category/package-version (without .ebuild).
214 print "ERROR: insufficient parameters!"
217 mylist=portage.db[argv[0]]["porttree"].dbapi.match(argv[1])
218 visible=portage.best(mylist)
226 best_visible.uses_root = True
229 def mass_best_visible(argv):
230 """<root> [<category/package>]+
231 Returns category/package-version (without .ebuild).
234 print "ERROR: insufficient parameters!"
237 for pack in argv[1:]:
238 mylist=portage.db[argv[0]]["porttree"].dbapi.match(pack)
239 print pack+":"+portage.best(mylist)
242 mass_best_visible.uses_root = True
245 def all_best_visible(argv):
247 Returns all best_visible packages (without .ebuild).
250 print "ERROR: insufficient parameters!"
252 #print portage.db[argv[0]]["porttree"].dbapi.cp_all()
253 for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all():
254 mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
257 all_best_visible.uses_root = True
262 Returns a \\n separated list of category/package-version.
263 When given an empty string, all installed packages will
267 print "ERROR: expected 2 parameters, got %d!" % len(argv)
271 results = portage.db[root]["vartree"].dbapi.match(atom)
273 results = portage.db[root]["vartree"].dbapi.cpv_all()
277 match.uses_root = True
282 Returns the path used for the var(installed) package database for the
283 set environment/configuration options.
285 print portage.root+portage.VDB_PATH
288 def gentoo_mirrors(argv):
290 Returns the mirrors set to use in the portage configuration.
292 print portage.settings["GENTOO_MIRRORS"]
297 Returns the PORTDIR path.
299 print portage.settings["PORTDIR"]
302 def config_protect(argv):
304 Returns the CONFIG_PROTECT paths.
306 print portage.settings["CONFIG_PROTECT"]
309 def config_protect_mask(argv):
311 Returns the CONFIG_PROTECT_MASK paths.
313 print portage.settings["CONFIG_PROTECT_MASK"]
316 def portdir_overlay(argv):
318 Returns the PORTDIR_OVERLAY path.
320 print portage.settings["PORTDIR_OVERLAY"]
325 Returns the PKGDIR path.
327 print portage.settings["PKGDIR"]
332 Returns the DISTDIR path.
334 print portage.settings["DISTDIR"]
339 Returns a specific environment variable as exists prior to ebuild.sh.
340 Similar to: emerge --verbose --info | egrep '^<variable>='
342 verbose = "-v" in argv
344 argv.pop(argv.index("-v"))
347 print "ERROR: insufficient parameters!"
352 print arg +"='"+ portage.settings[arg] +"'"
354 print portage.settings[arg]
358 Returns all repos with names (repo_name file) argv[0] = $ROOT
361 print "ERROR: insufficient parameters!"
363 print " ".join(portage.db[argv[0]]["porttree"].dbapi.getRepositories())
365 def get_repo_path(argv):
367 Returns the path to the repo named argv[1], argv[0] = $ROOT
370 print "ERROR: insufficient parameters!"
373 print portage.db[argv[0]]["porttree"].dbapi.getRepositoryPath(argv[1])
375 def list_preserved_libs(argv):
377 Print a list of libraries preserved during a package update in the form
378 package: path. Returns 0 if no preserved libraries could be found,
383 print "ERROR: wrong number of arguments"
385 mylibs = portage.db[argv[0]]["vartree"].dbapi.plib_registry.getPreservedLibs()
389 for path in mylibs[cpv]:
394 list_preserved_libs.uses_root = True
396 #-----------------------------------------------------------------------------
398 # DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
402 print ">>> Portage information query tool"
404 print ">>> Usage: portageq <command> [<option> ...]"
406 print "Available commands:"
409 # Show our commands -- we do this by scanning the functions in this
410 # file, and formatting each functions documentation.
412 commands = [x for x in globals() if x not in \
413 ("usage", "__doc__", "__name__", "main", "os", "portage", \
414 "sys", "__builtins__", "types", "string","exithandler")]
417 for name in commands:
419 obj = globals()[name]
420 if (type(obj) != types.FunctionType):
426 print " MISSING DOCUMENTATION!"
430 lines = doc.split("\n")
431 print " "+name+" "+lines[0].strip()
432 if (len(sys.argv) > 1):
433 if ("--help" not in sys.argv):
435 for line in lines[1:]:
436 print " "+line.strip()
437 if (len(sys.argv) == 1):
438 print "\nRun portageq with --help for info"
441 if "-h" in sys.argv or "--help" in sys.argv:
444 elif len(sys.argv) < 2:
446 sys.exit(os.EX_USAGE)
449 function = globals().get(cmd)
452 sys.exit(os.EX_USAGE)
453 function = globals()[cmd]
454 uses_root = getattr(function, "uses_root", False) and len(sys.argv) > 2
456 if not os.path.isdir(sys.argv[2]):
457 sys.stderr.write("Not a directory: '%s'\n" % sys.argv[2])
458 sys.stderr.write("Run portageq with --help for info\n")
460 sys.exit(os.EX_USAGE)
461 os.environ["ROOT"] = sys.argv[2]
465 # First import the main portage module without legacy globals since it
466 # is almost certain to succeed in that case. This provides access to
467 # the portage.exception namespace which is needed for later exception
468 # handling, like if portage.exception.PermissionDenied is raised when
469 # constructing the legacy global config instance.
470 os.environ["PORTAGE_LEGACY_GLOBALS"] = "false"
472 del os.environ["PORTAGE_LEGACY_GLOBALS"]
477 from os import path as osp
478 sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
481 sys.argv[2] = portage.root
482 retval = function(sys.argv[2:])
485 except portage.exception.PermissionDenied, e:
486 sys.stderr.write("Permission denied: '%s'\n" % str(e))
488 except portage.exception.ParseError, e:
489 sys.stderr.write("%s\n" % str(e))
491 except ValueError, e:
493 not hasattr(e.args[0], "__len__") or \
496 # Multiple matches thrown from cpv_expand
498 # An error has occurred so we writemsg to stderr and exit nonzero.
499 portage.writemsg("You specified an unqualified atom that matched multiple packages:\n", noiselevel=-1)
501 portage.writemsg("* %s\n" % pkg, noiselevel=-1)
502 portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
507 #-----------------------------------------------------------------------------