Added '0install digest' command
[zeroinstall/zeroinstall-limyreth.git] / zeroinstall / cmd / __init__.py
blob91cf00f8f2e1c9a6b8b1df85710b30bc23ace683
1 """
2 The B{0install} command-line interface.
3 """
5 # Copyright (C) 2011, Thomas Leonard
6 # See the README file for details, or visit http://0install.net.
8 from zeroinstall import _
9 import os, sys
10 from optparse import OptionParser
11 import logging
13 from zeroinstall import SafeException
15 valid_commands = ['select', 'download', 'run', 'update',
16 'config', 'import', 'list', 'add-feed', 'remove-feed', 'list-feeds',
17 'digest']
19 class UsageError(Exception): pass
21 def _ensure_standard_fds():
22 "Ensure stdin, stdout and stderr FDs exist, to avoid confusion."
23 for std in (0, 1, 2):
24 try:
25 os.fstat(std)
26 except OSError:
27 fd = os.open('/dev/null', os.O_RDONLY)
28 if fd != std:
29 os.dup2(fd, std)
30 os.close(fd)
32 def _no_command(command_args):
33 """Handle --help and --version"""
34 parser = OptionParser(usage=_("usage: %prog COMMAND\n\nTry --help with one of these:") +
35 "\n\n0install " + '\n0install '.join(valid_commands))
36 parser.add_option("-V", "--version", help=_("display version information"), action='store_true')
38 (options, args) = parser.parse_args(command_args)
39 if options.version:
40 import zeroinstall
41 print "0install (zero-install) " + zeroinstall.version
42 print "Copyright (C) 2011 Thomas Leonard"
43 print _("This program comes with ABSOLUTELY NO WARRANTY,"
44 "\nto the extent permitted by law."
45 "\nYou may redistribute copies of this program"
46 "\nunder the terms of the GNU Lesser General Public License."
47 "\nFor more information about these matters, see the file named COPYING.")
48 sys.exit(0)
49 parser.print_help()
50 sys.exit(2)
52 def main(command_args, config = None):
53 """Act as if 0install was run with the given arguments.
54 @arg command_args: array of arguments (e.g. C{sys.argv[1:]})
55 @type command_args: [str]
56 """
57 _ensure_standard_fds()
59 if config is None:
60 from zeroinstall.injector.config import load_config
61 config = load_config()
63 # The first non-option argument is the command name (or "help" if none is found).
64 command = None
65 for i, arg in enumerate(command_args):
66 if not arg.startswith('-'):
67 command = arg
68 del command_args[i]
69 break
70 elif arg == '--':
71 break
73 verbose = False
74 try:
75 if command is None:
76 return _no_command(command_args)
78 if command not in valid_commands:
79 raise SafeException(_("Unknown sub-command '%s': try --help") % command)
81 # Configure a parser for the given command
82 module_name = command.replace('-', '_')
83 cmd = __import__('zeroinstall.cmd.' + module_name, globals(), locals(), [module_name], 0)
84 parser = OptionParser(usage=_("usage: %%prog %s [OPTIONS] %s") % (command, cmd.syntax))
86 parser.add_option("-c", "--console", help=_("never use GUI"), action='store_false', dest='gui')
87 parser.add_option("", "--dry-run", help=_("just print what would be executed"), action='store_true')
88 parser.add_option("-g", "--gui", help=_("show graphical policy editor"), action='store_true')
89 parser.add_option("-v", "--verbose", help=_("more verbose output"), action='count')
90 parser.add_option("", "--with-store", help=_("add an implementation cache"), action='append', metavar='DIR')
92 cmd.add_options(parser)
93 (options, args) = parser.parse_args(command_args)
95 if options.verbose:
96 logger = logging.getLogger()
97 if options.verbose == 1:
98 logger.setLevel(logging.INFO)
99 else:
100 logger.setLevel(logging.DEBUG)
101 import zeroinstall
102 logging.info(_("Running 0install %(version)s %(args)s; Python %(python_version)s"), {'version': zeroinstall.version, 'args': repr(command_args), 'python_version': sys.version})
104 if options.with_store:
105 from zeroinstall import zerostore
106 for x in options.with_store:
107 config.stores.stores.append(zerostore.Store(os.path.abspath(x)))
108 logging.info(_("Stores search path is now %s"), config.stores.stores)
110 config.handler.dry_run = bool(options.dry_run)
112 cmd.handle(config, options, args)
113 except UsageError:
114 parser.print_help()
115 sys.exit(1)
116 except SafeException as ex:
117 if verbose: raise
118 try:
119 print >>sys.stderr, unicode(ex)
120 except:
121 print >>sys.stderr, repr(ex)
122 sys.exit(1)
123 return