Ticket #188: basedir-node-directory-option-improvements.dpatch

File basedir-node-directory-option-improvements.dpatch, 16.6 KB (added by davidsarah, at 2010-08-02T04:49:00Z)

Basedir/node directory option improvements for ticket798 branch. addresses #188, #706, #715, #772, #890. Version 3 (still disentangled from Unicode changes)

Line 
11 patch for repository davidsarah@tahoe-lafs.org:/home/source/darcs/tahoe-lafs/ticket798:
2
3Mon Aug  2 05:30:04 GMT Daylight Time 2010  david-sarah@jacaranda.org
4  * Basedir/node directory option improvements for ticket798 branch. addresses #188, #706, #715, #772, #890
5
6New patches:
7
8[Basedir/node directory option improvements for ticket798 branch. addresses #188, #706, #715, #772, #890
9david-sarah@jacaranda.org**20100802043004
10 Ignore-this: d19fc24349afa19833406518595bfdf7
11] {
12hunk ./src/allmydata/scripts/cli.py 3
13 import os.path, re, sys, fnmatch
14 from twisted.python import usage
15-from allmydata.scripts.common import BaseOptions, get_aliases
16-from allmydata.util.encodingutil import argv_to_unicode, argv_to_abspath
17+from allmydata.scripts.common import BaseOptions, get_aliases, get_default_nodedir, DEFAULT_ALIAS
18+from allmydata.util.encodingutil import argv_to_unicode, argv_to_abspath, quote_output
19 
20 NODEURL_RE=re.compile("http(s?)://([^:]*)(:([1-9][0-9]*))?")
21 
22hunk ./src/allmydata/scripts/cli.py 8
23-class VDriveOptions(BaseOptions, usage.Options):
24+_default_nodedir = get_default_nodedir()
25+
26+class VDriveOptions(BaseOptions):
27     optParameters = [
28hunk ./src/allmydata/scripts/cli.py 12
29-        ["node-directory", "d", "~/.tahoe",
30-         "Look here to find out which Tahoe node should be used for all "
31-         "operations. The directory should either contain a full Tahoe node, "
32-         "or a file named node.url which points to some other Tahoe node. "
33-         "It should also contain a file named private/aliases which contains "
34-         "the mapping from alias name to root dirnode URI."
35-         ],
36+        ["node-directory", "d", None,
37+         "Specify which Tahoe node directory should be used. The directory "
38+         "should either contain a full Tahoe node, or a file named node.url "
39+         "that points to some other Tahoe node. It should also contain a file "
40+         "named private/aliases which contains the mapping from alias name "
41+         "to root dirnode URI." + (
42+            _default_nodedir and (" [default for most commands: " + quote_output(_default_nodedir) + "]") or "")],
43         ["node-url", "u", None,
44          "URL of the tahoe node to use, a URL like \"http://127.0.0.1:3456\". "
45          "This overrides the URL found in the --node-directory ."],
46hunk ./src/allmydata/scripts/cli.py 27
47         ]
48 
49     def postOptions(self):
50-        # compute a node-url from the existing options, put in self['node-url']
51         if self['node-directory']:
52hunk ./src/allmydata/scripts/cli.py 28
53-            if sys.platform == 'win32' and self['node-directory'] == '~/.tahoe':
54-                from allmydata.windows import registry
55-                self['node-directory'] = registry.get_base_dir_path()
56-            else:
57-                self['node-directory'] = argv_to_abspath(self['node-directory'])
58+            self['node-directory'] = argv_to_abspath(self['node-directory'])
59+        else:
60+            self['node-directory'] = _default_nodedir
61+
62+        # compute a node-url from the existing options, put in self['node-url']
63         if self['node-url']:
64             if (not isinstance(self['node-url'], basestring)
65                 or not NODEURL_RE.match(self['node-url'])):
66hunk ./src/allmydata/scripts/cli.py 48
67 
68         aliases = get_aliases(self['node-directory'])
69         if self['dir-cap']:
70-            aliases["tahoe"] = self['dir-cap']
71+            aliases[DEFAULT_ALIAS] = self['dir-cap']
72         self.aliases = aliases # maps alias name to dircap
73 
74 
75hunk ./src/allmydata/scripts/common.py 9
76 from allmydata.util.encodingutil import unicode_to_url, quote_output, argv_to_abspath
77 from allmydata.util.fileutil import abspath_expanduser_unicode
78 
79-class BaseOptions:
80+
81+_default_nodedir = None
82+if sys.platform == 'win32':
83+    from allmydata.windows import registry
84+    path = registry.get_base_dir_path()
85+    if path:
86+        precondition(isinstance(path, unicode), path)
87+        _default_nodedir = abspath_expanduser_unicode(path)
88+
89+if _default_nodedir is None:
90+    path = abspath_expanduser_unicode(u"~/.tahoe")
91+    precondition(isinstance(path, unicode), path)
92+    _default_nodedir = path
93+
94+def get_default_nodedir():
95+    return _default_nodedir
96+
97+
98+class BaseOptions(usage.Options):
99     # unit tests can override these to point at StringIO instances
100     stdin = sys.stdin
101     stdout = sys.stdout
102hunk ./src/allmydata/scripts/common.py 37
103         ["quiet", "q", "Operate silently."],
104         ["version", "V", "Display version numbers and exit."],
105         ["version-and-path", None, "Display version numbers and paths to their locations and exit."],
106-        ]
107+    ]
108+    optParameters = [
109+        ["node-directory", "d", None, "Specify which Tahoe node directory should be used." + (
110+            _default_nodedir and (" [default for most commands: " + quote_output(_default_nodedir) + "]") or "")],
111+    ]
112 
113     def opt_version(self):
114         import allmydata
115hunk ./src/allmydata/scripts/common.py 55
116 
117 
118 class BasedirMixin:
119-    optFlags = [
120-        ["multiple", "m", "allow multiple basedirs to be specified at once"],
121-        ]
122+    default_nodedir = _default_nodedir
123+    allow_multiple = True
124 
125hunk ./src/allmydata/scripts/common.py 58
126-    def postOptions(self):
127-        if not self.basedirs:
128-            raise usage.UsageError("<basedir> parameter is required")
129-        if self['basedir']:
130-            del self['basedir']
131-        self['basedirs'] = self.basedirs
132+    optParameters = [
133+        ["basedir", "C", None, "Same as --node-directory."],
134+    ]
135+    optFlags = [
136+        ["multiple", "m", "Specify multiple node directories at once"],
137+    ]
138 
139     def parseArgs(self, *args):
140hunk ./src/allmydata/scripts/common.py 66
141-        self.basedirs = []
142-        if self['basedir']:
143-            precondition(isinstance(self['basedir'], str), self['basedir'])
144-            self.basedirs.append(argv_to_abspath(self['basedir']))
145-        if self['multiple']:
146-            self.basedirs.extend(map(argv_to_abspath, args))
147+        if self['node-directory'] and self['basedir']:
148+            raise usage.UsageError("The --node-directory (or -d) and --basedir (or -C) "
149+                                   "options cannot both be used.")
150+
151+        if self['node-directory'] or self['basedir']:
152+            self.basedirs = [argv_to_abspath(self['node-directory'] or self['basedir'])]
153         else:
154hunk ./src/allmydata/scripts/common.py 73
155-            if len(args) == 0 and not self.basedirs:
156-                if sys.platform == 'win32':
157-                    from allmydata.windows import registry
158-                    rbdp = registry.get_base_dir_path()
159-                    if rbdp:
160-                        precondition(isinstance(registry.get_base_dir_path(), unicode), registry.get_base_dir_path())
161-                        self.basedirs.append(rbdp)
162-                else:
163-                    self.basedirs.append(abspath_expanduser_unicode(u"~/.tahoe"))
164-            if len(args) > 0:
165-                self.basedirs.append(argv_to_abspath(args[0]))
166-            if len(args) > 1:
167-                raise usage.UsageError("I wasn't expecting so many arguments")
168+            self.basedirs = []
169 
170hunk ./src/allmydata/scripts/common.py 75
171-class NoDefaultBasedirMixin(BasedirMixin):
172-    def parseArgs(self, *args):
173-        # create-client won't default to --basedir=~/.tahoe
174-        self.basedirs = []
175-        if self['basedir']:
176-            self.basedirs.append(argv_to_abspath(self['basedir']))
177-        if self['multiple']:
178+        if self.allow_multiple and self['multiple']:
179             self.basedirs.extend(map(argv_to_abspath, args))
180         else:
181             if len(args) > 0:
182hunk ./src/allmydata/scripts/common.py 81
183                 self.basedirs.append(argv_to_abspath(args[0]))
184             if len(args) > 1:
185-                raise usage.UsageError("I wasn't expecting so many arguments")
186+                raise usage.UsageError("I wasn't expecting so many arguments." +
187+                    (self.allow_multiple and
188+                     " Use the --multiple option to specify more than one node directory." or ""))
189+
190+            if len(args) == 0 and self.default_nodedir and not self.basedirs:
191+                self.basedirs.append(self.default_nodedir)
192+            elif len(args) > 0:
193+                self.basedirs.append(argv_to_abspath(args[0]))
194+
195+    def postOptions(self):
196         if not self.basedirs:
197hunk ./src/allmydata/scripts/common.py 92
198-            raise usage.UsageError("--basedir must be provided")
199+            raise usage.UsageError("A base directory for the node must be provided.")
200+        del self['basedir']
201+        self['basedirs'] = self.basedirs
202+
203 
204 DEFAULT_ALIAS = u"tahoe"
205 
206hunk ./src/allmydata/scripts/common.py 109
207         f = open(rootfile, "r")
208         rootcap = f.read().strip()
209         if rootcap:
210-            aliases[u"tahoe"] = uri.from_string_dirnode(rootcap).to_string()
211+            aliases[DEFAULT_ALIAS] = uri.from_string_dirnode(rootcap).to_string()
212     except EnvironmentError:
213         pass
214     try:
215hunk ./src/allmydata/scripts/create_node.py 3
216 
217 import os, sys
218-from twisted.python import usage
219-from allmydata.scripts.common import BasedirMixin, NoDefaultBasedirMixin
220+from allmydata.scripts.common import BasedirMixin, BaseOptions
221 from allmydata.util.assertutil import precondition
222 from allmydata.util.encodingutil import listdir_unicode, argv_to_unicode, quote_output
223 import allmydata
224hunk ./src/allmydata/scripts/create_node.py 8
225 
226-class CreateClientOptions(BasedirMixin, usage.Options):
227+class CreateClientOptions(BasedirMixin, BaseOptions):
228     optParameters = [
229         ("basedir", "C", None, "which directory to create the node in"),
230         # we provide 'create-node'-time options for the most common
231hunk ./src/allmydata/scripts/create_node.py 25
232         ("no-storage", None, "do not offer storage service to other nodes"),
233         ]
234 
235-class CreateIntroducerOptions(NoDefaultBasedirMixin, usage.Options):
236+class CreateIntroducerOptions(BasedirMixin, BaseOptions):
237+    default_nodedir = None
238+
239     optParameters = [
240         ["basedir", "C", None, "which directory to create the introducer in"],
241         ]
242hunk ./src/allmydata/scripts/keygen.py 3
243 
244 import os, sys
245-from twisted.python import usage
246-#from allmydata.scripts.common import BasedirMixin, NoDefaultBasedirMixin
247-from allmydata.util.encodingutil import listdir_unicode, argv_to_abspath, quote_output
248+from allmydata.scripts.common import BasedirMixin, BaseOptions
249+from allmydata.util.encodingutil import listdir_unicode, quote_output
250+
251+class CreateKeyGeneratorOptions(BasedirMixin, BaseOptions):
252+    default_nodedir = None
253+    allow_multiple = False
254 
255hunk ./src/allmydata/scripts/keygen.py 10
256-class CreateKeyGeneratorOptions(usage.Options):
257     optParameters = [
258         ["basedir", "C", None, "which directory to create the key-generator in"],
259hunk ./src/allmydata/scripts/keygen.py 12
260-        ]
261+    ]
262 
263 keygen_tac = """
264 # -*- python -*-
265hunk ./src/allmydata/scripts/keygen.py 30
266 """
267 
268 def create_key_generator(config, out=sys.stdout, err=sys.stderr):
269-    if not config['basedir']:
270-        print >>err, "a basedir was not provided, please use --basedir or -C"
271-        return -1
272-    basedir = argv_to_abspath(config['basedir'])
273+    basedir = config['basedirs'][0]
274     if os.path.exists(basedir):
275         if listdir_unicode(basedir):
276             print >>err, "The base directory %s is not empty." % quote_output(basedir)
277hunk ./src/allmydata/scripts/startstop_node.py 3
278 
279 import os, sys, signal, time
280-from twisted.python import usage
281-from allmydata.scripts.common import BasedirMixin
282+from allmydata.scripts.common import BasedirMixin, BaseOptions
283 from allmydata.util import fileutil, find_exe
284 
285hunk ./src/allmydata/scripts/startstop_node.py 6
286-class StartOptions(BasedirMixin, usage.Options):
287+class StartOptions(BasedirMixin, BaseOptions):
288     optParameters = [
289         ["basedir", "C", None, "which directory to start the node in"],
290         ]
291hunk ./src/allmydata/scripts/startstop_node.py 15
292         ["syslog", None, "tell the node to log to syslog, not a file"],
293         ]
294 
295-class StopOptions(BasedirMixin, usage.Options):
296+class StopOptions(BasedirMixin, BaseOptions):
297     optParameters = [
298         ["basedir", "C", None, "which directory to stop the node in"],
299         ]
300hunk ./src/allmydata/scripts/startstop_node.py 20
301 
302-class RestartOptions(BasedirMixin, usage.Options):
303+class RestartOptions(BasedirMixin, BaseOptions):
304     optParameters = [
305         ["basedir", "C", None, "which directory to restart the node in"],
306         ]
307hunk ./src/allmydata/scripts/startstop_node.py 29
308         ["syslog", None, "tell the node to log to syslog, not a file"],
309         ]
310 
311-class RunOptions(usage.Options):
312+class RunOptions(BasedirMixin, BaseOptions):
313+    default_nodedir = u"."
314+
315     optParameters = [
316         ["basedir", "C", None, "which directory to run the node in, CWD by default"],
317         ]
318hunk ./src/allmydata/test/test_runner.py 205
319 
320         # make sure it rejects a missing basedir specification
321         argv = ["create-key-generator"]
322-        rc, out, err = self.run_tahoe(argv)
323-        self.failIfEqual(rc, 0, str((out, err, rc)))
324-        self.failUnlessEqual(out, "")
325-        self.failUnless("a basedir was not provided" in err)
326+        self.failUnlessRaises(usage.UsageError,
327+                              runner.runner, argv,
328+                              run_by_human=False)
329 
330     def test_stats_gatherer(self):
331         basedir = self.workdir("test_stats_gatherer")
332}
333
334Context:
335
336[Makefile: change tahoe_lafs* globs to *tahoe* (in order to also catch allmydata-tahoe). Change 'clean' to no longer delete bundled egg directories for setuptools, setuptools-trial and darcver.
337david-sarah@jacaranda.org**20100802033536
338 Ignore-this: d2cb81aaf9da4151fc0a3f89efa1de73
339] 
340[Makefile: fix 'clean' target to remove tahoe_lafs*.egg_info, and 'upload-tarballs' to upload tahoe_lafs* (instead of allmydata_tahoe*). Change 'upload-tarballs' to upload even for branches, and add 'upload-tarballs-trunkonly' that does what the name says.
341david-sarah@jacaranda.org**20100802031829
342 Ignore-this: d5765c6f51234b374fe32b3699e4fa1f
343] 
344[test_util.py: Python < 2.6 portability fix -- use .replace("1", "") instead of .translate(None, "1")
345david-sarah@jacaranda.org**20100802023210
346 Ignore-this: 2aa7e85362df25d3189c91633be9fdc2
347] 
348[.darcs-boringfile: Tahoe egg-info directories are no longer called allmydata-tahoe.egg-info.
349david-sarah@jacaranda.org**20100802015019
350 Ignore-this: a48fc3388290700ad24e37c963c3f683
351] 
352[test_runner.py: Fix error in message arguments to 'fail' calls.
353david-sarah@jacaranda.org**20100802013526
354 Ignore-this: 3bfdef19ae3cf993194811367da5d020
355] 
356[Additional Unicode basedir changes for ticket798 branch.
357david-sarah@jacaranda.org**20100802010552
358 Ignore-this: 7090d8c6b04eb6275345a55e75142028
359] 
360[Unicode basedir changes for ticket798 branch.
361david-sarah@jacaranda.org**20100801235310
362 Ignore-this: a00717eaeae8650847b5395801e04c45
363] 
364[New files added by New Downloader.
365david-sarah@jacaranda.org**20100801234004
366 Ignore-this: f44a1622f92d3c5b8a7603f0295c3f63
367] 
368[fileutil: change WindowsError to OSError in abspath_expanduser_unicode, because WindowsError might not exist.
369david-sarah@jacaranda.org**20100725222603
370 Ignore-this: e125d503670ed049a9ade0322faa0c51
371] 
372[test_system: correct a failure in _test_runner caused by Unicode basedir patch on non-Unicode platforms.
373david-sarah@jacaranda.org**20100724032123
374 Ignore-this: 399b3953104fdd1bbed3f7564d163553
375] 
376[Brian's New Downloader, for testing in 1.8beta. (rebased for ticket798 branch)
377david-sarah@jacaranda.org**20100801175522
378 Ignore-this: c4a9455865e13908e7c1bba4d5142c75
379] 
380[Fix test failures due to Unicode basedir patches.
381david-sarah@jacaranda.org**20100725010318
382 Ignore-this: fe92cd439eb3e60a56c007ae452784ed
383] 
384[util.encodingutil: change quote_output to do less unnecessary escaping, and to use double-quotes more consistently when needed. This version avoids u-escaping for characters that are representable in the output encoding, when double quotes are used, and includes tests. fixes #1135
385david-sarah@jacaranda.org**20100723075314
386 Ignore-this: b82205834d17db61612dd16436b7c5a2
387] 
388[Replace uses of os.path.abspath with abspath_expanduser_unicode where necessary. This makes basedir paths consistently represented as Unicode.
389david-sarah@jacaranda.org**20100722001418
390 Ignore-this: 9f8cb706540e695550e0dbe303c01f52
391] 
392[util.fileutil, test.test_util: add abspath_expanduser_unicode function, to work around <http://bugs.python.org/issue3426>. util.encodingutil: add a convenience function argv_to_abspath.
393david-sarah@jacaranda.org**20100721231507
394 Ignore-this: eee6904d1f65a733ff35190879844d08
395] 
396[TAG tahoe-lafs-ticket798-1.7.1
397zooko@zooko.com**20100801165549
398 Ignore-this: ab7966b17c0f091b4f532cc0cf518068
399] 
400Patch bundle hash:
401632304e342f5f910dc976a44eb8d2d23f5136b82