| 1 | Wed Feb 10 18:43:18 PST 2010 Kevan Carstensen <kevan@isnotajoke.com> |
|---|
| 2 | * Alter CLI utilities to handle nonexistent aliases better |
|---|
| 3 | |
|---|
| 4 | New patches: |
|---|
| 5 | |
|---|
| 6 | [Alter CLI utilities to handle nonexistent aliases better |
|---|
| 7 | Kevan Carstensen <kevan@isnotajoke.com>**20100211024318 |
|---|
| 8 | Ignore-this: e698ea4a57f5fe27c24336581ca0cf65 |
|---|
| 9 | ] { |
|---|
| 10 | hunk ./src/allmydata/scripts/common.py 137 |
|---|
| 11 | # DefaultAliasMarker. We special-case strings with a recognized cap URI |
|---|
| 12 | # prefix, to make it easy to access specific files/directories by their |
|---|
| 13 | # caps. |
|---|
| 14 | + # If the transformed alias is either not found in aliases, or is blank |
|---|
| 15 | + # and default is not found in aliases, an UnknownAliasError is |
|---|
| 16 | + # raised. |
|---|
| 17 | path = path.strip() |
|---|
| 18 | if uri.has_uri_prefix(path): |
|---|
| 19 | # The only way to get a sub-path is to use URI:blah:./foo, and we |
|---|
| 20 | hunk ./src/allmydata/scripts/common.py 153 |
|---|
| 21 | # no alias |
|---|
| 22 | if default == None: |
|---|
| 23 | return DefaultAliasMarker, path |
|---|
| 24 | + if default not in aliases: |
|---|
| 25 | + raise UnknownAliasError("No alias specified, and the default " |
|---|
| 26 | + "'tahoe' alias doesn't exist. To create " |
|---|
| 27 | + "it, use 'tahoe create-alias tahoe'.") |
|---|
| 28 | return aliases[default], path |
|---|
| 29 | if colon == 1 and default == None and platform_uses_lettercolon_drivename(): |
|---|
| 30 | # treat C:\why\must\windows\be\so\weird as a local path, not a tahoe |
|---|
| 31 | hunk ./src/allmydata/scripts/common.py 168 |
|---|
| 32 | # "foo/bar:7" |
|---|
| 33 | if default == None: |
|---|
| 34 | return DefaultAliasMarker, path |
|---|
| 35 | + if default not in aliases: |
|---|
| 36 | + raise UnknownAliasError("No alias specified, and the default " |
|---|
| 37 | + "'tahoe' alias doesn't exist. To create " |
|---|
| 38 | + "it, use 'tahoe create-alias tahoe'.") |
|---|
| 39 | return aliases[default], path |
|---|
| 40 | if alias not in aliases: |
|---|
| 41 | raise UnknownAliasError("Unknown alias '%s', please create it with 'tahoe add-alias' or 'tahoe create-alias'." % alias) |
|---|
| 42 | hunk ./src/allmydata/scripts/slow_operation.py 3 |
|---|
| 43 | |
|---|
| 44 | import os, time |
|---|
| 45 | -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path |
|---|
| 46 | +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
|---|
| 47 | + UnknownAliasError |
|---|
| 48 | from allmydata.scripts.common_http import do_http |
|---|
| 49 | from allmydata.util import base32 |
|---|
| 50 | import urllib |
|---|
| 51 | hunk ./src/allmydata/scripts/slow_operation.py 21 |
|---|
| 52 | nodeurl += "/" |
|---|
| 53 | self.nodeurl = nodeurl |
|---|
| 54 | where = options.where |
|---|
| 55 | - rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) |
|---|
| 56 | + try: |
|---|
| 57 | + rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) |
|---|
| 58 | + except UnknownAliasError, e: |
|---|
| 59 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 60 | + return 1 |
|---|
| 61 | if path == '/': |
|---|
| 62 | path = '' |
|---|
| 63 | url = nodeurl + "uri/%s" % urllib.quote(rootcap) |
|---|
| 64 | hunk ./src/allmydata/scripts/tahoe_backup.py 7 |
|---|
| 65 | import urllib |
|---|
| 66 | import simplejson |
|---|
| 67 | import datetime |
|---|
| 68 | -from allmydata.scripts.common import get_alias, escape_path, DEFAULT_ALIAS |
|---|
| 69 | +from allmydata.scripts.common import get_alias, escape_path, DEFAULT_ALIAS, \ |
|---|
| 70 | + UnknownAliasError |
|---|
| 71 | from allmydata.scripts.common_http import do_http |
|---|
| 72 | from allmydata.util import time_format |
|---|
| 73 | from allmydata.scripts import backupdb |
|---|
| 74 | hunk ./src/allmydata/scripts/tahoe_backup.py 96 |
|---|
| 75 | print >>stderr, "ERROR: Unable to load backup db." |
|---|
| 76 | return 1 |
|---|
| 77 | |
|---|
| 78 | - rootcap, path = get_alias(options.aliases, options.to_dir, DEFAULT_ALIAS) |
|---|
| 79 | + try: |
|---|
| 80 | + rootcap, path = get_alias(options.aliases, options.to_dir, DEFAULT_ALIAS) |
|---|
| 81 | + except UnknownAliasError, e: |
|---|
| 82 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 83 | + return 1 |
|---|
| 84 | to_url = nodeurl + "uri/%s/" % urllib.quote(rootcap) |
|---|
| 85 | if path: |
|---|
| 86 | to_url += escape_path(path) |
|---|
| 87 | hunk ./src/allmydata/scripts/tahoe_check.py 5 |
|---|
| 88 | import urllib |
|---|
| 89 | import simplejson |
|---|
| 90 | from twisted.protocols.basic import LineOnlyReceiver |
|---|
| 91 | -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path |
|---|
| 92 | +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
|---|
| 93 | + UnknownAliasError |
|---|
| 94 | from allmydata.scripts.common_http import do_http |
|---|
| 95 | |
|---|
| 96 | class Checker: |
|---|
| 97 | hunk ./src/allmydata/scripts/tahoe_check.py 19 |
|---|
| 98 | if not nodeurl.endswith("/"): |
|---|
| 99 | nodeurl += "/" |
|---|
| 100 | where = options.where |
|---|
| 101 | - rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) |
|---|
| 102 | + try: |
|---|
| 103 | + rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) |
|---|
| 104 | + except UnknownAliasError, e: |
|---|
| 105 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 106 | + return 1 |
|---|
| 107 | if path == '/': |
|---|
| 108 | path = '' |
|---|
| 109 | url = nodeurl + "uri/%s" % urllib.quote(rootcap) |
|---|
| 110 | hunk ./src/allmydata/scripts/tahoe_check.py 272 |
|---|
| 111 | nodeurl += "/" |
|---|
| 112 | self.nodeurl = nodeurl |
|---|
| 113 | where = options.where |
|---|
| 114 | - rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) |
|---|
| 115 | + try: |
|---|
| 116 | + rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) |
|---|
| 117 | + except UnknownAliasError, e: |
|---|
| 118 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 119 | + return 1 |
|---|
| 120 | if path == '/': |
|---|
| 121 | path = '' |
|---|
| 122 | url = nodeurl + "uri/%s" % urllib.quote(rootcap) |
|---|
| 123 | hunk ./src/allmydata/scripts/tahoe_cp.py 7 |
|---|
| 124 | import simplejson |
|---|
| 125 | from cStringIO import StringIO |
|---|
| 126 | from twisted.python.failure import Failure |
|---|
| 127 | -from allmydata.scripts.common import get_alias, escape_path, DefaultAliasMarker |
|---|
| 128 | +from allmydata.scripts.common import get_alias, escape_path, \ |
|---|
| 129 | + DefaultAliasMarker, UnknownAliasError |
|---|
| 130 | from allmydata.scripts.common_http import do_http |
|---|
| 131 | from allmydata import uri |
|---|
| 132 | |
|---|
| 133 | hunk ./src/allmydata/scripts/tahoe_cp.py 468 |
|---|
| 134 | destination_spec = self.options.destination |
|---|
| 135 | recursive = self.options["recursive"] |
|---|
| 136 | |
|---|
| 137 | - target = self.get_target_info(destination_spec) |
|---|
| 138 | + try: |
|---|
| 139 | + target = self.get_target_info(destination_spec) |
|---|
| 140 | + except UnknownAliasError, e: |
|---|
| 141 | + self.to_stderr("error: %s" % e.args[0]) |
|---|
| 142 | + return 1 |
|---|
| 143 | |
|---|
| 144 | try: |
|---|
| 145 | sources = [] # list of (name, source object) |
|---|
| 146 | hunk ./src/allmydata/scripts/tahoe_cp.py 482 |
|---|
| 147 | except MissingSourceError, e: |
|---|
| 148 | self.to_stderr("No such file or directory %s" % e.args[0]) |
|---|
| 149 | return 1 |
|---|
| 150 | + except UnknownAliasError, e: |
|---|
| 151 | + self.to_stderr("error: %s" % e.args[0]) |
|---|
| 152 | + return 1 |
|---|
| 153 | |
|---|
| 154 | have_source_dirs = bool([s for (name,s) in sources |
|---|
| 155 | if isinstance(s, (LocalDirectorySource, |
|---|
| 156 | hunk ./src/allmydata/scripts/tahoe_get.py 3 |
|---|
| 157 | |
|---|
| 158 | import urllib |
|---|
| 159 | -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path |
|---|
| 160 | +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
|---|
| 161 | + UnknownAliasError |
|---|
| 162 | from allmydata.scripts.common_http import do_http |
|---|
| 163 | |
|---|
| 164 | def get(options): |
|---|
| 165 | hunk ./src/allmydata/scripts/tahoe_get.py 17 |
|---|
| 166 | |
|---|
| 167 | if nodeurl[-1] != "/": |
|---|
| 168 | nodeurl += "/" |
|---|
| 169 | - rootcap, path = get_alias(aliases, from_file, DEFAULT_ALIAS) |
|---|
| 170 | + try: |
|---|
| 171 | + rootcap, path = get_alias(aliases, from_file, DEFAULT_ALIAS) |
|---|
| 172 | + except UnknownAliasError, e: |
|---|
| 173 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 174 | + return 1 |
|---|
| 175 | url = nodeurl + "uri/%s" % urllib.quote(rootcap) |
|---|
| 176 | if path: |
|---|
| 177 | url += "/" + escape_path(path) |
|---|
| 178 | hunk ./src/allmydata/scripts/tahoe_ls.py 4 |
|---|
| 179 | |
|---|
| 180 | import urllib, time |
|---|
| 181 | import simplejson |
|---|
| 182 | -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path |
|---|
| 183 | +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
|---|
| 184 | + UnknownAliasError |
|---|
| 185 | from allmydata.scripts.common_http import do_http |
|---|
| 186 | |
|---|
| 187 | def list(options): |
|---|
| 188 | hunk ./src/allmydata/scripts/tahoe_ls.py 19 |
|---|
| 189 | nodeurl += "/" |
|---|
| 190 | if where.endswith("/"): |
|---|
| 191 | where = where[:-1] |
|---|
| 192 | - rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS) |
|---|
| 193 | + try: |
|---|
| 194 | + rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS) |
|---|
| 195 | + except UnknownAliasError, e: |
|---|
| 196 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 197 | + return 1 |
|---|
| 198 | url = nodeurl + "uri/%s" % urllib.quote(rootcap) |
|---|
| 199 | if path: |
|---|
| 200 | # move where.endswith check here? |
|---|
| 201 | hunk ./src/allmydata/scripts/tahoe_manifest.py 6 |
|---|
| 202 | from twisted.protocols.basic import LineOnlyReceiver |
|---|
| 203 | from allmydata.util.abbreviate import abbreviate_space_both |
|---|
| 204 | from allmydata.scripts.slow_operation import SlowOperationRunner |
|---|
| 205 | -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path |
|---|
| 206 | +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
|---|
| 207 | + UnknownAliasError |
|---|
| 208 | from allmydata.scripts.common_http import do_http |
|---|
| 209 | |
|---|
| 210 | class FakeTransport: |
|---|
| 211 | hunk ./src/allmydata/scripts/tahoe_manifest.py 29 |
|---|
| 212 | nodeurl += "/" |
|---|
| 213 | self.nodeurl = nodeurl |
|---|
| 214 | where = options.where |
|---|
| 215 | - rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) |
|---|
| 216 | + try: |
|---|
| 217 | + rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) |
|---|
| 218 | + except UnknownAliasError, e: |
|---|
| 219 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 220 | + return 1 |
|---|
| 221 | if path == '/': |
|---|
| 222 | path = '' |
|---|
| 223 | url = nodeurl + "uri/%s" % urllib.quote(rootcap) |
|---|
| 224 | hunk ./src/allmydata/scripts/tahoe_mkdir.py 4 |
|---|
| 225 | |
|---|
| 226 | import urllib |
|---|
| 227 | from allmydata.scripts.common_http import do_http, check_http_error |
|---|
| 228 | -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS |
|---|
| 229 | +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, UnknownAliasError |
|---|
| 230 | |
|---|
| 231 | def mkdir(options): |
|---|
| 232 | nodeurl = options['node-url'] |
|---|
| 233 | hunk ./src/allmydata/scripts/tahoe_mkdir.py 15 |
|---|
| 234 | if not nodeurl.endswith("/"): |
|---|
| 235 | nodeurl += "/" |
|---|
| 236 | if where: |
|---|
| 237 | - rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS) |
|---|
| 238 | + try: |
|---|
| 239 | + rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS) |
|---|
| 240 | + except UnknownAliasError, e: |
|---|
| 241 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 242 | + return 1 |
|---|
| 243 | |
|---|
| 244 | if not where or not path: |
|---|
| 245 | # create a new unlinked directory |
|---|
| 246 | hunk ./src/allmydata/scripts/tahoe_mv.py 5 |
|---|
| 247 | import re |
|---|
| 248 | import urllib |
|---|
| 249 | import simplejson |
|---|
| 250 | -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path |
|---|
| 251 | +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
|---|
| 252 | + UnknownAliasError |
|---|
| 253 | from allmydata.scripts.common_http import do_http |
|---|
| 254 | |
|---|
| 255 | # this script is used for both 'mv' and 'ln' |
|---|
| 256 | hunk ./src/allmydata/scripts/tahoe_mv.py 21 |
|---|
| 257 | |
|---|
| 258 | if nodeurl[-1] != "/": |
|---|
| 259 | nodeurl += "/" |
|---|
| 260 | - rootcap, from_path = get_alias(aliases, from_file, DEFAULT_ALIAS) |
|---|
| 261 | + try: |
|---|
| 262 | + rootcap, from_path = get_alias(aliases, from_file, DEFAULT_ALIAS) |
|---|
| 263 | + except UnknownAliasError, e: |
|---|
| 264 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 265 | + return 1 |
|---|
| 266 | from_url = nodeurl + "uri/%s" % urllib.quote(rootcap) |
|---|
| 267 | if from_path: |
|---|
| 268 | from_url += "/" + escape_path(from_path) |
|---|
| 269 | hunk ./src/allmydata/scripts/tahoe_mv.py 38 |
|---|
| 270 | cap = str(cap) |
|---|
| 271 | |
|---|
| 272 | # now get the target |
|---|
| 273 | - rootcap, path = get_alias(aliases, to_file, DEFAULT_ALIAS) |
|---|
| 274 | + try: |
|---|
| 275 | + rootcap, path = get_alias(aliases, to_file, DEFAULT_ALIAS) |
|---|
| 276 | + except UnknownAliasError, e: |
|---|
| 277 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 278 | + return 1 |
|---|
| 279 | to_url = nodeurl + "uri/%s" % urllib.quote(rootcap) |
|---|
| 280 | if path: |
|---|
| 281 | to_url += "/" + escape_path(path) |
|---|
| 282 | hunk ./src/allmydata/scripts/tahoe_put.py 6 |
|---|
| 283 | import os.path |
|---|
| 284 | import urllib |
|---|
| 285 | from allmydata.scripts.common_http import do_http |
|---|
| 286 | -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path |
|---|
| 287 | +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
|---|
| 288 | + UnknownAliasError |
|---|
| 289 | |
|---|
| 290 | def put(options): |
|---|
| 291 | """ |
|---|
| 292 | hunk ./src/allmydata/scripts/tahoe_put.py 38 |
|---|
| 293 | # /oops/subdir/foo : DISALLOWED |
|---|
| 294 | # ALIAS:foo : aliases[ALIAS]/foo |
|---|
| 295 | # ALIAS:subdir/foo : aliases[ALIAS]/subdir/foo |
|---|
| 296 | - |
|---|
| 297 | + |
|---|
| 298 | # ALIAS:/oops/subdir/foo : DISALLOWED |
|---|
| 299 | # DIRCAP:./foo : DIRCAP/foo |
|---|
| 300 | # DIRCAP:./subdir/foo : DIRCAP/subdir/foo |
|---|
| 301 | hunk ./src/allmydata/scripts/tahoe_put.py 48 |
|---|
| 302 | if to_file.startswith("URI:SSK:"): |
|---|
| 303 | url = nodeurl + "uri/%s" % urllib.quote(to_file) |
|---|
| 304 | else: |
|---|
| 305 | - rootcap, path = get_alias(aliases, to_file, DEFAULT_ALIAS) |
|---|
| 306 | + try: |
|---|
| 307 | + rootcap, path = get_alias(aliases, to_file, DEFAULT_ALIAS) |
|---|
| 308 | + except UnknownAliasError, e: |
|---|
| 309 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 310 | + return 1 |
|---|
| 311 | if path.startswith("/"): |
|---|
| 312 | suggestion = to_file.replace("/", "", 1) |
|---|
| 313 | print >>stderr, "ERROR: The remote filename must not start with a slash" |
|---|
| 314 | hunk ./src/allmydata/scripts/tahoe_rm.py 4 |
|---|
| 315 | |
|---|
| 316 | import urllib |
|---|
| 317 | from allmydata.scripts.common_http import do_http |
|---|
| 318 | -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path |
|---|
| 319 | +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
|---|
| 320 | + UnknownAliasError |
|---|
| 321 | |
|---|
| 322 | def rm(options): |
|---|
| 323 | """ |
|---|
| 324 | hunk ./src/allmydata/scripts/tahoe_rm.py 19 |
|---|
| 325 | |
|---|
| 326 | if nodeurl[-1] != "/": |
|---|
| 327 | nodeurl += "/" |
|---|
| 328 | - rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS) |
|---|
| 329 | + try: |
|---|
| 330 | + rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS) |
|---|
| 331 | + except UnknownAliasError, e: |
|---|
| 332 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 333 | + return 1 |
|---|
| 334 | assert path |
|---|
| 335 | url = nodeurl + "uri/%s" % urllib.quote(rootcap) |
|---|
| 336 | url += "/" + escape_path(path) |
|---|
| 337 | hunk ./src/allmydata/scripts/tahoe_webopen.py 2 |
|---|
| 338 | |
|---|
| 339 | -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path |
|---|
| 340 | +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
|---|
| 341 | + UnknownAliasError |
|---|
| 342 | import urllib |
|---|
| 343 | |
|---|
| 344 | def webopen(options, opener=None): |
|---|
| 345 | hunk ./src/allmydata/scripts/tahoe_webopen.py 8 |
|---|
| 346 | nodeurl = options['node-url'] |
|---|
| 347 | + stderr = options.stderr |
|---|
| 348 | if not nodeurl.endswith("/"): |
|---|
| 349 | nodeurl += "/" |
|---|
| 350 | where = options.where |
|---|
| 351 | hunk ./src/allmydata/scripts/tahoe_webopen.py 13 |
|---|
| 352 | if where: |
|---|
| 353 | - rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) |
|---|
| 354 | + try: |
|---|
| 355 | + rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) |
|---|
| 356 | + except UnknownAliasError, e: |
|---|
| 357 | + print >>stderr, "error: %s" % e.args[0] |
|---|
| 358 | + return 1 |
|---|
| 359 | if path == '/': |
|---|
| 360 | path = '' |
|---|
| 361 | url = nodeurl + "uri/%s" % urllib.quote(rootcap) |
|---|
| 362 | } |
|---|
| 363 | |
|---|
| 364 | Context: |
|---|
| 365 | |
|---|
| 366 | [adding pycrypto to the auto dependencies |
|---|
| 367 | secorp@allmydata.com**20100206054314 |
|---|
| 368 | Ignore-this: b873fc00a6a5b001d30d479e6053cf2f |
|---|
| 369 | ] |
|---|
| 370 | [docs running.html - "tahoe run ." does not work with the current installation, replaced with "tahoe start ." |
|---|
| 371 | secorp@allmydata.com**20100206165320 |
|---|
| 372 | Ignore-this: fdb2dcb0e417d303cd43b1951a4f8c03 |
|---|
| 373 | ] |
|---|
| 374 | [code coverage: replace figleaf with coverage.py, should work on py2.6 now. |
|---|
| 375 | Brian Warner <warner@lothar.com>**20100203165421 |
|---|
| 376 | Ignore-this: 46ab590360be6a385cb4fc4e68b6b42c |
|---|
| 377 | |
|---|
| 378 | It still lacks the right HTML report (the builtin report is very pretty, but |
|---|
| 379 | lacks the "lines uncovered" numbers that I want), and the half-finished |
|---|
| 380 | delta-from-last-run measurements. |
|---|
| 381 | ] |
|---|
| 382 | [More comprehensive changes and ticket references for NEWS |
|---|
| 383 | david-sarah@jacaranda.org**20100202061256 |
|---|
| 384 | Ignore-this: 696cf0106e8a7fd388afc5b55fba8a1b |
|---|
| 385 | ] |
|---|
| 386 | [docs: install.html: link into Python 2.5.5 download page |
|---|
| 387 | zooko@zooko.com**20100202065852 |
|---|
| 388 | Ignore-this: 1a9471b8175b7de5741d8445a7ede29d |
|---|
| 389 | ] |
|---|
| 390 | [TAG allmydata-tahoe-1.6.0 |
|---|
| 391 | zooko@zooko.com**20100202061125 |
|---|
| 392 | Ignore-this: dee6ade7ac1452cf5d1d9c69a8146d84 |
|---|
| 393 | ] |
|---|
| 394 | Patch bundle hash: |
|---|
| 395 | 08b3b81c318baadf54c58f8b2b61eafbd4db3b0e |
|---|