]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/runner.py
remove --multiple/-m option from all CLI commands: closes #1262
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / runner.py
1
2 import sys
3 from cStringIO import StringIO
4
5 from twisted.python import usage
6
7 from allmydata.scripts.common import BaseOptions
8 from allmydata.scripts import debug, create_node, startstop_node, cli, keygen, stats_gatherer
9 from allmydata.util.encodingutil import quote_output, get_argv_encoding
10
11 def GROUP(s):
12     # Usage.parseOptions compares argv[1] against command[0], so it will
13     # effectively ignore any "subcommand" that starts with a newline. We use
14     # these to insert section headers into the --help output.
15     return [("\n" + s, None, None, None)]
16
17
18 class Options(BaseOptions, usage.Options):
19     synopsis = "\nUsage:  tahoe <command> [command options]"
20     subCommands = ( GROUP("Administration")
21                     +   create_node.subCommands
22                     +   keygen.subCommands
23                     +   stats_gatherer.subCommands
24                     + GROUP("Controlling a node")
25                     +   startstop_node.subCommands
26                     + GROUP("Debugging")
27                     +   debug.subCommands
28                     + GROUP("Using the filesystem")
29                     +   cli.subCommands
30                     )
31
32     def getUsage(self, **kwargs):
33         t = usage.Options.getUsage(self, **kwargs)
34         return t + "\nPlease run 'tahoe <command> --help' for more details on each command.\n"
35
36     def postOptions(self):
37         if not hasattr(self, 'subOptions'):
38             raise usage.UsageError("must specify a command")
39
40
41 create_dispatch = {}
42 for module in (create_node, keygen, stats_gatherer):
43     create_dispatch.update(module.dispatch)
44
45 def runner(argv,
46            run_by_human=True,
47            stdin=None, stdout=None, stderr=None,
48            install_node_control=True, additional_commands=None):
49
50     stdin  = stdin  or sys.stdin
51     stdout = stdout or sys.stdout
52     stderr = stderr or sys.stderr
53
54     config = Options()
55     if install_node_control:
56         config.subCommands.extend(startstop_node.subCommands)
57
58     ac_dispatch = {}
59     if additional_commands:
60         for ac in additional_commands:
61             config.subCommands.extend(ac.subCommands)
62             ac_dispatch.update(ac.dispatch)
63
64     try:
65         config.parseOptions(argv)
66     except usage.error, e:
67         if not run_by_human:
68             raise
69         c = config
70         while hasattr(c, 'subOptions'):
71             c = c.subOptions
72         print >>stdout, str(c)
73         try:
74             msg = e.args[0].decode(get_argv_encoding())
75         except Exception:
76             msg = repr(e)
77         print >>stdout, "%s:  %s\n" % (sys.argv[0], quote_output(msg, quotemarks=False))
78         return 1
79
80     command = config.subCommand
81     so = config.subOptions
82
83     if config['quiet']:
84         stdout = StringIO()
85
86     so.stdout = stdout
87     so.stderr = stderr
88     so.stdin = stdin
89
90     if command in create_dispatch:
91         rc = create_dispatch[command](so, stdout, stderr)
92     elif command in startstop_node.dispatch:
93         rc = startstop_node.dispatch[command](so, stdout, stderr)
94     elif command in debug.dispatch:
95         rc = debug.dispatch[command](so)
96     elif command in cli.dispatch:
97         rc = cli.dispatch[command](so)
98     elif command in ac_dispatch:
99         rc = ac_dispatch[command](so, stdout, stderr)
100     else:
101         raise usage.UsageError()
102
103     return rc
104
105
106 def run(install_node_control=True):
107     if sys.platform == "win32":
108         from allmydata.windows.fixups import initialize
109         initialize()
110
111     rc = runner(sys.argv[1:], install_node_control=install_node_control)
112     sys.exit(rc)