#!/usr/bin/python -O
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Id$
+
+from __future__ import print_function
import sys
# This block ensures that ^C interrupts are handled quietly.
sys.exit(1)
import os
-sys.path = ["/usr/lib/portage/pym"]+sys.path
-import types,string
+import types
+
+# Avoid sandbox violations after python upgrade.
+pym_path = os.path.join(os.path.dirname(
+ os.path.dirname(os.path.realpath(__file__))), "pym")
+if os.environ.get("SANDBOX_ON") == "1":
+ sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":")
+ if pym_path not in sandbox_write:
+ sandbox_write.append(pym_path)
+ os.environ["SANDBOX_WRITE"] = \
+ ":".join(filter(None, sandbox_write))
+ del sandbox_write
+
+try:
+ import portage
+except ImportError:
+ sys.path.insert(0, pym_path)
+ import portage
+del pym_path
+
+from portage import os
+from portage.util import writemsg, writemsg_stdout
+def eval_atom_use(atom):
+ if 'USE' in os.environ:
+ use = frozenset(os.environ['USE'].split())
+ atom = atom.evaluate_conditionals(use)
+ return atom
#-----------------------------------------------------------------------------
#
# and will automaticly add a command by the same name as the function!
#
-
def has_version(argv):
"""<root> <category/package>
Return code 0 if it's available, 1 otherwise.
"""
if (len(argv) < 2):
- print "ERROR: insufficient parameters!"
+ print("ERROR: insufficient parameters!")
sys.exit(2)
try:
- mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
+ atom = portage.dep.Atom(argv[1])
+ except portage.exception.InvalidAtom:
+ if atom_validate_strict:
+ portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
+ noiselevel=-1)
+ return 2
+ else:
+ atom = argv[1]
+ else:
+ atom = eval_atom_use(atom)
+
+ try:
+ mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom)
if mylist:
sys.exit(0)
else:
sys.exit(1)
except KeyError:
sys.exit(1)
+ except portage.exception.InvalidAtom:
+ portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
+ noiselevel=-1)
+ return 2
has_version.uses_root = True
Returns category/package-version (without .ebuild).
"""
if (len(argv) < 2):
- print "ERROR: insufficient parameters!"
+ print("ERROR: insufficient parameters!")
sys.exit(2)
try:
- mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
- print portage.best(mylist)
+ atom = portage.dep.Atom(argv[1])
+ except portage.exception.InvalidAtom:
+ if atom_validate_strict:
+ portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
+ noiselevel=-1)
+ return 2
+ else:
+ atom = argv[1]
+ else:
+ atom = eval_atom_use(atom)
+ try:
+ mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom)
+ print(portage.best(mylist))
except KeyError:
sys.exit(1)
best_version.uses_root = True
Returns category/package-version (without .ebuild).
"""
if (len(argv) < 2):
- print "ERROR: insufficient parameters!"
+ print("ERROR: insufficient parameters!")
sys.exit(2)
try:
for pack in argv[1:]:
mylist=portage.db[argv[0]]["vartree"].dbapi.match(pack)
- print pack+":"+portage.best(mylist)
+ print(pack+":"+portage.best(mylist))
except KeyError:
sys.exit(1)
mass_best_version.uses_root = True
def metadata(argv):
- """<root> <pkgtype> <category/package> [<key>]+
- Returns metadata values for the specified package.
- """
if (len(argv) < 4):
- print >> sys.stderr, "ERROR: insufficient parameters!"
+ print("ERROR: insufficient parameters!", file=sys.stderr)
sys.exit(2)
root, pkgtype, pkgspec = argv[0:3]
"binary":"bintree",
"installed":"vartree"}
if pkgtype not in type_map:
- print >> sys.stderr, "Unrecognized package type: '%s'" % pkgtype
+ print("Unrecognized package type: '%s'" % pkgtype, file=sys.stderr)
sys.exit(1)
trees = portage.db
if os.path.realpath(root) == os.path.realpath(portage.settings["ROOT"]):
try:
values = trees[root][type_map[pkgtype]].dbapi.aux_get(
pkgspec, metakeys)
- for value in values:
- print value
+ writemsg_stdout(''.join('%s\n' % x for x in values), noiselevel=-1)
except KeyError:
- print >> sys.stderr, "Package not found: '%s'" % pkgspec
+ print("Package not found: '%s'" % pkgspec, file=sys.stderr)
sys.exit(1)
+metadata.__doc__ = """
+<root> <pkgtype> <category/package> [<key>]+
+Returns metadata values for the specified package.
+Available keys: %s
+""" % ','.join(sorted(x for x in portage.auxdbkeys \
+if not x.startswith('UNUSED_')))
+
metadata.uses_root = True
+def contents(argv):
+ """<root> <category/package>
+ List the files that are installed for a given package, with
+ one file listed on each line. All file names will begin with
+ <root>.
+ """
+ if len(argv) != 2:
+ print("ERROR: expected 2 parameters, got %d!" % len(argv))
+ return 2
+
+ root, cpv = argv
+ vartree = portage.db[root]["vartree"]
+ if not vartree.dbapi.cpv_exists(cpv):
+ sys.stderr.write("Package not found: '%s'\n" % cpv)
+ return 1
+ cat, pkg = portage.catsplit(cpv)
+ db = portage.dblink(cat, pkg, root, vartree.settings,
+ treetype="vartree", vartree=vartree)
+ writemsg_stdout(''.join('%s\n' % x for x in sorted(db.getcontents())),
+ noiselevel=-1)
+contents.uses_root = True
+
+def owners(argv):
+ """<root> [<filename>]+
+ Given a list of files, print the packages that own the files and which
+ files belong to each package. Files owned by a package are listed on
+ the lines below it, indented by a single tab character (\\t). All file
+ paths must either start with <root> or be a basename alone.
+ Returns 1 if no owners could be found, and 0 otherwise.
+ """
+ if len(argv) < 2:
+ sys.stderr.write("ERROR: insufficient parameters!\n")
+ sys.stderr.flush()
+ return 2
+
+ from portage import catsplit, dblink
+ settings = portage.settings
+ root = settings["ROOT"]
+ vardb = portage.db[root]["vartree"].dbapi
+
+ cwd = None
+ try:
+ cwd = os.getcwd()
+ except OSError:
+ pass
+
+ files = []
+ for f in argv[1:]:
+ f = portage.normalize_path(f)
+ is_basename = os.sep not in f
+ if not is_basename and f[:1] != os.sep:
+ if cwd is None:
+ sys.stderr.write("ERROR: cwd does not exist!\n")
+ sys.stderr.flush()
+ return 2
+ f = os.path.join(cwd, f)
+ f = portage.normalize_path(f)
+ if not is_basename and not f.startswith(root):
+ sys.stderr.write("ERROR: file paths must begin with <root>!\n")
+ sys.stderr.flush()
+ return 2
+ if is_basename:
+ files.append(f)
+ else:
+ files.append(f[len(root)-1:])
+
+ owners = vardb._owners.get_owners(files)
+
+ msg = []
+ for pkg, owned_files in owners.items():
+ cpv = pkg.mycpv
+ msg.append("%s\n" % cpv)
+ for f in sorted(owned_files):
+ msg.append("\t%s\n" % \
+ os.path.join(root, f.lstrip(os.path.sep)))
+
+ writemsg_stdout(''.join(msg), noiselevel=-1)
+
+ if owners:
+ return 0
+
+ sys.stderr.write("None of the installed packages claim the file(s).\n")
+ sys.stderr.flush()
+ return 1
+
+owners.uses_root = True
+
+def is_protected(argv):
+ """<root> <filename>
+ Given a single filename, return code 0 if it's protected, 1 otherwise.
+ The filename must begin with <root>.
+ """
+ if len(argv) != 2:
+ sys.stderr.write("ERROR: expected 2 parameters, got %d!\n" % len(argv))
+ sys.stderr.flush()
+ return 2
+
+ root, filename = argv
+
+ err = sys.stderr
+ cwd = None
+ try:
+ cwd = os.getcwd()
+ except OSError:
+ pass
+
+ f = portage.normalize_path(filename)
+ if not f.startswith(os.path.sep):
+ if cwd is None:
+ err.write("ERROR: cwd does not exist!\n")
+ err.flush()
+ return 2
+ f = os.path.join(cwd, f)
+ f = portage.normalize_path(f)
+
+ if not f.startswith(root):
+ err.write("ERROR: file paths must begin with <root>!\n")
+ err.flush()
+ return 2
+
+ from portage.util import ConfigProtect
+
+ settings = portage.settings
+ protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
+ protect_mask = portage.util.shlex_split(
+ settings.get("CONFIG_PROTECT_MASK", ""))
+ protect_obj = ConfigProtect(root, protect, protect_mask)
+
+ if protect_obj.isprotected(f):
+ return 0
+ return 1
+
+is_protected.uses_root = True
+
+def filter_protected(argv):
+ """<root>
+ Read filenames from stdin and write them to stdout if they are protected.
+ All filenames are delimited by \\n and must begin with <root>.
+ """
+ if len(argv) != 1:
+ sys.stderr.write("ERROR: expected 1 parameter, got %d!\n" % len(argv))
+ sys.stderr.flush()
+ return 2
+
+ root, = argv
+ out = sys.stdout
+ err = sys.stderr
+ cwd = None
+ try:
+ cwd = os.getcwd()
+ except OSError:
+ pass
+
+ from portage.util import ConfigProtect
+
+ settings = portage.settings
+ protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
+ protect_mask = portage.util.shlex_split(
+ settings.get("CONFIG_PROTECT_MASK", ""))
+ protect_obj = ConfigProtect(root, protect, protect_mask)
+
+ protected = 0
+ errors = 0
+
+ for line in sys.stdin:
+ filename = line.rstrip("\n")
+ f = portage.normalize_path(filename)
+ if not f.startswith(os.path.sep):
+ if cwd is None:
+ err.write("ERROR: cwd does not exist!\n")
+ err.flush()
+ errors += 1
+ continue
+ f = os.path.join(cwd, f)
+ f = portage.normalize_path(f)
+
+ if not f.startswith(root):
+ err.write("ERROR: file paths must begin with <root>!\n")
+ err.flush()
+ errors += 1
+ continue
+
+ if protect_obj.isprotected(f):
+ protected += 1
+ out.write("%s\n" % filename)
+ out.flush()
+
+ if errors:
+ return 2
+
+ return 0
+
+filter_protected.uses_root = True
+
def best_visible(argv):
"""<root> [<category/package>]+
Returns category/package-version (without .ebuild).
"""
if (len(argv) < 2):
- print "ERROR: insufficient parameters!"
+ print("ERROR: insufficient parameters!")
sys.exit(2)
try:
mylist=portage.db[argv[0]]["porttree"].dbapi.match(argv[1])
- print portage.best(mylist)
+ visible=portage.best(mylist)
+ if visible:
+ print(visible)
+ sys.exit(0)
+ else:
+ sys.exit(1)
except KeyError:
sys.exit(1)
best_visible.uses_root = True
Returns category/package-version (without .ebuild).
"""
if (len(argv) < 2):
- print "ERROR: insufficient parameters!"
+ print("ERROR: insufficient parameters!")
sys.exit(2)
try:
for pack in argv[1:]:
mylist=portage.db[argv[0]]["porttree"].dbapi.match(pack)
- print pack+":"+portage.best(mylist)
+ print(pack+":"+portage.best(mylist))
except KeyError:
sys.exit(1)
mass_best_visible.uses_root = True
Returns all best_visible packages (without .ebuild).
"""
if (len(argv) < 1):
- print "ERROR: insufficient parameters!"
+ print("ERROR: insufficient parameters!")
#print portage.db[argv[0]]["porttree"].dbapi.cp_all()
for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all():
mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
if mybest:
- print mybest
+ print(mybest)
all_best_visible.uses_root = True
def match(argv):
- """<root> <category/package>
- Returns \n seperated list of category/package-version
+ """<root> <atom>
+ Returns a \\n separated list of category/package-version.
+ When given an empty string, all installed packages will
+ be listed.
"""
- if (len(argv) < 2):
- print "ERROR: insufficient parameters!"
+ if len(argv) != 2:
+ print("ERROR: expected 2 parameters, got %d!" % len(argv))
sys.exit(2)
- try:
- print string.join(portage.db[argv[0]]["vartree"].dbapi.match(argv[1]),"\n")
- except ValueError, e:
- # Multiple matches thrown from cpv_expand
- pkgs = e.args[0]
- # An error has occurred so we writemsg to stderr and exit nonzero.
- portage.writemsg("The following packages available:\n", noiselevel=-1)
- for pkg in pkgs:
- portage.writemsg("* %s\n" % pkg, noiselevel=-1)
- portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
- sys.exit(1)
- except KeyError, e:
- portage.writemsg("%s\n" % str(e), noiselevel=-1)
- sys.exit(1)
+ root, atom = argv
+ if atom:
+ if atom_validate_strict and not portage.isvalidatom(atom):
+ portage.writemsg("ERROR: Invalid atom: '%s'\n" % atom,
+ noiselevel=-1)
+ return 2
+ results = portage.db[root]["vartree"].dbapi.match(atom)
+ else:
+ results = portage.db[root]["vartree"].dbapi.cpv_all()
+ results.sort()
+ for cpv in results:
+ print(cpv)
match.uses_root = True
Returns the path used for the var(installed) package database for the
set environment/configuration options.
"""
- print portage.root+portage.VDB_PATH
-
+ out = sys.stdout
+ out.write(os.path.join(portage.settings["ROOT"], portage.VDB_PATH) + "\n")
+ out.flush()
+ return os.EX_OK
def gentoo_mirrors(argv):
"""
Returns the mirrors set to use in the portage configuration.
"""
- print portage.settings["GENTOO_MIRRORS"]
+ print(portage.settings["GENTOO_MIRRORS"])
def portdir(argv):
"""
Returns the PORTDIR path.
"""
- print portage.settings["PORTDIR"]
+ print(portage.settings["PORTDIR"])
def config_protect(argv):
"""
Returns the CONFIG_PROTECT paths.
"""
- print portage.settings["CONFIG_PROTECT"]
+ print(portage.settings["CONFIG_PROTECT"])
def config_protect_mask(argv):
"""
Returns the CONFIG_PROTECT_MASK paths.
"""
- print portage.settings["CONFIG_PROTECT_MASK"]
+ print(portage.settings["CONFIG_PROTECT_MASK"])
def portdir_overlay(argv):
"""
Returns the PORTDIR_OVERLAY path.
"""
- print portage.settings["PORTDIR_OVERLAY"]
+ print(portage.settings["PORTDIR_OVERLAY"])
def pkgdir(argv):
"""
Returns the PKGDIR path.
"""
- print portage.settings["PKGDIR"]
+ print(portage.settings["PKGDIR"])
def distdir(argv):
"""
Returns the DISTDIR path.
"""
- print portage.settings["DISTDIR"]
+ print(portage.settings["DISTDIR"])
def envvar(argv):
argv.pop(argv.index("-v"))
if len(argv) == 0:
- print "ERROR: insufficient parameters!"
+ print("ERROR: insufficient parameters!")
sys.exit(2)
for arg in argv:
if verbose:
- print arg +"='"+ portage.settings[arg] +"'"
+ print(arg +"='"+ portage.settings[arg] +"'")
else:
- print portage.settings[arg]
+ print(portage.settings[arg])
+def get_repos(argv):
+ """<root>
+ Returns all repos with names (repo_name file) argv[0] = $ROOT
+ """
+ if len(argv) < 1:
+ print("ERROR: insufficient parameters!")
+ sys.exit(2)
+ print(" ".join(portage.db[argv[0]]["porttree"].dbapi.getRepositories()))
+
+def get_repo_path(argv):
+ """<root> <repo_id>+
+ Returns the path to the repo named argv[1], argv[0] = $ROOT
+ """
+ if len(argv) < 2:
+ print("ERROR: insufficient parameters!")
+ sys.exit(2)
+ for arg in argv[1:]:
+ print(portage.db[argv[0]]["porttree"].dbapi.getRepositoryPath(arg))
+
+def list_preserved_libs(argv):
+ """<root>
+ Print a list of libraries preserved during a package update in the form
+ package: path. Returns 0 if no preserved libraries could be found,
+ 1 otherwise.
+ """
+
+ if len(argv) != 1:
+ print("ERROR: wrong number of arguments")
+ sys.exit(2)
+ mylibs = portage.db[argv[0]]["vartree"].dbapi._plib_registry.getPreservedLibs()
+ rValue = 0
+ msg = []
+ for cpv in sorted(mylibs):
+ msg.append(cpv)
+ for path in mylibs[cpv]:
+ msg.append(' ' + path)
+ rValue = 1
+ msg.append('\n')
+ writemsg_stdout(''.join(msg), noiselevel=-1)
+ return rValue
+list_preserved_libs.uses_root = True
#-----------------------------------------------------------------------------
#
# DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
#
+if not portage.const._ENABLE_PRESERVE_LIBS:
+ del list_preserved_libs
+
+non_commands = frozenset(['eval_atom_use', 'exithandler', 'main',
+ 'usage', 'writemsg', 'writemsg_stdout'])
+commands = sorted(k for k, v in globals().items() \
+ if type(v) is types.FunctionType and k not in non_commands)
+
def usage(argv):
- rev="$Revision: 1.13.2.1 $"
- ver=string.split(rev, ' ')[1]
- print ">>> Portage information query tool -- version "+ver
- print ">>> Usage: portageq <command> [<option> ...]"
- print ""
- print "Available commands:"
+ print(">>> Portage information query tool")
+ print(">>> %s" % portage.VERSION)
+ print(">>> Usage: portageq <command> [<option> ...]")
+ print("")
+ print("Available commands:")
#
# Show our commands -- we do this by scanning the functions in this
# file, and formatting each functions documentation.
#
- for name in globals().keys():
- # Drop python stuff, modules, and our own support functions.
- if (name in ("usage", "__doc__", "__name__", "main", "os", "portage", "sys", "__builtins__", "types", "string")):
- continue
-
+ help_mode = '--help' in sys.argv
+ for name in commands:
# Drop non-functions
obj = globals()[name]
- if (type(obj) != types.FunctionType):
- continue
doc = obj.__doc__
if (doc == None):
- print " "+name
- print " MISSING DOCUMENTATION!"
- print ""
+ print(" " + name)
+ print(" MISSING DOCUMENTATION!")
+ print("")
continue
- lines = string.split(doc, '\n')
- print " "+name+" "+string.strip(lines[0])
+ lines = doc.split("\n")
+ print(" " + name + " " + lines[0].strip())
if (len(sys.argv) > 1):
- if ("--help" not in sys.argv):
+ if (not help_mode):
lines = lines[:-1]
for line in lines[1:]:
- print " "+string.strip(line)
+ print(" " + line.strip())
if (len(sys.argv) == 1):
- print "\nRun portageq with --help for info"
+ print("\nRun portageq with --help for info")
+
+atom_validate_strict = "EBUILD_PHASE" in os.environ
def main():
if "-h" in sys.argv or "--help" in sys.argv:
sys.exit(os.EX_USAGE)
cmd = sys.argv[1]
- try:
- function = globals()[cmd]
- uses_root = (getattr(function, "uses_root", False) and len(sys.argv) > 2)
- if uses_root:
- os.environ["ROOT"] = sys.argv[2]
- global portage
- import portage
- if uses_root:
- sys.argv[2] = portage.root
- function(sys.argv[2:])
- except KeyError:
+ function = globals().get(cmd)
+ if function is None or cmd not in commands:
usage(sys.argv)
sys.exit(os.EX_USAGE)
+ function = globals()[cmd]
+ uses_root = getattr(function, "uses_root", False) and len(sys.argv) > 2
+ if uses_root:
+ if not os.path.isdir(sys.argv[2]):
+ sys.stderr.write("Not a directory: '%s'\n" % sys.argv[2])
+ sys.stderr.write("Run portageq with --help for info\n")
+ sys.stderr.flush()
+ sys.exit(os.EX_USAGE)
+ os.environ["ROOT"] = sys.argv[2]
+
+ args = sys.argv[2:]
+ if args and sys.hexversion < 0x3000000 and not isinstance(args[0], unicode):
+ for i in range(len(args)):
+ args[i] = portage._unicode_decode(args[i])
+
+ try:
+ if uses_root:
+ args[0] = portage.settings["ROOT"]
+ retval = function(args)
+ if retval:
+ sys.exit(retval)
+ except portage.exception.PermissionDenied as e:
+ sys.stderr.write("Permission denied: '%s'\n" % str(e))
+ sys.exit(e.errno)
+ except portage.exception.ParseError as e:
+ sys.stderr.write("%s\n" % str(e))
+ sys.exit(1)
+ except portage.exception.AmbiguousPackageName as e:
+ # Multiple matches thrown from cpv_expand
+ pkgs = e.args[0]
+ # An error has occurred so we writemsg to stderr and exit nonzero.
+ portage.writemsg("You specified an unqualified atom that matched multiple packages:\n", noiselevel=-1)
+ for pkg in pkgs:
+ portage.writemsg("* %s\n" % pkg, noiselevel=-1)
+ portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
+ sys.exit(1)
main()