Updated exception handling to Python 2.6 syntax
[zeroinstall.git] / zeroinstall / injector / cli.py
blob646902aae09d1d338723e8ce31efcf87130a8fa2
1 """
2 The B{0launch} command-line interface.
4 This code is here, rather than in B{0launch} itself, simply so that it gets byte-compiled at
5 install time.
6 """
8 from zeroinstall import _
9 import os, sys
10 from optparse import OptionParser
11 import logging
13 from zeroinstall import SafeException, NeedDownload
14 from zeroinstall.injector.config import load_config
15 from zeroinstall.cmd import UsageError
17 #def program_log(msg): os.access('MARK: 0launch: ' + msg, os.F_OK)
18 #import __main__
19 #__main__.__builtins__.program_log = program_log
20 #program_log('0launch ' + ' '.join((sys.argv[1:])))
22 def main(command_args, config = None):
23 """Act as if 0launch was run with the given arguments.
24 @arg command_args: array of arguments (e.g. C{sys.argv[1:]})
25 @type command_args: [str]
26 """
27 # Ensure stdin, stdout and stderr FDs exist, to avoid confusion
28 for std in (0, 1, 2):
29 try:
30 os.fstat(std)
31 except OSError:
32 fd = os.open('/dev/null', os.O_RDONLY)
33 if fd != std:
34 os.dup2(fd, std)
35 os.close(fd)
37 parser = OptionParser(usage=_("usage: %prog [options] interface [args]\n"
38 " %prog --list [search-term]\n"
39 " %prog --import [signed-interface-files]\n"
40 " %prog --feed [interface]"))
41 parser.add_option("", "--before", help=_("choose a version before this"), metavar='VERSION')
42 parser.add_option("", "--command", help=_("command to select"), metavar='COMMAND')
43 parser.add_option("-c", "--console", help=_("never use GUI"), action='store_false', dest='gui')
44 parser.add_option("", "--cpu", help=_("target CPU type"), metavar='CPU')
45 parser.add_option("-d", "--download-only", help=_("fetch but don't run"), action='store_true')
46 parser.add_option("-D", "--dry-run", help=_("just print actions"), action='store_true')
47 parser.add_option("-f", "--feed", help=_("add or remove a feed"), action='store_true')
48 parser.add_option("", "--get-selections", help=_("write selected versions as XML"), action='store_true', dest='xml')
49 parser.add_option("-g", "--gui", help=_("show graphical policy editor"), action='store_true')
50 parser.add_option("-i", "--import", help=_("import from files, not from the network"), action='store_true')
51 parser.add_option("-l", "--list", help=_("list all known interfaces"), action='store_true')
52 parser.add_option("-m", "--main", help=_("name of the file to execute"))
53 parser.add_option("", "--message", help=_("message to display when interacting with user"))
54 parser.add_option("", "--not-before", help=_("minimum version to choose"), metavar='VERSION')
55 parser.add_option("", "--os", help=_("target operation system type"), metavar='OS')
56 parser.add_option("-o", "--offline", help=_("try to avoid using the network"), action='store_true')
57 parser.add_option("-r", "--refresh", help=_("refresh all used interfaces"), action='store_true')
58 parser.add_option("", "--select-only", help=_("only download the feeds"), action='store_true')
59 parser.add_option("", "--set-selections", help=_("run versions specified in XML file"), metavar='FILE')
60 parser.add_option("", "--show", help=_("show where components are installed"), action='store_true')
61 parser.add_option("-s", "--source", help=_("select source code"), action='store_true')
62 parser.add_option("-v", "--verbose", help=_("more verbose output"), action='count')
63 parser.add_option("-V", "--version", help=_("display version information"), action='store_true')
64 parser.add_option("", "--with-store", help=_("add an implementation cache"), action='append', metavar='DIR')
65 parser.add_option("-w", "--wrapper", help=_("execute program using a debugger, etc"), metavar='COMMAND')
66 parser.disable_interspersed_args()
68 (options, args) = parser.parse_args(command_args)
70 if options.verbose:
71 logger = logging.getLogger()
72 if options.verbose == 1:
73 logger.setLevel(logging.INFO)
74 else:
75 logger.setLevel(logging.DEBUG)
76 import zeroinstall
77 logging.info(_("Running 0launch %(version)s %(args)s; Python %(python_version)s"), {'version': zeroinstall.version, 'args': repr(args), 'python_version': sys.version})
79 if options.select_only or options.show:
80 options.download_only = True
82 if config is None:
83 config = load_config()
84 config.handler.dry_run = bool(options.dry_run)
86 if options.with_store:
87 from zeroinstall import zerostore
88 for x in options.with_store:
89 config.stores.stores.append(zerostore.Store(os.path.abspath(x)))
90 logging.info(_("Stores search path is now %s"), config.stores.stores)
92 if options.set_selections:
93 args = [options.set_selections] + args
95 try:
96 if options.list:
97 from zeroinstall.cmd import list
98 list.handle(config, options, args)
99 elif options.version:
100 import zeroinstall
101 print "0launch (zero-install) " + zeroinstall.version
102 print "Copyright (C) 2010 Thomas Leonard"
103 print _("This program comes with ABSOLUTELY NO WARRANTY,"
104 "\nto the extent permitted by law."
105 "\nYou may redistribute copies of this program"
106 "\nunder the terms of the GNU Lesser General Public License."
107 "\nFor more information about these matters, see the file named COPYING.")
108 elif getattr(options, 'import'):
109 # (import is a keyword)
110 cmd = __import__('zeroinstall.cmd.import', globals(), locals(), ["import"], 0)
111 cmd.handle(config, options, args)
112 elif options.feed:
113 from zeroinstall.cmd import add_feed
114 add_feed.handle(config, options, args, add_ok = True, remove_ok = True)
115 elif options.select_only:
116 from zeroinstall.cmd import select
117 if not options.show:
118 options.quiet = True
119 select.handle(config, options, args)
120 elif options.download_only or options.xml or options.show:
121 from zeroinstall.cmd import download
122 download.handle(config, options, args)
123 else:
124 if len(args) < 1:
125 if options.gui:
126 from zeroinstall import helpers
127 return helpers.get_selections_gui(None, [])
128 else:
129 raise UsageError()
130 else:
131 from zeroinstall.cmd import run
132 run.handle(config, options, args)
133 except NeedDownload as ex:
134 # This only happens for dry runs
135 print ex
136 except UsageError:
137 parser.print_help()
138 sys.exit(1)
139 except SafeException as ex:
140 if options.verbose: raise
141 try:
142 print >>sys.stderr, unicode(ex)
143 except:
144 print >>sys.stderr, repr(ex)
145 sys.exit(1)