Ticket #1258: auto-deps-and-init-changes.darcs.patch

File auto-deps-and-init-changes.darcs.patch, 54.4 KB (added by davidsarah, at 2011-01-21T06:21:12Z)

Refactor _auto_deps.py and init.py, adding more robust checking of dependency versions, and not trusting pkg_resources to get the versions right. refs #1258, #1287

Line 
11 patch for repository davidsarah@dev.allmydata.org:/home/darcs/tahoe/trunk:
2
3Fri Jan 21 05:36:10 GMT Standard Time 2011  david-sarah@jacaranda.org
4  * Refactor _auto_deps.py and __init__.py, adding more robust checking of dependency versions, and not trusting pkg_resources to get the versions right. refs #1258, #1287
5
6New patches:
7
8[Refactor _auto_deps.py and __init__.py, adding more robust checking of dependency versions, and not trusting pkg_resources to get the versions right. refs #1258, #1287
9david-sarah@jacaranda.org**20110121053610
10 Ignore-this: b36d03e725ea9eb3362417e322019ebe
11] {
12hunk ./src/allmydata/__init__.py 7
13 community web site: U{http://tahoe-lafs.org/}
14 """
15 
16-# We want to call require_auto_deps() before other imports, because the setuptools
17-# docs claim that if a distribution is installed with --multi-version, it might not
18-# be importable until after pkg_resources.require() has been called for it. We don't
19-# have an example of this happening at this time. It is possible that require() isn't
20-# actually needed because we set __requires__ in the generated startup script, but
21-# that would be an undocumented property of the setuptools implementation.
22-
23-from allmydata import _auto_deps
24-_auto_deps.require_auto_deps()
25-
26-# This is just to suppress DeprecationWarnings from nevow and twisted.
27-# See http://allmydata.org/trac/tahoe/ticket/859 and
28-# http://divmod.org/trac/ticket/2994 .
29-import warnings
30-warnings.filterwarnings("ignore", category=DeprecationWarning,
31-    message="the sha module is deprecated; use the hashlib module instead",
32-    append=True)
33-warnings.filterwarnings("ignore", category=DeprecationWarning,
34-    message="object.__new__\(\) takes no parameters",
35-    append=True)
36-warnings.filterwarnings("ignore", category=DeprecationWarning,
37-    message="The popen2 module is deprecated.  Use the subprocess module.",
38-    append=True)
39-warnings.filterwarnings("ignore", category=DeprecationWarning,
40-    message="the md5 module is deprecated; use hashlib instead",
41-    append=True)
42-warnings.filterwarnings("ignore", category=DeprecationWarning,
43-    message="twisted.web.error.NoResource is deprecated since Twisted 9.0.  See twisted.web.resource.NoResource.",
44-    append=True)
45-try:
46-    import nevow
47-    from twisted.persisted import sob
48-    from twisted.python import filepath
49-    hush_pyflakes = (nevow, sob, filepath)
50-    del hush_pyflakes
51-finally:
52-    warnings.filters.pop()
53-    warnings.filters.pop()
54-    warnings.filters.pop()
55-    warnings.filters.pop()
56-    # Don't pop the filter for the sha module warning because it is also generated
57-    # by pycrypto (which we don't want to import unless needed).
58-    # warnings.filters.pop()
59-
60-# This warning is generated by twisted, PyRex, and possibly other packages,
61-# but can happen at any time, not only when they are imported. See
62-# http://tahoe-lafs.org/trac/tahoe-lafs/ticket/1129 .
63-warnings.filterwarnings("ignore", category=DeprecationWarning,
64-    message="BaseException.message has been deprecated as of Python 2.6",
65-    append=True)
66+class PackagingError(EnvironmentError):
67+    """
68+    Raised when there is an error in packaging of Tahoe-LAFS or its
69+    dependencies which makes it impossible to proceed safely.
70+    """
71+    pass
72 
73 __version__ = "unknown"
74 try:
75hunk ./src/allmydata/__init__.py 134
76     else:
77         return platform.platform()
78 
79-def get_package_versions_from_setuptools():
80-    import pkg_resources
81-    return dict([(p.project_name, (p.version, p.location)) for p in pkg_resources.require(__appname__)])
82 
83hunk ./src/allmydata/__init__.py 135
84-def package_dir(srcfile):
85-    return os.path.dirname(os.path.dirname(os.path.normcase(os.path.realpath(srcfile))))
86+from allmydata.util import verlib
87+def normalized_version(verstr):
88+    return verlib.NormalizedVersion(verlib.suggest_normalized_version(verstr))
89+
90 
91 def get_package_versions_and_locations():
92hunk ./src/allmydata/__init__.py 141
93-    # because there are a few dependencies that are outside setuptools's ken
94-    # (Python and platform, and sqlite3 if you are on Python >= 2.5), and
95-    # because setuptools might fail to find something even though import
96-    # finds it:
97-    import OpenSSL, allmydata, foolscap.api, nevow, platform, pycryptopp, setuptools, simplejson, twisted, zfec, zope.interface
98-    pysqlitever = None
99-    pysqlitefile = None
100-    sqlitever = None
101+    import warnings
102+    from _auto_deps import package_imports, deprecation_messages, deprecation_imports
103+
104+    def package_dir(srcfile):
105+        return os.path.dirname(os.path.dirname(os.path.normcase(os.path.realpath(srcfile))))
106+
107+    # pkg_resources.require returns the distribution that pkg_resources attempted to put
108+    # on sys.path, which can differ from the one that we actually import due to #1258,
109+    # or any other bug that causes sys.path to be set up incorrectly. Therefore we
110+    # must import the packages in order to check their versions and paths.
111+
112+    # This warning is generated by twisted, PyRex, and possibly other packages,
113+    # but can happen at any time, not only when they are imported. See
114+    # http://tahoe-lafs.org/trac/tahoe-lafs/ticket/1129 .
115+    warnings.filterwarnings("ignore", category=DeprecationWarning,
116+        message="BaseException.message has been deprecated as of Python 2.6",
117+        append=True)
118+
119+    # This is to suppress various DeprecationWarnings that occur when modules are imported.
120+    # See http://allmydata.org/trac/tahoe/ticket/859 and http://divmod.org/trac/ticket/2994 .
121+
122+    for msg in deprecation_messages:
123+        warnings.filterwarnings("ignore", category=DeprecationWarning, message=msg, append=True)
124     try:
125hunk ./src/allmydata/__init__.py 165
126-        import sqlite3
127-    except ImportError:
128-        try:
129-            from pysqlite2 import dbapi2
130-        except ImportError:
131-            pass
132+        for modulename in deprecation_imports:
133+            try:
134+                __import__(modulename)
135+            except ImportError:
136+                pass
137+    finally:
138+        for ign in deprecation_messages:
139+            warnings.filters.pop()
140+
141+    packages = []
142+
143+    def get_version(module, attr):
144+        return str(getattr(module, attr, 'unknown'))
145+
146+    for pkgname, modulename in [(__appname__, 'allmydata')] + package_imports:
147+        if modulename:
148+            try:
149+                __import__(modulename)
150+                module = sys.modules[modulename]
151+            except ImportError:
152+                packages.append((pkgname, (None, modulename)))
153+            else:
154+                if 'sqlite' in pkgname:
155+                    packages.append( (pkgname,  (get_version(module, 'version'),        package_dir(module.__file__))) )
156+                    packages.append( ('sqlite', (get_version(module, 'sqlite_version'), package_dir(module.__file__))) )
157+                else:
158+                    packages.append( (pkgname,  (get_version(module, '__version__'),    package_dir(module.__file__))) )
159+        elif pkgname == 'python':
160+            packages.append( (pkgname, (platform.python_version(), sys.executable)) )
161+        elif pkgname == 'platform':
162+            packages.append( (pkgname, (get_platform(), None)) )
163+
164+    return packages
165+
166+
167+def check_requirement(req, vers_and_locs):
168+    # TODO: check [] options
169+    # We support only disjunctions of >= and ==
170+
171+    reqlist = req.split(',')
172+    name = reqlist[0].split('>=')[0].split('==')[0].strip(' ').split('[')[0]
173+    if name not in vers_and_locs:
174+        raise PackagingError("no version info for %s" % (name,))
175+    if req.strip(' ') == name:
176+        return
177+    (actual, location) = vers_and_locs[name]
178+    if actual is None:
179+        raise ImportError("could not import %r for requirement %r" % (location, req))
180+    if actual == 'unknown':
181+        return
182+    actualver = normalized_version(actual)
183+
184+    for r in reqlist:
185+        s = r.split('>=')
186+        if len(s) == 2:
187+            required = s[1].strip(' ')
188+            if actualver >= normalized_version(required):
189+                return  # minimum requirement met
190         else:
191hunk ./src/allmydata/__init__.py 224
192-            pysqlitever = dbapi2.version
193-            pysqlitefile = package_dir(dbapi2.__file__)
194-            sqlitever = dbapi2.sqlite_version
195-    else:
196-        pysqlitever = sqlite3.version
197-        pysqlitefile = package_dir(sqlite3.__file__)
198-        sqlitever = sqlite3.sqlite_version
199+            s = r.split('==')
200+            if len(s) == 2:
201+                required = s[1].strip(' ')
202+                if actualver == normalized_version(required):
203+                    return  # exact requirement met
204+            else:
205+                raise PackagingError("no version info or could not understand requirement %r" % (req,))
206+
207+    msg = ("We require %s, but could only find version %s.\n" % (req, actual))
208+    if location and location != 'unknown':
209+        msg += "The version we found is from %r.\n" % (location,)
210+    msg += ("To resolve this problem, uninstall that version, either using your\n"
211+            "operating system's package manager or by moving aside the directory.")
212+    raise PackagingError(msg)
213+
214+
215+_vers_and_locs_list = get_package_versions_and_locations()
216 
217hunk ./src/allmydata/__init__.py 242
218-    d1 = {
219-        'pyOpenSSL': (OpenSSL.__version__, package_dir(OpenSSL.__file__)),
220-        __appname__: (allmydata.__version__, package_dir(allmydata.__file__)),
221-        'foolscap': (foolscap.api.__version__, package_dir(foolscap.__file__)),
222-        'Nevow': (nevow.__version__, package_dir(nevow.__file__)),
223-        'pycryptopp': (pycryptopp.__version__, package_dir(pycryptopp.__file__)),
224-        'setuptools': (setuptools.__version__, package_dir(setuptools.__file__)),
225-        'simplejson': (simplejson.__version__, package_dir(simplejson.__file__)),
226-        'pysqlite': (pysqlitever, pysqlitefile),
227-        'sqlite': (sqlitever, 'unknown'),
228-        'zope.interface': ('unknown', package_dir(zope.interface.__file__)),
229-        'Twisted': (twisted.__version__, package_dir(twisted.__file__)),
230-        'zfec': (zfec.__version__, package_dir(zfec.__file__)),
231-        'python': (platform.python_version(), sys.executable),
232-        'platform': (get_platform(), None),
233-        }
234+
235+def cross_check_pkg_resources_versus_import():
236+    """This function returns a list of errors due to any failed cross-checks."""
237 
238hunk ./src/allmydata/__init__.py 246
239-    # But we prefer to get all the dependencies as known by setuptools:
240     import pkg_resources
241hunk ./src/allmydata/__init__.py 247
242-    try:
243-        d2 = get_package_versions_from_setuptools()
244-    except pkg_resources.DistributionNotFound:
245-        # See docstring in _auto_deps.require_auto_deps() to explain why it makes sense to ignore this exception.
246-        pass
247+    from _auto_deps import install_requires
248+
249+    errors = []
250+    not_pkg_resourceable = set(['sqlite', 'sqlite3', 'python', 'platform', __appname__.lower()])
251+    not_import_versionable = set(['zope.interface', 'mock', 'pyasn1'])
252+    ignorable = set(['argparse', 'pyutil', 'zbase32'])
253+
254+    pkg_resources_vers_and_locs = dict([(p.project_name.lower(), (str(p.version), p.location))
255+                                        for p in pkg_resources.require(install_requires)])
256+
257+    for name, (imp_ver, imp_loc) in _vers_and_locs_list:
258+        name = name.lower()
259+        if name not in not_pkg_resourceable:
260+            if name not in pkg_resources_vers_and_locs:
261+                errors.append("Warning: dependency %s (version %s imported from %r) was not found by pkg_resources."
262+                              % (name, imp_ver, imp_loc))
263+
264+            pr_ver, pr_loc = pkg_resources_vers_and_locs[name]
265+            try:
266+                pr_normver = normalized_version(pr_ver)
267+            except Exception, e:
268+                errors.append("Warning: version number %s found for dependency %s by pkg_resources could not be parsed. "
269+                              "The version found by import was %s from %r. "
270+                              "pkg_resources thought it should be found at %r. "
271+                              "The exception was %s: %s"
272+                              % (pr_ver, name, imp_ver, imp_loc, pr_loc, e.__class__.name, e))
273+            else:
274+                if imp_ver == 'unknown':
275+                    if name not in not_import_versionable:
276+                        errors.append("Warning: unexpectedly could not find a version number for dependency %s imported from %r. "
277+                                      "pkg_resources thought it should be version %s at %r."
278+                                      % (name, imp_loc, pr_ver, pr_loc))
279+                else:
280+                    try:
281+                        imp_normver = normalized_version(imp_ver)
282+                    except Exception, e:
283+                        errors.append("Warning: version number %s found for dependency %s (imported from %r) could not be parsed. "
284+                                      "pkg_resources thought it should be version %s at %r. "
285+                                      "The exception was %s: %s"
286+                                      % (imp_ver, name, imp_loc, pr_ver, pr_loc, e.__class__.name, e))
287+                    else:
288+                        if pr_ver == 'unknown' or (pr_normver != imp_normver):
289+                            if not os.path.normpath(os.path.realpath(pr_loc)) == os.path.normpath(os.path.realpath(imp_loc)):
290+                                errors.append("Warning: dependency %s found to have version number %s (normalized to %s, from %r) "
291+                                              "by pkg_resources, but version %s (normalized to %s, from %r) by import."
292+                                              % (name, pr_ver, str(pr_normver), pr_loc, imp_ver, str(imp_normver), imp_loc))
293+
294+    imported_packages = set([p.lower() for (p, _) in _vers_and_locs_list])
295+    for pr_name, (pr_ver, pr_loc) in pkg_resources_vers_and_locs.iteritems():
296+        if pr_name not in imported_packages and pr_name not in ignorable:
297+            errors.append("Warning: dependency %s (version %s) found by pkg_resources not found by import."
298+                          % (pr_name, pr_ver))
299+
300+    return errors
301+
302+
303+def get_error_string(errors):
304+    from allmydata._auto_deps import install_requires
305+
306+    return ("\n%s\n\n"
307+            "For debugging purposes, the PYTHONPATH was\n"
308+            "  %r\n"
309+            "install_requires was\n"
310+            "  %r\n"
311+            "sys.path after importing pkg_resources was\n"
312+            "  %s\n"
313+            % ("\n".join(errors), os.environ.get('PYTHONPATH'), install_requires, (os.pathsep+"\n  ").join(sys.path)) )
314+
315+def check_all_requirements():
316+    """This function returns a list of errors due to any failed checks."""
317+
318+    from allmydata._auto_deps import install_requires
319+
320+    errors = []
321+
322+    # we require 2.4.4 on non-UCS-2, non-Redhat builds to avoid <http://www.python.org/news/security/PSF-2006-001/>
323+    # we require 2.4.3 on non-UCS-2 Redhat, because 2.4.3 is common on Redhat-based distros and will have patched the above bug
324+    # we require at least 2.4.2 in any case to avoid a bug in the base64 module: <http://bugs.python.org/issue1171487>
325+    if sys.maxunicode == 65535:
326+        if sys.version_info < (2, 4, 2) or sys.version_info[0] > 2:
327+            errors.append("Tahoe-LAFS current requires Python v2.4.2 or greater "
328+                          "for a UCS-2 build (but less than v3), not %r" %
329+                          (sys.version_info,))
330+    elif platform.platform().lower().find('redhat') >= 0:
331+        if sys.version_info < (2, 4, 3) or sys.version_info[0] > 2:
332+            errors.append("Tahoe-LAFS current requires Python v2.4.3 or greater "
333+                          "on Redhat-based distributions (but less than v3), not %r" %
334+                          (sys.version_info,))
335     else:
336hunk ./src/allmydata/__init__.py 336
337-        d1.update(d2)
338+        if sys.version_info < (2, 4, 4) or sys.version_info[0] > 2:
339+            errors.append("Tahoe-LAFS current requires Python v2.4.4 or greater "
340+                          "for a non-UCS-2 build (but less than v3), not %r" %
341+                          (sys.version_info,))
342+
343+    vers_and_locs = dict(_vers_and_locs_list)
344+    for requirement in install_requires:
345+        try:
346+            check_requirement(requirement, vers_and_locs)
347+        except Exception, e:
348+            errors.append("%s: %s" % (e.__class__.__name__, e))
349+
350+    if errors:
351+        raise PackagingError(get_error_string(errors))
352+
353+check_all_requirements()
354 
355hunk ./src/allmydata/__init__.py 353
356-    return d1
357 
358 def get_package_versions():
359hunk ./src/allmydata/__init__.py 355
360-    return dict([(k, v) for k, (v, l) in get_package_versions_and_locations().iteritems()])
361+    return dict([(k, v) for k, (v, l) in _vers_and_locs_list])
362 
363 def get_package_locations():
364hunk ./src/allmydata/__init__.py 358
365-    return dict([(k, l) for k, (v, l) in get_package_versions_and_locations().iteritems()])
366+    return dict([(k, l) for k, (v, l) in _vers_and_locs_list])
367 
368 def get_package_versions_string(show_paths=False):
369hunk ./src/allmydata/__init__.py 361
370-    vers_and_locs = get_package_versions_and_locations()
371     res = []
372hunk ./src/allmydata/__init__.py 362
373-    for p in [__appname__, "foolscap", "pycryptopp", "zfec", "Twisted", "Nevow", "zope.interface", "python", "platform"]:
374-        (ver, loc) = vers_and_locs.get(p, ('UNKNOWN', 'UNKNOWN'))
375-        info = str(p) + ": " + str(ver)
376-        if show_paths:
377-            info = info + " (%s)" % str(loc)
378-        res.append(info)
379-        if vers_and_locs.has_key(p):
380-            del vers_and_locs[p]
381-
382-    for p, (v, loc) in vers_and_locs.iteritems():
383+    for p, (v, loc) in _vers_and_locs_list:
384         info = str(p) + ": " + str(v)
385         if show_paths:
386             info = info + " (%s)" % str(loc)
387hunk ./src/allmydata/__init__.py 367
388         res.append(info)
389-    return ', '.join(res)
390+
391+    output = ",\n".join(res) + "\n"
392+
393+    if not hasattr(sys, 'frozen'):
394+        errors = cross_check_pkg_resources_versus_import()
395+        if errors:
396+            output += get_error_string(errors)
397+
398+    return output
399hunk ./src/allmydata/_auto_deps.py 1
400-# Note: do not import any module from Tahoe-LAFS itself in this
401-# file. Also please avoid importing modules from other packages than
402-# the Python Standard Library if at all possible (exception: we rely
403-# on importing pkg_resources, which is provided by setuptools,
404-# zetuptoolz, distribute, and perhaps in the future distutils2, for
405-# the require_auto_deps() function.)
406+# Note: please minimize imports in this file. In particular, do not import
407+# any module from Tahoe-LAFS or its dependencies, and do not import any
408+# modules at all at global level. That includes setuptools and pkg_resources.
409+# It is ok to import modules from the Python Standard Library if they are
410+# always available, or the import is protected by try...except ImportError.
411 
412hunk ./src/allmydata/_auto_deps.py 7
413-install_requires=[
414-                  # we require newer versions of setuptools (actually
415-                  # zetuptoolz) to build, but can handle older versions to run
416-                  "setuptools >= 0.6c6",
417+install_requires = [
418+    "zfec >= 1.1.0",
419 
420hunk ./src/allmydata/_auto_deps.py 10
421-                  "zfec >= 1.1.0",
422+    # Feisty has simplejson 1.4
423+    "simplejson >= 1.4",
424 
425hunk ./src/allmydata/_auto_deps.py 13
426-                  # Feisty has simplejson 1.4
427-                  "simplejson >= 1.4",
428+    "zope.interface",
429 
430hunk ./src/allmydata/_auto_deps.py 15
431-                  "zope.interface",
432-                  "Twisted >= 2.4.0",
433+    "Twisted >= 2.4.0",
434 
435hunk ./src/allmydata/_auto_deps.py 17
436-                  # foolscap < 0.5.1 had a performance bug which spent
437-                  # O(N**2) CPU for transferring large mutable files
438-                  # of size N.
439-                  # foolscap < 0.6 is incompatible with Twisted 10.2.0.
440-                  # foolscap 0.6.1 quiets a DeprecationWarning.
441-                  "foolscap[secure_connections] >= 0.6.1",
442-                  "Nevow >= 0.6.0",
443+    # foolscap < 0.5.1 had a performance bug which spent
444+    # O(N**2) CPU for transferring large mutable files
445+    # of size N.
446+    # foolscap < 0.6 is incompatible with Twisted 10.2.0.
447+    # foolscap 0.6.1 quiets a DeprecationWarning.
448+    "foolscap[secure_connections] >= 0.6.1",
449 
450hunk ./src/allmydata/_auto_deps.py 24
451-                  # Needed for SFTP. pyasn1 is needed by twisted.conch in Twisted >= 9.0.
452-                  # pycrypto 2.2 doesn't work due to https://bugs.launchpad.net/pycrypto/+bug/620253
453-                  "pycrypto == 2.0.1, == 2.1, >= 2.3",
454-                  "pyasn1 >= 0.0.8a",
455+    "Nevow >= 0.6.0",
456 
457hunk ./src/allmydata/_auto_deps.py 26
458-                  # http://www.voidspace.org.uk/python/mock/
459-                  "mock",
460+    # Needed for SFTP. pyasn1 is needed by twisted.conch in Twisted >= 9.0.
461+    # pycrypto 2.2 doesn't work due to https://bugs.launchpad.net/pycrypto/+bug/620253
462+    "pycrypto == 2.0.1, == 2.1.0, >= 2.3",
463+    "pyasn1 >= 0.0.8a",
464 
465hunk ./src/allmydata/_auto_deps.py 31
466-                  # Will be needed to test web apps, but not yet. See #1001.
467-                  #"windmill >= 1.3",
468-                  ]
469+    # http://www.voidspace.org.uk/python/mock/
470+    "mock",
471 
472hunk ./src/allmydata/_auto_deps.py 34
473-import platform
474-if platform.machine().lower() in ['i386', 'x86_64', 'amd64', 'x86', '']:
475-    # pycryptopp v0.5.20 fixes bugs in SHA-256 and AES on x86 or amd64
476-    # (from Crypto++ revisions 470, 471, 480, 492).  The '' is there
477-    # in case platform.machine is broken and this is actually an x86
478-    # or amd64 machine.
479-    install_requires.append("pycryptopp >= 0.5.20")
480-else:
481-    # pycryptopp v0.5.13 had a new bundled version of Crypto++
482-    # (v5.6.0) and a new bundled version of setuptools (although that
483-    # shouldn't make any different to users of pycryptopp).
484-    install_requires.append("pycryptopp >= 0.5.14")
485+    # Will be needed to test web apps, but not yet. See #1001.
486+    #"windmill >= 1.3",
487+]
488 
489hunk ./src/allmydata/_auto_deps.py 38
490+# Includes some indirect dependencies, but does not include allmydata.
491+# These are in the order they should be listed by --version, etc.
492+package_imports = [
493+    # package name      module name
494+    ('foolscap',        'foolscap'),
495+    ('pycryptopp',      'pycryptopp'),
496+    ('zfec',            'zfec'),
497+    ('Twisted',         'twisted'),
498+    ('Nevow',           'nevow'),
499+    ('zope.interface',  'zope.interface'),
500+    ('python',          None),
501+    ('platform',        None),
502+    ('pyOpenSSL',       'OpenSSL'),
503+    ('simplejson',      'simplejson'),
504+    ('pycrypto',        'Crypto'),
505+    ('pyasn1',          'pyasn1'),
506+    ('mock',            'mock'),
507+]
508 
509hunk ./src/allmydata/_auto_deps.py 57
510-# Sqlite comes built into Python >= 2.5, and is provided by the "pysqlite"
511-# distribution for Python 2.4.
512-import sys
513-if sys.version_info < (2, 5):
514-    # pysqlite v2.0.5 was shipped in Ubuntu 6.06 LTS "dapper" and Nexenta NCP 1.
515-    install_requires.append("pysqlite >= 2.0.5")
516+def require_more():
517+    import platform, sys
518 
519hunk ./src/allmydata/_auto_deps.py 60
520-if hasattr(sys, 'frozen'): # for py2exe
521-    install_requires=[]
522-del sys # clean up namespace
523+    if platform.machine().lower() in ['i386', 'x86_64', 'amd64', 'x86', '']:
524+        # pycryptopp v0.5.20 fixes bugs in SHA-256 and AES on x86 or amd64
525+        # (from Crypto++ revisions 470, 471, 480, 492).  The '' is there
526+        # in case platform.machine is broken and this is actually an x86
527+        # or amd64 machine.
528+        install_requires.append("pycryptopp >= 0.5.20")
529+    else:
530+        # pycryptopp v0.5.13 had a new bundled version of Crypto++
531+        # (v5.6.0) and a new bundled version of setuptools (although that
532+        # shouldn't make any difference to users of pycryptopp).
533+        install_requires.append("pycryptopp >= 0.5.14")
534 
535hunk ./src/allmydata/_auto_deps.py 72
536-def require_python_version():
537-    import sys, platform
538+    # Sqlite comes built into Python >= 2.5, and is provided by the "pysqlite"
539+    # distribution for Python 2.4.
540+    try:
541+        import sqlite3
542+        sqlite3 # hush pyflakes
543+        package_imports.append(('sqlite3', 'sqlite3'))
544+    except ImportError:
545+        # pysqlite v2.0.5 was shipped in Ubuntu 6.06 LTS "dapper" and Nexenta NCP 1.
546+        install_requires.append("pysqlite >= 2.0.5")
547+        package_imports.append(('pysqlite', 'pysqlite.dbapi2'))
548 
549hunk ./src/allmydata/_auto_deps.py 83
550-    # we require 2.4.4 on non-UCS-2, non-Redhat builds to avoid <http://www.python.org/news/security/PSF-2006-001/>
551-    # we require 2.4.3 on non-UCS-2 Redhat, because 2.4.3 is common on Redhat-based distros and will have patched the above bug
552-    # we require at least 2.4.2 in any case to avoid a bug in the base64 module: <http://bugs.python.org/issue1171487>
553-    if sys.maxunicode == 65535:
554-        if sys.version_info < (2, 4, 2) or sys.version_info[0] > 2:
555-            raise NotImplementedError("Tahoe-LAFS current requires Python v2.4.2 or greater "
556-                                      "for a UCS-2 build (but less than v3), not %r" %
557-                                      (sys.version_info,))
558-    elif platform.platform().lower().find('redhat') >= 0:
559-        if sys.version_info < (2, 4, 3) or sys.version_info[0] > 2:
560-            raise NotImplementedError("Tahoe-LAFS current requires Python v2.4.3 or greater "
561-                                      "on Redhat-based distributions (but less than v3), not %r" %
562-                                      (sys.version_info,))
563-    else:
564-        if sys.version_info < (2, 4, 4) or sys.version_info[0] > 2:
565-            raise NotImplementedError("Tahoe-LAFS current requires Python v2.4.4 or greater "
566-                                      "for a non-UCS-2 build (but less than v3), not %r" %
567-                                      (sys.version_info,))
568+    if not hasattr(sys, 'frozen'):
569+        # we require newer versions of setuptools (actually
570+        # zetuptoolz) to build, but can handle older versions to run
571+        install_requires.append("setuptools >= 0.6c6")
572+        package_imports.append(('setuptools', 'setuptools'))
573+
574+require_more()
575 
576hunk ./src/allmydata/_auto_deps.py 91
577-def require_auto_deps():
578-    """
579-    The purpose of this function is to raise a pkg_resources exception if any of the
580-    requirements can't be imported.  This is just to give earlier and more explicit error
581-    messages, as opposed to waiting until the source code tries to import some module from one
582-    of these packages and gets an ImportError.  This function gets called from
583-    src/allmydata/__init__.py .
584-    """
585-    require_python_version()
586+deprecation_messages = [
587+    "the sha module is deprecated; use the hashlib module instead",
588+    "object.__new__\(\) takes no parameters",
589+    "The popen2 module is deprecated.  Use the subprocess module.",
590+    "the md5 module is deprecated; use hashlib instead",
591+    "twisted.web.error.NoResource is deprecated since Twisted 9.0.  See twisted.web.resource.NoResource.",
592+    "the sets module is deprecated",
593+]
594 
595hunk ./src/allmydata/_auto_deps.py 100
596-    import pkg_resources
597-    for requirement in install_requires:
598-        try:
599-            pkg_resources.require(requirement)
600-        except pkg_resources.DistributionNotFound:
601-            # there is no .egg-info present for this requirement, which
602-            # either means that it isn't installed, or it is installed in a
603-            # way that pkg_resources can't find it (but regular python
604-            # might).  There are several older Linux distributions which
605-            # provide our dependencies just fine, but they don't ship
606-            # .egg-info files. Note that if there *is* an .egg-info file,
607-            # but it shows a too-old version, then we'll get a
608-            # VersionConflict error instead of DistributionNotFound.
609-            pass
610+deprecation_imports = [
611+    'nevow',
612+    'twisted.persisted.sob',
613+    'twisted.python.filepath',
614+    'Crypto.Hash.SHA',
615+]
616addfile ./src/allmydata/test/test_version.py
617hunk ./src/allmydata/test/test_version.py 1
618+
619+from twisted.trial import unittest
620+
621+from allmydata import check_requirement, PackagingError
622+from allmydata.util.verlib import NormalizedVersion as V, \
623+                                  IrrationalVersionError, \
624+                                  suggest_normalized_version as suggest
625+
626+
627+class CheckRequirement(unittest.TestCase):
628+    def test_check_requirement(self):
629+        check_requirement("setuptools >= 0.6c6", {"setuptools": ("0.6", "")})
630+        check_requirement("pycrypto == 2.0.1, == 2.1, >= 2.3", {"pycrypto": ("2.1.0", "")})
631+        check_requirement("pycrypto == 2.0.1, == 2.1, >= 2.3", {"pycrypto": ("2.4.0", "")})
632+
633+        check_requirement("zope.interface", {"zope.interface": ("unknown", "")})
634+        check_requirement("mock", {"mock": ("0.6.0", "")})
635+        check_requirement("foo >= 1.0", {"foo": ("1.0", ""), "bar": ("2.0", "")})
636+
637+        check_requirement("foolscap[secure_connections] >= 0.6.0", {"foolscap": ("0.7.0", "")})
638+
639+        self.failUnlessRaises(PackagingError, check_requirement,
640+                              "foolscap[secure_connections] >= 0.6.0", {"foolscap": ("0.5.1", "")})
641+        self.failUnlessRaises(PackagingError, check_requirement,
642+                              "pycrypto == 2.0.1, == 2.1, >= 2.3", {"pycrypto": ("2.2.0", "")})
643+        self.failUnlessRaises(PackagingError, check_requirement,
644+                              "foo >= 1.0", {})
645+
646+
647+# based on https://bitbucket.org/tarek/distutilsversion/src/17df9a7d96ef/test_verlib.py
648+
649+class VersionTestCase(unittest.TestCase):
650+    versions = ((V('1.0'), '1.0'),
651+                (V('1.1'), '1.1'),
652+                (V('1.2.3'), '1.2.3'),
653+                (V('1.2'), '1.2'),
654+                (V('1.2.3a4'), '1.2.3a4'),
655+                (V('1.2c4'), '1.2c4'),
656+                (V('1.2.3.4'), '1.2.3.4'),
657+                (V('1.2.3.4.0b3'), '1.2.3.4b3'),
658+                (V('1.2.0.0.0'), '1.2'),
659+                (V('1.0.dev345'), '1.0.dev345'),
660+                (V('1.0.post456.dev623'), '1.0.post456.dev623'))
661+
662+    def test_basic_versions(self):
663+        for v, s in self.versions:
664+            self.failUnlessEqual(str(v), s)
665+
666+    def test_from_parts(self):
667+        for v, s in self.versions:
668+            parts = v.parts
669+            v2 = V.from_parts(*parts)
670+            self.failUnlessEqual(v, v2)
671+            self.failUnlessEqual(str(v), str(v2))
672+
673+    def test_irrational_versions(self):
674+        irrational = ('1', '1.2a', '1.2.3b', '1.02', '1.2a03',
675+                      '1.2a3.04', '1.2.dev.2', '1.2dev', '1.2.dev',
676+                      '1.2.dev2.post2', '1.2.post2.dev3.post4')
677+
678+        for s in irrational:
679+            self.failUnlessRaises(IrrationalVersionError, V, s)
680+
681+    def test_comparison(self):
682+        self.failUnlessRaises(TypeError, lambda: V('1.2.0') == '1.2')
683+
684+        self.failUnlessEqual(V('1.2.0'), V('1.2'))
685+        self.failIfEqual(V('1.2.0'), V('1.2.3'))
686+        self.failUnless(V('1.2.0') < V('1.2.3'))
687+        self.failUnless(V('1.0') > V('1.0b2'))
688+        self.failUnless(V('1.0') > V('1.0c2') > V('1.0c1') > V('1.0b2') > V('1.0b1')
689+                        > V('1.0a2') > V('1.0a1'))
690+        self.failUnless(V('1.0.0') > V('1.0.0c2') > V('1.0.0c1') > V('1.0.0b2') > V('1.0.0b1')
691+                        > V('1.0.0a2') > V('1.0.0a1'))
692+
693+        self.failUnless(V('1.0') < V('1.0.post456.dev623'))
694+        self.failUnless(V('1.0.post456.dev623') < V('1.0.post456')  < V('1.0.post1234'))
695+
696+        self.failUnless(V('1.0a1')
697+                        < V('1.0a2.dev456')
698+                        < V('1.0a2')
699+                        < V('1.0a2.1.dev456')  # e.g. need to do a quick post release on 1.0a2
700+                        < V('1.0a2.1')
701+                        < V('1.0b1.dev456')
702+                        < V('1.0b2')
703+                        < V('1.0c1')
704+                        < V('1.0c2.dev456')
705+                        < V('1.0c2')
706+                        < V('1.0.dev7')
707+                        < V('1.0.dev18')
708+                        < V('1.0.dev456')
709+                        < V('1.0.dev1234')
710+                        < V('1.0')
711+                        < V('1.0.post456.dev623')  # development version of a post release
712+                        < V('1.0.post456'))
713+
714+    def test_suggest_normalized_version(self):
715+        self.failUnlessEqual(suggest('1.0'), '1.0')
716+        self.failUnlessEqual(suggest('1.0-alpha1'), '1.0a1')
717+        self.failUnlessEqual(suggest('1.0c2'), '1.0c2')
718+        self.failUnlessEqual(suggest('walla walla washington'), None)
719+        self.failUnlessEqual(suggest('2.4c1'), '2.4c1')
720+
721+        # from setuptools
722+        self.failUnlessEqual(suggest('0.4a1.r10'), '0.4a1.post10')
723+        self.failUnlessEqual(suggest('0.7a1dev-r66608'), '0.7a1.dev66608')
724+        self.failUnlessEqual(suggest('0.6a9.dev-r41475'), '0.6a9.dev41475')
725+        self.failUnlessEqual(suggest('2.4preview1'), '2.4c1')
726+        self.failUnlessEqual(suggest('2.4pre1') , '2.4c1')
727+        self.failUnlessEqual(suggest('2.1-rc2'), '2.1c2')
728+
729+        # from pypi
730+        self.failUnlessEqual(suggest('0.1dev'), '0.1.dev0')
731+        self.failUnlessEqual(suggest('0.1.dev'), '0.1.dev0')
732+
733+        # we want to be able to parse Twisted
734+        # development versions are like post releases in Twisted
735+        self.failUnlessEqual(suggest('9.0.0+r2363'), '9.0.0.post2363')
736+
737+        # pre-releases are using markers like "pre1"
738+        self.failUnlessEqual(suggest('9.0.0pre1'), '9.0.0c1')
739+
740+        # we want to be able to parse Tcl-TK
741+        # they us "p1" "p2" for post releases
742+        self.failUnlessEqual(suggest('1.4p1'), '1.4.post1')
743+
744+        # from darcsver
745+        self.failUnlessEqual(suggest('1.8.1-r4956'), '1.8.1.post4956')
746+
747+        # zetuptoolz
748+        self.failUnlessEqual(suggest('0.6c16dev3'), '0.6c16.dev3')
749}
750
751Context:
752
753[src/allmydata/util/iputil.py: loosen regexps and ensure that 'LANG=en_US.UTF-8' is set in the environment, to minimize problems with localized output of IP-address-finding tools. refs #1274
754david-sarah@jacaranda.org**20110120084827
755 Ignore-this: da04b1d780915ecfe492b671fdc2727e
756]
757[Eliminate dependencies on pywin32, even via Twisted. refs #1274
758david-sarah@jacaranda.org**20110120043238
759 Ignore-this: 96a2c30ea71a897472d704e905d3cb13
760]
761[Makefile: consistently use TAHOE macro to run bin/tahoe. Use '$(TAHOE) debug repl' instead of $(RUNPP) -p. refs #1296
762david-sarah@jacaranda.org**20110119234429
763 Ignore-this: 1c339126c6cdb6cd7d60a95a2f0db0a2
764]
765[Makefile: consistently use 'tahoe debug trial' to run tests. refs #1296
766david-sarah@jacaranda.org**20110119233737
767 Ignore-this: 4b6b5a13fcf767c23e5f983f92f2c053
768]
769[setup.py: add descriptions for some of the setup commands. ref #1306
770david-sarah@jacaranda.org**20110119233305
771 Ignore-this: 8759eb5c3ee4b717bba5580622d76c6b
772]
773[setup.py: create bin/tahoe.pyscript on Unix as well as Windows for consistency, and to reduce conditional code. ref #1306
774david-sarah@jacaranda.org**20110119233145
775 Ignore-this: d1a7e66b3a2244fb4523ab3ef4057e5f
776]
777[src/allmydata/test/test_runner.py: add test_import_from_repl, which checks that we are running the right code in a bin/tahoe subprocess. refs #1258
778david-sarah@jacaranda.org**20110119082145
779 Ignore-this: c53a76827b47446df9e7b0128a2cb2c5
780]
781[docs/frontends/CLI.rst, src/allmydata/test/trialtest.py: add trailing newlines. refs #1296
782david-sarah@jacaranda.org**20110119081955
783 Ignore-this: 1d19fad753ff17febf9b99bb2f5b7df7
784]
785[Eliminate direct dependencies of Tahoe-LAFS on pywin32 (rebased to trunk). refs #1274
786david-sarah@jacaranda.org**20110119075911
787 Ignore-this: 8f31d1188daa382ec694908a68a19194
788]
789[trivial: add comment in scripts/debug.py about trial option parsing. refs #1296
790david-sarah@jacaranda.org**20110119060808
791 Ignore-this: 3cda9b574d1fbc1cac683ed31c826051
792]
793[Update foolscap requirement to >= 0.6.1. fixes #1329
794david-sarah@jacaranda.org**20110119060639
795 Ignore-this: 47908e13d1c79e74b9ebb9df934b3cf1
796]
797[Add support to bin/tahoe for invoking a runner command prefixed with @, with the Tahoe libraries on the PYTHONPATH. This is documented in 'tahoe debug --help'.
798david-sarah@jacaranda.org**20110119051137
799 Ignore-this: 65fd13a23670aea3825a706f45a7019f
800]
801[bin/tahoe-script.template, src/windows/fixups.py: simplify the method of stripping initial arguments in sys.argv on Windows. This helps with bb-freeze and running tahoe via 'coverage'. Also includes some wording changes and minor refactoring of bin/tahoe-script.template. refs #585, #1303
802david-sarah@jacaranda.org**20110119045324
803 Ignore-this: 756e83c5eae7dabac31290b98a0e5a99
804]
805[Change misc/build_helpers/test-with-fake-pkg to use 'setup.py trial'. refs #1296
806david-sarah@jacaranda.org**20110119042401
807 Ignore-this: e1518b6f43becf47d5a956bb710a9dcb
808]
809[Makefile: update 'make clean' to delete the setuptools_trial egg(s).
810david-sarah@jacaranda.org**20110119025053
811 Ignore-this: ec373228f3a169c7070633e3b89ec1d
812]
813[Change 'setup.py trial' and 'setup.py test' to use 'bin/tahoe debug trial'. refs #1296
814david-sarah@jacaranda.org**20110119024532
815 Ignore-this: 43df1a50435c794cfa60ecca71a46b10
816]
817[src/allmydata/test/test_cli.py: add test for 'tahoe debug trial' options help. refs #1296
818david-sarah@jacaranda.org**20110119024224
819 Ignore-this: e9f7a67724b60c11a34efbce9a83a5cb
820]
821[Makefile: update 'make clean' to avoid deleting the setuptools_darcs egg.
822david-sarah@jacaranda.org**20110119021958
823 Ignore-this: 908673ddd30ab88db5af8c8d80a74eb1
824]
825[Add src/allmydata/test/trialtest.py needed by tests for 'tahoe debug trial'. refs #1296
826david-sarah@jacaranda.org**20110119020239
827 Ignore-this: 58d468dbd869c2e6c85552710ed47ffe
828]
829[Tests for 'tahoe debug trial' (rebased and fixed to work with Twisted 10.2). refs #1296
830david-sarah@jacaranda.org**20110119013859
831 Ignore-this: bb2ea70e5c3c841713ae38744b80980f
832]
833[Documentation for 'tahoe debug trial' (rebased for trunk). refs #1296
834david-sarah@jacaranda.org**20110118205729
835 Ignore-this: 3a4a4c2d23864851cb24c32a5b7962b4
836]
837[Make 'mock' a run-time rather than setup-time dependency. This is necessary in order for 'tahoe debug trial' to work. refs #1296
838david-sarah@jacaranda.org**20110118205114
839 Ignore-this: 256c4fcd259eda02dd86ed163afc6497
840]
841[src/allmydata/scripts/debug.py: add 'tahoe debug trial' command (rebased for trunk). refs #1296
842david-sarah@jacaranda.org**20110118204659
843 Ignore-this: 19e5f96d15c14625d5969ca4ae10a3cc
844]
845[Remove setuptools_trial egg.
846david-sarah@jacaranda.org**20110110063306
847 Ignore-this: 329f5062db0c7914464c547a3957c596
848]
849[src/allmydata/webish.py: clean-ups and correction to a comment. Also change an open and write to use fileutil.write. See ref #1286 comment 13.
850david-sarah@jacaranda.org**20110117233152
851 Ignore-this: c4aa2f4286ad8a9fba9827d428f7fbe5
852]
853[setup: load the setuptools_darcs-1.2.12.egg that is bundled in the root of the source tree at setup.py time, and setup_require it. This is in order to make sure that its 'find all package data' plugin works to inform setuptools of all files which are under revision control, so that setuptools can include them in a distribution. By the way, this is ugly and horrible. refs #1054
854david-sarah@jacaranda.org**20110118065445
855 Ignore-this: b4b9d3798a9beb9c44943daf2722a51
856]
857[setup: bundle a copy of setuptools_darcs-1.2.12
858zooko@zooko.com**20110118062521
859 Ignore-this: 47e240417e0ff57a66d2f02f416a78fe
860 This is to work-around https://bitbucket.org/tarek/distribute/issue/55/revision-control-plugin-automatically-installed-as-a-build-dependency-is-not-present-when-another-build-dependency-is-being . refs #1054.
861]
862[NEWS: default reserved_space for new storage nodes is 1 GiB. refs #1208
863david-sarah@jacaranda.org**20110117235930
864 Ignore-this: 81c898890f51400b7229b4b6de69eb30
865]
866['tahoe debug catalog-shares': sort SIs and shnums
867Brian Warner <warner@lothar.com>**20110117095932
868 Ignore-this: f2c60da422178dfba6d03ff4957cf80c
869 
870 Without this, SIs or shnums could be emitted in random order, depending upon
871 what the filesystem happens to return.
872]
873[CLI: tests for ref #1305 (v2, remove spurious extra arg to create-alias in test)
874david-sarah@jacaranda.org**20110114040327
875 Ignore-this: 770b7117e66b04ced293b7b740b4a27f
876]
877[CLI: make 'tahoe create-alias' and 'tahoe add-alias' accept a trailing colon on the new alias name (v2, minor change not to rely on implicit Unicode conversion). Includes doc changes and news; tests in a separate patch. fixes #1305
878david-sarah@jacaranda.org**20110114034414
879 Ignore-this: 97e8e88d8b0f7c628b77db3adb67fa1b
880]
881[Improve 'tahoe ln' help text. Patch by David-Sarah. Closes #1230.
882Brian Warner <warner@lothar.com>**20110117081421
883 Ignore-this: ae0ab1525fd39c95500535d6d015e706
884]
885[Tolerate Twisted-10.2's endpoints, patch by David-Sarah. Closes #1286.
886Brian Warner <warner@lothar.com>**20110117074751
887 Ignore-this: 8875749e4cab0e444a8452e290647bb6
888 
889 The service generated by strports.service() changed in 10.2, and the ugly
890 private-attribute-reading hack we used to glean a kernel-allocated port
891 number (e.g. when using "tcp:0", especially during unit tests) broke, causing
892 Tahoe to be completely unusable with Twisted-10.2 . The new ugly
893 private-attribute-reading hack starts by figuring out what sort of service
894 was generated, then reads different attributes accordingly.
895 
896 This also hushes a warning when using schemeless strports strings like "0" or
897 "3456", by quietly prepending a "tcp:" scheme, since 10.2 complains about
898 those. It also adds getURL() and getPortnum() accessors to the "webish"
899 service, rather than having unit tests dig through _url and _portnum and such
900 to find out what they are.
901]
902[debian/control: add python-twisted-conch to dependencies. Closes #1095.
903Brian Warner <warner@lothar.com>**20110117071206
904 Ignore-this: 74714eeb8bd324d6124824f119468ab5
905]
906[Test changes to take account of ref #1311.
907david-sarah@jacaranda.org**20110117060540
908 Ignore-this: d787405b00a05d98abb34e5133a88b36
909]
910[create_node.py: add comments to default tahoe.cfg to clarify the meaning of each section. fixes #1311
911david-sarah@jacaranda.org**20110117052419
912 Ignore-this: a2b0bba6b347bb0b0247782ee9ea9419
913]
914[Undo the temporary hack to check the foolscap version. refs #1246
915david-sarah@jacaranda.org**20110117052042
916 Ignore-this: c58a8a5b91355a15d02b60c20a44bbd9
917]
918[misc/build_helpers/run_trial.py: fix pyflakes warning.
919david-sarah@jacaranda.org**20110115080456
920 Ignore-this: 95760a442fc397526a5d921510ec3843
921]
922[Set "reserved_space=1G" in newly-created storage nodes. Closes #1208.
923Brian Warner <warner@lothar.com>**20110116205822
924 Ignore-this: 2aac3dbb46e181ce7ae5e0af07bbb3bb
925]
926[Temporary hack to investigate whether we are getting the right version of foolscap on trunk. refs #1258
927david-sarah@jacaranda.org**20110116044959
928 Ignore-this: 4760970f9235dde07472ca980c24f75b
929]
930[Makefile: allow tarball upload when either BB_BRANCH=='trunk' or BB_BRANCH==''.
931david-sarah@jacaranda.org**20110115212211
932 Ignore-this: 358822b25e69bfe9651a561ec387ca7a
933]
934[misc/build_helpers/test-with-fake-dists.py: clean up directories and files only if they exist.
935david-sarah@jacaranda.org**20110115053011
936 Ignore-this: 7aa8fec370e12c62d9b56afcd55d17f
937]
938[misc/build_helpers/test-with-fake-dists.py: wrong arguments in comment.
939david-sarah@jacaranda.org**20110115045325
940 Ignore-this: 89322306ed4fb478af4988675fd4c968
941]
942[Attempt to fix test-with-fake-dist build step.
943david-sarah@jacaranda.org**20110115022651
944 Ignore-this: 9d7195dca59b79f93a5f527b1ae9e79e
945]
946[bin/tahoe-script.template: improve the error message if we end up running under Python 3. refs #1302
947david-sarah@jacaranda.org**20110112211628
948 Ignore-this: ee78f8e4bbd197e620cb0cc6b995ac46
949]
950[Makefile: Fix uploading of tarballs on trunk builds.
951david-sarah@jacaranda.org**20110109065851
952 Ignore-this: 864b06e39103f46dbb6ccb74e1e333d3
953]
954[docs/frontends/CLI.rst: fix the rst syntax to be as actually intended :-)
955david-sarah@jacaranda.org**20110109014057
956 Ignore-this: c11331670ba89d8601ba3782ffc4f32c
957]
958[docs/frontends/CLI.rst: really fix rst syntax error this time.
959david-sarah@jacaranda.org**20110109013914
960 Ignore-this: 59550154c9ab41488ddfdee8938d7bda
961]
962[docs/frontends/CLI.rst: fix rst syntax error.
963david-sarah@jacaranda.org**20110109010943
964 Ignore-this: 427444f5572115059c75fa1bd8371d51
965]
966[docs/frontends/CLI.rst: discuss commandline/output quoting issues and wildcards. refs #1135
967david-sarah@jacaranda.org**20110109010119
968 Ignore-this: 533938d89be878b404a8540aebdf68ad
969]
970[setup.py: add Python 2.7 trove classifier.
971david-sarah@jacaranda.org**20110108211212
972 Ignore-this: b479c0a1adf9b7a2d1fdc54abc6582e6
973]
974[docs/FTP-and-SFTP.rst: document issue in ref #1297. Remove known issue #1045 which is fixed. Also some cosmetic changes.
975david-sarah@jacaranda.org**20110108061038
976 Ignore-this: 8d9aa2e33f1054545f7bed47bf0e647d
977]
978[misc/build_helpers/show-tool-versions.py: remove attempts to show stdout.encoding and stderr.encoding that always printed None due to redirection. Also remove code to show os.path.supports_unicode_filenames which is not useful. refs #1251
979david-sarah@jacaranda.org**20110103015144
980 Ignore-this: 45e11431f7e2e0cebcb58e1841485cf8
981]
982[NEWS: 'top' for node processes, WUI formatting, removal of GUI apps, documentation updates, foolscap dependency. refs #174, #1219, #1225
983david-sarah@jacaranda.org**20110106005727
984 Ignore-this: f61ac58b4d10e635feb6f7391b1b48fe
985]
986[Makefile: update 'clean' target for files in bin/
987david-sarah@jacaranda.org**20110103052738
988 Ignore-this: 2bdbc4a50e13e508b66d0f65718c79b2
989]
990[docs: update performance.rst to describe the difference between already-uploaded and not-already-uploaded, to parameterize segment size, and to use "~A" to mean "approximately A"
991zooko@zooko.com**20110104065455
992 Ignore-this: 8df0d79a062ee19854c0211bd202f606
993]
994[bin/tahoe-script.template: On non-Windows, invoke support/bin/tahoe directly as a script (rather than via python), so that 'top' for example will show it as 'tahoe'. On Windows, simplify some code that set argv[0], which is never used. fixes #174
995david-sarah@jacaranda.org**20101127232650
996 Ignore-this: 42a86f3eecfdc1ea7b76a7cc68626898
997]
998[test_runner: avoid unnecessary use of non-ASCII.
999david-sarah@jacaranda.org**20110101100101
1000 Ignore-this: e2ff40dce6bb3b021306f2913d4e75df
1001]
1002[docs/quickstart.html: fix redundant, badly nested tag. refs #1284
1003david-sarah@jacaranda.org**20110102175159
1004 Ignore-this: 2ae9cc0b47d2e87b9eb64a0f517c4eef
1005]
1006[docs/quickstart.html: information about 'troublesome dependencies' and 'verified systems' de-emphasized by smaller italic font. Re-wrap so that the HTML source is readable (just about) as text. Minor wording tweaks. Improve organization by adding 'Windows Caveats' subsection. fixes #1284
1007david-sarah@jacaranda.org**20110102174212
1008 Ignore-this: e9dc57983974478200856651c5318fee
1009]
1010[NEWS: update entry for removal of Mac and Windows apps. refs #1282
1011david-sarah@jacaranda.org**20101226042245
1012 Ignore-this: c8099bc6e8235718d042c9a13c1e2425
1013]
1014[Move dependency imports from windows/depends.py (which has gone away) into src/allmydata/windows/tahoesvc.py. Also fix a pyflakes warning, and change the service display name from 'Allmydata Tahoe Node' to 'Tahoe-LAFS node'. refs #1282
1015david-sarah@jacaranda.org**20101226042100
1016 Ignore-this: ee45f324934e1251380206dbee6346d0
1017]
1018[Remove unmaintained Windows GUI app, except for windows/tahoesvc.py which is moved to src/allmydata/windows. refs #1282
1019david-sarah@jacaranda.org**20101226040237
1020 Ignore-this: cae37b6622a7dd5940acc7d3e6a98b90
1021]
1022[Remove the Makefile targets relating to the Mac GUI app. refs #1282
1023david-sarah@jacaranda.org**20101226025859
1024 Ignore-this: 75303be783974b41138744ec62b07965
1025]
1026[NEWS: remove unmaintained Mac GUI app. refs #1282
1027david-sarah@jacaranda.org**20101226020858
1028 Ignore-this: 40474a07f4a550b48563d35350be7ab5
1029]
1030[Remove unmaintained Mac GUI app. fixes #1282
1031david-sarah@jacaranda.org**20101226020508
1032 Ignore-this: b3613bf1abfd284d542bf7c753ec557a
1033]
1034[Remove src/allmydata/util/find_exe.py which is no longer used. fixes #1150
1035david-sarah@jacaranda.org**20101226023206
1036 Ignore-this: 7436c9b53bf210aed34a1a973cd9cace
1037]
1038[status_web_pages_review.darcs.patch
1039freestorm77@gmail.com**20110102034214
1040 Ignore-this: 29f1ecb36177f10f3f846b3d56b313b2
1041 
1042 I make some changes on status web pages
1043 
1044 status.xhtml:
1045 - Delete unused webform_css link
1046 - Align tables on the left
1047 
1048 tahoe-css:
1049 - Do some minor changes on code synthax
1050 - changes table.status-download-events style to look like other tables
1051 
1052 status.py:
1053 - Align table on the left
1054 - Changes table header
1055 - Add heading tags
1056 - Modify google api graph: add image border, calculate height to feet data
1057 
1058 signed-off-by: zooko@zooko.com
1059 fixes #1219
1060]
1061[test_storage.py: fix a pyflakes unused import warning.
1062david-sarah@jacaranda.org**20101231220756
1063 Ignore-this: df08231540cb7dff9d2b038e47ab30ee
1064]
1065[test_storage.py: leave at least 512 MiB free when running test_large_share. refs #1195
1066david-sarah@jacaranda.org**20101231203215
1067 Ignore-this: b2144c0341c3452b5d4ba219e284ea0e
1068]
1069[storage: use fileutil's version of get_disk_stats() and get_available_space(), use mockery/fakery in tests, enable large share test on platforms with sparse files and if > 4 GiB of disk space is currently available
1070zooko@zooko.com**20100910173629
1071 Ignore-this: 1304f1164c661de6d5304f993eb9b27b
1072]
1073[fileutil: copy in the get_disk_stats() and get_available_space() functions from storage/server.py
1074zooko@zooko.com**20100910173520
1075 Ignore-this: 8b15569715f710f4fc5092f7ca109253
1076]
1077[Update foolscap version requirement to 0.6.0, to address http://foolscap.lothar.com/trac/ticket/167
1078david-sarah@jacaranda.org**20101231060039
1079 Ignore-this: 98d2b8086a1a500b9f4565bca5a3810
1080]
1081[docs/webapi.rst: typos.
1082david-sarah@jacaranda.org**20101230034422
1083 Ignore-this: d1f5166d72cc711f7e0d9981eac9105e
1084]
1085[docs/webapi.rst: capitalization, formatting of section on URL character encoding, and a correction about Internet Explorer.
1086david-sarah@jacaranda.org**20101230034049
1087 Ignore-this: b3b9819d2fb264b4cdc5c8afd4e8c48d
1088]
1089[docs: corrections and clarifications.
1090david-sarah@jacaranda.org**20101227051056
1091 Ignore-this: e33202858c7644c58f3f924b164294b6
1092]
1093[docs: more formatting cleanups and corrections. Spell webapi and wapi as web-API.
1094david-sarah@jacaranda.org**20101227050533
1095 Ignore-this: 18b23cbfb780df585d8a722a1ec63e94
1096]
1097[docs/debian.rst: bring description of building dependencies from source up-to-date, and change hostname from allmydata.com to tahoe-lafs.org.
1098david-sarah@jacaranda.org**20101212222912
1099 Ignore-this: f38462afc88b4475195610385a28391c
1100]
1101[docs/architecture.rst: correct rst syntax.
1102david-sarah@jacaranda.org**20101212202003
1103 Ignore-this: 3fbe12feb28bec6f1c63aedbc79aad21
1104]
1105[docs/architecture.rst: formatting.
1106david-sarah@jacaranda.org**20101212201719
1107 Ignore-this: 305fa5dfc2939355eaf6d0d2161eb1ff
1108]
1109[docs: linkification, wording improvements.
1110david-sarah@jacaranda.org**20101212201234
1111 Ignore-this: 4e67287f527a8bc728cfbd93255d2aae
1112]
1113[docs: formatting.
1114david-sarah@jacaranda.org**20101212201115
1115 Ignore-this: 2e0ed394ac7726651d3a4f2c4b0d3798
1116]
1117[docs/configuration.rst: more formatting tweaks; which -> that.
1118david-sarah@jacaranda.org**20101212195522
1119 Ignore-this: a7becb7021854ca5a90edd892b36fdd7
1120]
1121[docs/configuration.rst: more changes to formatting.
1122david-sarah@jacaranda.org**20101212194511
1123 Ignore-this: 491aac33e5f5268d224359f1447d10be
1124]
1125[docs/configuration.rst: changes to formatting (mainly putting commands and filenames in monospace).
1126david-sarah@jacaranda.org**20101212181828
1127 Ignore-this: 8a1480e2d5f43bee678476424615b50f
1128]
1129[scripts/backupdb.py: more accurate comment about path field.
1130david-sarah@jacaranda.org**20101212170320
1131 Ignore-this: 50e47a2228a85207bbcd188a78a0d4e6
1132]
1133[scripts/cli.py: fix missing 'put' in usage example for 'tahoe put'.
1134david-sarah@jacaranda.org**20101212170207
1135 Ignore-this: 2cbadf066fff611fc03d3c0ff97ce6ec
1136]
1137[docs/frontends/CLI.rst: changes to formatting (mainly putting commands and filenames in monospace), and to command syntax to reflect that DIRCAP/... is accepted. Clarify the syntax of 'tahoe put' and other minor corrections. Tahoe -> Tahoe-LAFS.
1138david-sarah@jacaranda.org**20101212165800
1139 Ignore-this: a123ef6b564aa8624d1e79c97068ea12
1140]
1141[docs/frontends/CLI.rst: Unicode arguments to 'tahoe' work on Windows as of v1.7.1.
1142david-sarah@jacaranda.org**20101212063740
1143 Ignore-this: 3977a99dfa86ac33a44171deaf43aaab
1144]
1145[docs/known_issues.rst: fix title and linkify another URL. refs #1225
1146david-sarah@jacaranda.org**20101212062817
1147 Ignore-this: cc91287f7fb51c23440b3d2fe79c449c
1148]
1149[docs/known_issues.rst: fix an external link. refs #1225
1150david-sarah@jacaranda.org**20101212062435
1151 Ignore-this: b8cbf12f353131756c358965c48060ec
1152]
1153[Fix a link from uri.rst to dirnodes.rst. refs #1225
1154david-sarah@jacaranda.org**20101212054502
1155 Ignore-this: af6205299f5c9a33229cab259c00f9d5
1156]
1157[Fix a link from webapi.rst to FTP-and-SFTP.rst. refs #1225
1158david-sarah@jacaranda.org**20101212053435
1159 Ignore-this: 2b9f88678c3447ea860d6b61e8799858
1160]
1161[More specific hyperlink to architecture.rst from helper.rst. refs #1225
1162david-sarah@jacaranda.org**20101212052607
1163 Ignore-this: 50424c768fca481252fabf58424852dc
1164]
1165[Update hyperlinks between docs, and linkify some external references. refs #1225
1166david-sarah@jacaranda.org**20101212051459
1167 Ignore-this: cd43a4c3d3de1f832abfa88d5fc4ace1
1168]
1169[docs/specifications/dirnodes.rst: fix references to mutable.rst. refs #1225
1170david-sarah@jacaranda.org**20101212012720
1171 Ignore-this: 6819b4b4e06e947ee48b365e840db37d
1172]
1173[docs/specifications/mutable.rst: correct the magic string for v1 mutable containers. refs #1225
1174david-sarah@jacaranda.org**20101212011400
1175 Ignore-this: 99a5fcdd40cef83dbb08f323f6cdaaca
1176]
1177[Move .txt files in docs/frontends and docs/specifications to .rst. refs #1225
1178david-sarah@jacaranda.org**20101212010251
1179 Ignore-this: 8796d35d928370f7dc6ad2dafdc1c0fe
1180]
1181[Convert docs/frontends and docs/specifications to reStructuredText format (not including file moves).
1182david-sarah@jacaranda.org**20101212004632
1183 Ignore-this: e3ceb2d832d73875abe48624ddbb5622
1184]
1185[scripts/cli.py: remove the disclaimer in the help for 'tahoe cp' that it does not handle non-ASCII filenames well. (At least, we intend to handle them.)
1186david-sarah@jacaranda.org**20101130002145
1187 Ignore-this: 94c003efaa20b9eb4a83503d79844ca
1188]
1189[relnotes.txt: fifth -> sixth labor-of-love release
1190zooko@zooko.com**20101129045647
1191 Ignore-this: 21c245015268b38916e3a138d256c09d
1192]
1193[Makefile: BB_BRANCH is set to the empty string for trunk, not the string 'trunk'.
1194david-sarah@jacaranda.org**20101128233512
1195 Ignore-this: 5a7ef8eb10475636d21b91e25b56c369
1196]
1197[relnotes.txt: eleventh -> twelfth release.
1198david-sarah@jacaranda.org**20101128223321
1199 Ignore-this: 1e26410156a665271c1170803dea2c0d
1200]
1201[relnotes.tst: point to known_issues.rst, not known_issues.txt.
1202david-sarah@jacaranda.org**20101128222918
1203 Ignore-this: 60194eb4544cac446fe4f60b3e34b887
1204]
1205[quickstart.html: fix link to point to allmydata-tahoe-1.8.1.zip.
1206david-sarah@jacaranda.org**20101128221728
1207 Ignore-this: 7b3ee86f8256aa12f5d862f689f3ee29
1208]
1209[TAG allmydata-tahoe-1.8.1
1210david-sarah@jacaranda.org**20101128212336
1211 Ignore-this: 9c18bdeaef4822f590d2a0d879e00621
1212]
1213Patch bundle hash:
12142a5436643847f4294061f1182d078ec52424df11