streamline portage pythonpath handling and add an override analog to how the bash...
[portage.git] / bin / portageq
1 #!/usr/bin/python -O
2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 # $Id$
5
6 import sys
7 # This block ensures that ^C interrupts are handled quietly.
8 try:
9         import signal
10
11         def exithandler(signum, frame):
12                 signal.signal(signal.SIGINT, signal.SIG_IGN)
13                 signal.signal(signal.SIGTERM, signal.SIG_IGN)
14                 sys.exit(1)
15
16         signal.signal(signal.SIGINT, exithandler)
17         signal.signal(signal.SIGTERM, exithandler)
18
19 except KeyboardInterrupt:
20         sys.exit(1)
21
22 import os
23 sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "/usr/lib/portage/pym"))
24
25 import types,string
26
27
28 #-----------------------------------------------------------------------------
29 #
30 # To add functionality to this tool, add a function below.
31 #
32 # The format for functions is:
33 #
34 #   def function(argv):
35 #       """<list of options for this function>
36 #       <description of the function>
37 #       """
38 #       <code>
39 #
40 # "argv" is an array of the command line parameters provided after the command.
41 #
42 # Make sure you document the function in the right format.  The documentation
43 # is used to display help on the function.
44 #
45 # You do not need to add the function to any lists, this tool is introspective,
46 # and will automaticly add a command by the same name as the function!
47 #
48
49
50 def has_version(argv):
51         """<root> <category/package>
52         Return code 0 if it's available, 1 otherwise.
53         """
54         if (len(argv) < 2):
55                 print "ERROR: insufficient parameters!"
56                 sys.exit(2)
57         try:
58                 mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
59                 if mylist:
60                         sys.exit(0)
61                 else:
62                         sys.exit(1)
63         except KeyError:
64                 sys.exit(1)
65 has_version.uses_root = True
66
67
68 def best_version(argv):
69         """<root> <category/package>
70         Returns category/package-version (without .ebuild).
71         """
72         if (len(argv) < 2):
73                 print "ERROR: insufficient parameters!"
74                 sys.exit(2)
75         try:
76                 mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
77                 print portage.best(mylist)
78         except KeyError:
79                 sys.exit(1)
80 best_version.uses_root = True
81
82
83 def mass_best_version(argv):
84         """<root> [<category/package>]+
85         Returns category/package-version (without .ebuild).
86         """
87         if (len(argv) < 2):
88                 print "ERROR: insufficient parameters!"
89                 sys.exit(2)
90         try:
91                 for pack in argv[1:]:
92                         mylist=portage.db[argv[0]]["vartree"].dbapi.match(pack)
93                         print pack+":"+portage.best(mylist)
94         except KeyError:
95                 sys.exit(1)
96 mass_best_version.uses_root = True
97
98 def metadata(argv):
99         """<root> <pkgtype> <category/package> [<key>]+
100         Returns metadata values for the specified package.
101         """
102         if (len(argv) < 4):
103                 print >> sys.stderr, "ERROR: insufficient parameters!"
104                 sys.exit(2)
105
106         root, pkgtype, pkgspec = argv[0:3]
107         metakeys = argv[3:]
108         type_map = {
109                 "ebuild":"porttree",
110                 "binary":"bintree",
111                 "installed":"vartree"}
112         if pkgtype not in type_map:
113                 print >> sys.stderr, "Unrecognized package type: '%s'" % pkgtype
114                 sys.exit(1)
115         trees = portage.db
116         if os.path.realpath(root) == os.path.realpath(portage.settings["ROOT"]):
117                 root = portage.settings["ROOT"] # contains the normalized $ROOT
118         try:
119                         values = trees[root][type_map[pkgtype]].dbapi.aux_get(
120                                 pkgspec, metakeys)
121                         for value in values:
122                                 print value
123         except KeyError:
124                 print >> sys.stderr, "Package not found: '%s'" % pkgspec
125                 sys.exit(1)
126
127 metadata.uses_root = True
128
129 def best_visible(argv):
130         """<root> [<category/package>]+
131         Returns category/package-version (without .ebuild).
132         """
133         if (len(argv) < 2):
134                 print "ERROR: insufficient parameters!"
135                 sys.exit(2)
136         try:
137                 mylist=portage.db[argv[0]]["porttree"].dbapi.match(argv[1])
138                 print portage.best(mylist)
139         except KeyError:
140                 sys.exit(1)
141 best_visible.uses_root = True
142
143
144 def mass_best_visible(argv):
145         """<root> [<category/package>]+
146         Returns category/package-version (without .ebuild).
147         """
148         if (len(argv) < 2):
149                 print "ERROR: insufficient parameters!"
150                 sys.exit(2)
151         try:
152                 for pack in argv[1:]:
153                         mylist=portage.db[argv[0]]["porttree"].dbapi.match(pack)
154                         print pack+":"+portage.best(mylist)
155         except KeyError:
156                 sys.exit(1)
157 mass_best_visible.uses_root = True
158
159
160 def all_best_visible(argv):
161         """<root>
162         Returns all best_visible packages (without .ebuild).
163         """
164         if (len(argv) < 1):
165                 print "ERROR: insufficient parameters!"
166         
167         #print portage.db[argv[0]]["porttree"].dbapi.cp_all()
168         for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all():
169                 mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
170                 if mybest:
171                         print mybest
172 all_best_visible.uses_root = True
173
174
175 def match(argv):
176         """<root> <category/package>
177         Returns \n seperated list of category/package-version
178         """
179         if (len(argv) < 2):
180                 print "ERROR: insufficient parameters!"
181                 sys.exit(2)
182         try:
183                 print string.join(portage.db[argv[0]]["vartree"].dbapi.match(argv[1]),"\n")
184         except ValueError, e:
185                 # Multiple matches thrown from cpv_expand
186                 pkgs = e.args[0]
187                 # An error has occurred so we writemsg to stderr and exit nonzero.
188                 portage.writemsg("The following packages available:\n", noiselevel=-1)
189                 for pkg in pkgs:
190                         portage.writemsg("* %s\n" % pkg, noiselevel=-1)
191                 portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
192                 sys.exit(1)
193         except KeyError, e:
194                 portage.writemsg("%s\n" % str(e), noiselevel=-1)
195                 sys.exit(1)
196 match.uses_root = True
197
198
199 def vdb_path(argv):
200         """
201         Returns the path used for the var(installed) package database for the
202         set environment/configuration options.
203         """
204         print portage.root+portage.VDB_PATH
205
206
207 def gentoo_mirrors(argv):
208         """
209         Returns the mirrors set to use in the portage configuration.
210         """
211         print portage.settings["GENTOO_MIRRORS"]
212
213
214 def portdir(argv):
215         """
216         Returns the PORTDIR path.
217         """
218         print portage.settings["PORTDIR"]
219
220
221 def config_protect(argv):
222         """
223         Returns the CONFIG_PROTECT paths.
224         """
225         print portage.settings["CONFIG_PROTECT"]
226
227
228 def config_protect_mask(argv):
229         """
230         Returns the CONFIG_PROTECT_MASK paths.
231         """
232         print portage.settings["CONFIG_PROTECT_MASK"]
233
234
235 def portdir_overlay(argv):
236         """
237         Returns the PORTDIR_OVERLAY path.
238         """
239         print portage.settings["PORTDIR_OVERLAY"]
240
241
242 def pkgdir(argv):
243         """
244         Returns the PKGDIR path.
245         """
246         print portage.settings["PKGDIR"]
247
248
249 def distdir(argv):
250         """
251         Returns the DISTDIR path.
252         """
253         print portage.settings["DISTDIR"]
254
255
256 def envvar(argv):
257         """<variable>+
258         Returns a specific environment variable as exists prior to ebuild.sh.
259         Similar to: emerge --verbose --info | egrep '^<variable>='
260         """
261         verbose = "-v" in argv
262         if verbose:
263                 argv.pop(argv.index("-v"))
264
265         if len(argv) == 0:
266                 print "ERROR: insufficient parameters!"
267                 sys.exit(2)
268
269         for arg in argv:
270                 if verbose:
271                         print arg +"='"+ portage.settings[arg] +"'"
272                 else:
273                         print portage.settings[arg]
274
275
276 #-----------------------------------------------------------------------------
277 #
278 # DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
279 #
280
281 def usage(argv):
282         rev="$Revision: 1.13.2.1 $"
283         ver=string.split(rev, ' ')[1]
284         print ">>> Portage information query tool -- version "+ver
285         print ">>> Usage: portageq <command> [<option> ...]"
286         print ""
287         print "Available commands:"
288
289         #
290         # Show our commands -- we do this by scanning the functions in this
291         # file, and formatting each functions documentation.
292         #
293         for name in globals().keys():
294                 # Drop python stuff, modules, and our own support functions.
295                 if (name in ("usage", "__doc__", "__name__", "main", "os", "portage", "sys", "__builtins__", "types", "string")):
296                         continue
297
298                 # Drop non-functions
299                 obj = globals()[name]
300                 if  (type(obj) != types.FunctionType):
301                         continue
302
303                 doc = obj.__doc__
304                 if (doc == None):
305                         print "   "+name
306                         print "      MISSING DOCUMENTATION!"
307                         print ""
308                         continue
309
310                 lines = string.split(doc, '\n')
311                 print "   "+name+" "+string.strip(lines[0])
312                 if (len(sys.argv) > 1):
313                         if ("--help" not in sys.argv):
314                                 lines = lines[:-1]
315                         for line in lines[1:]:
316                                 print "      "+string.strip(line)
317         if (len(sys.argv) == 1):
318                 print "\nRun portageq with --help for info"
319
320 def main():
321         if "-h" in sys.argv or "--help" in sys.argv:
322                 usage(sys.argv)
323                 sys.exit(os.EX_OK)
324         elif len(sys.argv) < 2:
325                 usage(sys.argv)
326                 sys.exit(os.EX_USAGE)
327
328         cmd = sys.argv[1]
329         try:
330                 function = globals()[cmd]
331                 uses_root = (getattr(function, "uses_root", False) and len(sys.argv) > 2)
332                 if uses_root:
333                         os.environ["ROOT"] = sys.argv[2]
334                 global portage
335                 import portage
336                 if uses_root:
337                         sys.argv[2] = portage.root
338                 function(sys.argv[2:])
339         except KeyError:
340                 usage(sys.argv)
341                 sys.exit(os.EX_USAGE)
342
343 main()
344
345 #-----------------------------------------------------------------------------