3 from cStringIO import StringIO
5 from twisted.python import usage
7 from allmydata.scripts.common import get_default_nodedir
8 from allmydata.scripts import debug, create_node, startstop_node, cli, keygen, stats_gatherer, \
9 admin, magic_folder_cli
10 from allmydata.util.encodingutil import quote_output, quote_local_unicode_path, get_io_encoding
13 # Usage.parseOptions compares argv[1] against command[0], so it will
14 # effectively ignore any "subcommand" that starts with a newline. We use
15 # these to insert section headers into the --help output.
16 return [("\n(%s)" % s, None, None, None)]
19 _default_nodedir = get_default_nodedir()
21 NODEDIR_HELP = ("Specify which Tahoe node directory should be used. The "
22 "directory should either contain a full Tahoe node, or a "
23 "file named node.url that points to some other Tahoe node. "
24 "It should also contain a file named '"
25 + os.path.join('private', 'aliases') +
26 "' which contains the mapping from alias name to root "
29 NODEDIR_HELP += " [default for most commands: " + quote_local_unicode_path(_default_nodedir) + "]"
31 class Options(usage.Options):
32 # unit tests can override these to point at StringIO instances
37 synopsis = "\nUsage: tahoe <command> [command options]"
38 subCommands = ( GROUP("Administration")
39 + create_node.subCommands
41 + stats_gatherer.subCommands
43 + GROUP("Controlling a node")
44 + startstop_node.subCommands
47 + GROUP("Using the filesystem")
49 + magic_folder_cli.subCommands
53 ["quiet", "q", "Operate silently."],
54 ["version", "V", "Display version numbers."],
55 ["version-and-path", None, "Display version numbers and paths to their locations."],
58 ["node-directory", "d", None, NODEDIR_HELP],
61 def opt_version(self):
63 print >>self.stdout, allmydata.get_package_versions_string(debug=True)
64 self.no_command_needed = True
66 def opt_version_and_path(self):
68 print >>self.stdout, allmydata.get_package_versions_string(show_paths=True, debug=True)
69 self.no_command_needed = True
72 return ("\nUsage: tahoe [global-options] <command> [command-options]\n"
75 synopsis = "\nUsage: tahoe [global-options]" # used only for subcommands
77 def getUsage(self, **kwargs):
78 t = usage.Options.getUsage(self, **kwargs)
79 t = t.replace("Options:", "\nGlobal options:", 1)
80 return t + "\nPlease run 'tahoe <command> --help' for more details on each command.\n"
82 def postOptions(self):
83 if not hasattr(self, 'subOptions'):
84 if not hasattr(self, 'no_command_needed'):
85 raise usage.UsageError("must specify a command")
90 for module in (create_node, keygen, stats_gatherer):
91 create_dispatch.update(module.dispatch)
95 stdin=None, stdout=None, stderr=None,
96 install_node_control=True, additional_commands=None):
98 stdin = stdin or sys.stdin
99 stdout = stdout or sys.stdout
100 stderr = stderr or sys.stderr
103 if install_node_control:
104 config.subCommands.extend(startstop_node.subCommands)
107 if additional_commands:
108 for ac in additional_commands:
109 config.subCommands.extend(ac.subCommands)
110 ac_dispatch.update(ac.dispatch)
113 config.parseOptions(argv)
114 except usage.error, e:
118 while hasattr(c, 'subOptions'):
120 print >>stdout, str(c)
122 msg = e.args[0].decode(get_io_encoding())
125 print >>stdout, "%s: %s\n" % (sys.argv[0], quote_output(msg, quotemarks=False))
128 command = config.subCommand
129 so = config.subOptions
138 if command in create_dispatch:
139 rc = create_dispatch[command](so, stdout, stderr)
140 elif command in startstop_node.dispatch:
141 rc = startstop_node.dispatch[command](so, stdout, stderr)
142 elif command in debug.dispatch:
143 rc = debug.dispatch[command](so)
144 elif command in admin.dispatch:
145 rc = admin.dispatch[command](so)
146 elif command in cli.dispatch:
147 rc = cli.dispatch[command](so)
148 elif command in magic_folder_cli.dispatch:
149 rc = magic_folder_cli.dispatch[command](so)
150 elif command in ac_dispatch:
151 rc = ac_dispatch[command](so, stdout, stderr)
153 raise usage.UsageError()
158 def run(install_node_control=True):
160 if sys.platform == "win32":
161 from allmydata.windows.fixups import initialize
164 rc = runner(sys.argv[1:], install_node_control=install_node_control)
167 traceback.print_exc()