From 63c8c6574745374a7b62479f2ce983aa11502cc2 Mon Sep 17 00:00:00 2001
From: Kevan Carstensen <kevan@isnotajoke.com>
Date: Wed, 10 Feb 2010 18:43:18 -0800
Subject: [PATCH] Alter CLI utilities to handle nonexistent aliases better

---
 src/allmydata/scripts/common.py         | 11 +++++++++++
 src/allmydata/scripts/slow_operation.py |  9 +++++++--
 src/allmydata/scripts/tahoe_backup.py   |  9 +++++++--
 src/allmydata/scripts/tahoe_check.py    | 15 ++++++++++++---
 src/allmydata/scripts/tahoe_cp.py       | 12 ++++++++++--
 src/allmydata/scripts/tahoe_get.py      |  9 +++++++--
 src/allmydata/scripts/tahoe_ls.py       |  9 +++++++--
 src/allmydata/scripts/tahoe_manifest.py |  9 +++++++--
 src/allmydata/scripts/tahoe_mkdir.py    |  8 ++++++--
 src/allmydata/scripts/tahoe_mv.py       | 15 ++++++++++++---
 src/allmydata/scripts/tahoe_put.py      | 11 ++++++++---
 src/allmydata/scripts/tahoe_rm.py       |  9 +++++++--
 src/allmydata/scripts/tahoe_webopen.py  | 10 ++++++++--
 13 files changed, 109 insertions(+), 27 deletions(-)

diff --git a/src/allmydata/scripts/common.py b/src/allmydata/scripts/common.py
index 24f9922e..7b6f78aa 100644
--- a/src/allmydata/scripts/common.py
+++ b/src/allmydata/scripts/common.py
@@ -134,6 +134,9 @@ def get_alias(aliases, path, default):
     # DefaultAliasMarker. We special-case strings with a recognized cap URI
     # prefix, to make it easy to access specific files/directories by their
     # caps.
+    # If the transformed alias is either not found in aliases, or is blank
+    # and default is not found in aliases, an UnknownAliasError is
+    # raised.
     path = path.strip()
     if uri.has_uri_prefix(path):
         # The only way to get a sub-path is to use URI:blah:./foo, and we
@@ -147,6 +150,10 @@ def get_alias(aliases, path, default):
         # no alias
         if default == None:
             return DefaultAliasMarker, path
+        if default not in aliases:
+            raise UnknownAliasError("No alias specified, and the default "
+                                    "'tahoe' alias doesn't exist. To create "
+                                    "it, use 'tahoe create-alias tahoe'.")
         return aliases[default], path
     if colon == 1 and default == None and platform_uses_lettercolon_drivename():
         # treat C:\why\must\windows\be\so\weird as a local path, not a tahoe
@@ -158,6 +165,10 @@ def get_alias(aliases, path, default):
         # "foo/bar:7"
         if default == None:
             return DefaultAliasMarker, path
+        if default not in aliases:
+            raise UnknownAliasError("No alias specified, and the default "
+                                    "'tahoe' alias doesn't exist. To create "
+                                    "it, use 'tahoe create-alias tahoe'.")
         return aliases[default], path
     if alias not in aliases:
         raise UnknownAliasError("Unknown alias '%s', please create it with 'tahoe add-alias' or 'tahoe create-alias'." % alias)
diff --git a/src/allmydata/scripts/slow_operation.py b/src/allmydata/scripts/slow_operation.py
index 1f8a99a1..3f0a9c59 100644
--- a/src/allmydata/scripts/slow_operation.py
+++ b/src/allmydata/scripts/slow_operation.py
@@ -1,6 +1,7 @@
 
 import os, time
-from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
+                                     UnknownAliasError
 from allmydata.scripts.common_http import do_http
 from allmydata.util import base32
 import urllib
@@ -17,7 +18,11 @@ class SlowOperationRunner:
             nodeurl += "/"
         self.nodeurl = nodeurl
         where = options.where
-        rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
+        try:
+            rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
+        except UnknownAliasError, e:
+            print >>stderr, "error: %s" % e.args[0]
+            return 1
         if path == '/':
             path = ''
         url = nodeurl + "uri/%s" % urllib.quote(rootcap)
diff --git a/src/allmydata/scripts/tahoe_backup.py b/src/allmydata/scripts/tahoe_backup.py
index f816eedd..a7b96b14 100644
--- a/src/allmydata/scripts/tahoe_backup.py
+++ b/src/allmydata/scripts/tahoe_backup.py
@@ -4,7 +4,8 @@ import time
 import urllib
 import simplejson
 import datetime
-from allmydata.scripts.common import get_alias, escape_path, DEFAULT_ALIAS
+from allmydata.scripts.common import get_alias, escape_path, DEFAULT_ALIAS, \
+                                     UnknownAliasError
 from allmydata.scripts.common_http import do_http
 from allmydata.util import time_format
 from allmydata.scripts import backupdb
@@ -92,7 +93,11 @@ class BackerUpper:
             print >>stderr, "ERROR: Unable to load backup db."
             return 1
 
-        rootcap, path = get_alias(options.aliases, options.to_dir, DEFAULT_ALIAS)
+        try:
+            rootcap, path = get_alias(options.aliases, options.to_dir, DEFAULT_ALIAS)
+        except UnknownAliasError, e:
+            print >>stderr, "error: %s" % e.args[0]
+            return 1
         to_url = nodeurl + "uri/%s/" % urllib.quote(rootcap)
         if path:
             to_url += escape_path(path)
diff --git a/src/allmydata/scripts/tahoe_check.py b/src/allmydata/scripts/tahoe_check.py
index 5c1a2387..6fdd9013 100644
--- a/src/allmydata/scripts/tahoe_check.py
+++ b/src/allmydata/scripts/tahoe_check.py
@@ -2,7 +2,8 @@
 import urllib
 import simplejson
 from twisted.protocols.basic import LineOnlyReceiver
-from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
+                                     UnknownAliasError
 from allmydata.scripts.common_http import do_http
 
 class Checker:
@@ -15,7 +16,11 @@ def check(options):
     if not nodeurl.endswith("/"):
         nodeurl += "/"
     where = options.where
-    rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
+    try:
+        rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
+    except UnknownAliasError, e:
+        print >>stderr, "error: %s" % e.args[0]
+        return 1
     if path == '/':
         path = ''
     url = nodeurl + "uri/%s" % urllib.quote(rootcap)
@@ -264,7 +269,11 @@ class DeepCheckStreamer(LineOnlyReceiver):
             nodeurl += "/"
         self.nodeurl = nodeurl
         where = options.where
-        rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
+        try:
+            rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
+        except UnknownAliasError, e:
+            print >>stderr, "error: %s" % e.args[0]
+            return 1
         if path == '/':
             path = ''
         url = nodeurl + "uri/%s" % urllib.quote(rootcap)
diff --git a/src/allmydata/scripts/tahoe_cp.py b/src/allmydata/scripts/tahoe_cp.py
index 0e55d6eb..2b82bb60 100644
--- a/src/allmydata/scripts/tahoe_cp.py
+++ b/src/allmydata/scripts/tahoe_cp.py
@@ -4,7 +4,8 @@ import urllib
 import simplejson
 from cStringIO import StringIO
 from twisted.python.failure import Failure
-from allmydata.scripts.common import get_alias, escape_path, DefaultAliasMarker
+from allmydata.scripts.common import get_alias, escape_path, \
+                                     DefaultAliasMarker, UnknownAliasError
 from allmydata.scripts.common_http import do_http
 from allmydata import uri
 
@@ -464,7 +465,11 @@ class Copier:
         destination_spec = self.options.destination
         recursive = self.options["recursive"]
 
-        target = self.get_target_info(destination_spec)
+        try:
+            target = self.get_target_info(destination_spec)
+        except UnknownAliasError, e:
+            self.to_stderr("error: %s" % e.args[0])
+            return 1
 
         try:
             sources = [] # list of (name, source object)
@@ -474,6 +479,9 @@ class Copier:
         except MissingSourceError, e:
             self.to_stderr("No such file or directory %s" % e.args[0])
             return 1
+        except UnknownAliasError, e:
+            self.to_stderr("error: %s" % e.args[0])
+            return 1
 
         have_source_dirs = bool([s for (name,s) in sources
                                  if isinstance(s, (LocalDirectorySource,
diff --git a/src/allmydata/scripts/tahoe_get.py b/src/allmydata/scripts/tahoe_get.py
index abcd927c..5b709569 100644
--- a/src/allmydata/scripts/tahoe_get.py
+++ b/src/allmydata/scripts/tahoe_get.py
@@ -1,6 +1,7 @@
 
 import urllib
-from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
+                                     UnknownAliasError
 from allmydata.scripts.common_http import do_http
 
 def get(options):
@@ -13,7 +14,11 @@ def get(options):
 
     if nodeurl[-1] != "/":
         nodeurl += "/"
-    rootcap, path = get_alias(aliases, from_file, DEFAULT_ALIAS)
+    try:
+        rootcap, path = get_alias(aliases, from_file, DEFAULT_ALIAS)
+    except UnknownAliasError, e:
+        print >>stderr, "error: %s" % e.args[0]
+        return 1
     url = nodeurl + "uri/%s" % urllib.quote(rootcap)
     if path:
         url += "/" + escape_path(path)
diff --git a/src/allmydata/scripts/tahoe_ls.py b/src/allmydata/scripts/tahoe_ls.py
index 6d71c713..a169d82b 100644
--- a/src/allmydata/scripts/tahoe_ls.py
+++ b/src/allmydata/scripts/tahoe_ls.py
@@ -1,7 +1,8 @@
 
 import urllib, time
 import simplejson
-from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
+                                     UnknownAliasError
 from allmydata.scripts.common_http import do_http
 
 def list(options):
@@ -15,7 +16,11 @@ def list(options):
         nodeurl += "/"
     if where.endswith("/"):
         where = where[:-1]
-    rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS)
+    try:
+        rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS)
+    except UnknownAliasError, e:
+        print >>stderr, "error: %s" % e.args[0]
+        return 1
     url = nodeurl + "uri/%s" % urllib.quote(rootcap)
     if path:
         # move where.endswith check here?
diff --git a/src/allmydata/scripts/tahoe_manifest.py b/src/allmydata/scripts/tahoe_manifest.py
index 5131aead..66f05a9b 100644
--- a/src/allmydata/scripts/tahoe_manifest.py
+++ b/src/allmydata/scripts/tahoe_manifest.py
@@ -3,7 +3,8 @@ import urllib, simplejson
 from twisted.protocols.basic import LineOnlyReceiver
 from allmydata.util.abbreviate import abbreviate_space_both
 from allmydata.scripts.slow_operation import SlowOperationRunner
-from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
+                                     UnknownAliasError
 from allmydata.scripts.common_http import do_http
 
 class FakeTransport:
@@ -25,7 +26,11 @@ class ManifestStreamer(LineOnlyReceiver):
             nodeurl += "/"
         self.nodeurl = nodeurl
         where = options.where
-        rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
+        try:
+            rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
+        except UnknownAliasError, e:
+            print >>stderr, "error: %s" % e.args[0]
+            return 1
         if path == '/':
             path = ''
         url = nodeurl + "uri/%s" % urllib.quote(rootcap)
diff --git a/src/allmydata/scripts/tahoe_mkdir.py b/src/allmydata/scripts/tahoe_mkdir.py
index 1c6f31a6..50223dc9 100644
--- a/src/allmydata/scripts/tahoe_mkdir.py
+++ b/src/allmydata/scripts/tahoe_mkdir.py
@@ -1,7 +1,7 @@
 
 import urllib
 from allmydata.scripts.common_http import do_http, check_http_error
-from allmydata.scripts.common import get_alias, DEFAULT_ALIAS
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, UnknownAliasError
 
 def mkdir(options):
     nodeurl = options['node-url']
@@ -12,7 +12,11 @@ def mkdir(options):
     if not nodeurl.endswith("/"):
         nodeurl += "/"
     if where:
-        rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS)
+        try:
+            rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS)
+        except UnknownAliasError, e:
+            print >>stderr, "error: %s" % e.args[0]
+            return 1
 
     if not where or not path:
         # create a new unlinked directory
diff --git a/src/allmydata/scripts/tahoe_mv.py b/src/allmydata/scripts/tahoe_mv.py
index abdfd6d7..208b720e 100644
--- a/src/allmydata/scripts/tahoe_mv.py
+++ b/src/allmydata/scripts/tahoe_mv.py
@@ -2,7 +2,8 @@
 import re
 import urllib
 import simplejson
-from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
+                                     UnknownAliasError
 from allmydata.scripts.common_http import do_http
 
 # this script is used for both 'mv' and 'ln'
@@ -17,7 +18,11 @@ def mv(options, mode="move"):
 
     if nodeurl[-1] != "/":
         nodeurl += "/"
-    rootcap, from_path = get_alias(aliases, from_file, DEFAULT_ALIAS)
+    try:
+        rootcap, from_path = get_alias(aliases, from_file, DEFAULT_ALIAS)
+    except UnknownAliasError, e:
+        print >>stderr, "error: %s" % e.args[0]
+        return 1
     from_url = nodeurl + "uri/%s" % urllib.quote(rootcap)
     if from_path:
         from_url += "/" + escape_path(from_path)
@@ -30,7 +35,11 @@ def mv(options, mode="move"):
     cap = str(cap)
 
     # now get the target
-    rootcap, path = get_alias(aliases, to_file, DEFAULT_ALIAS)
+    try:
+        rootcap, path = get_alias(aliases, to_file, DEFAULT_ALIAS)
+    except UnknownAliasError, e:
+        print >>stderr, "error: %s" % e.args[0]
+        return 1
     to_url = nodeurl + "uri/%s" % urllib.quote(rootcap)
     if path:
         to_url += "/" + escape_path(path)
diff --git a/src/allmydata/scripts/tahoe_put.py b/src/allmydata/scripts/tahoe_put.py
index 13a8306c..24a7e3ef 100644
--- a/src/allmydata/scripts/tahoe_put.py
+++ b/src/allmydata/scripts/tahoe_put.py
@@ -3,7 +3,8 @@ from cStringIO import StringIO
 import os.path
 import urllib
 from allmydata.scripts.common_http import do_http
-from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
+                                     UnknownAliasError
 
 def put(options):
     """
@@ -34,7 +35,7 @@ def put(options):
         #  /oops/subdir/foo : DISALLOWED
         #  ALIAS:foo  : aliases[ALIAS]/foo
         #  ALIAS:subdir/foo  : aliases[ALIAS]/subdir/foo
-        
+
         #  ALIAS:/oops/subdir/foo : DISALLOWED
         #  DIRCAP:./foo        : DIRCAP/foo
         #  DIRCAP:./subdir/foo : DIRCAP/subdir/foo
@@ -44,7 +45,11 @@ def put(options):
         if to_file.startswith("URI:SSK:"):
             url = nodeurl + "uri/%s" % urllib.quote(to_file)
         else:
-            rootcap, path = get_alias(aliases, to_file, DEFAULT_ALIAS)
+            try:
+                rootcap, path = get_alias(aliases, to_file, DEFAULT_ALIAS)
+            except UnknownAliasError, e:
+                print >>stderr, "error: %s" % e.args[0]
+                return 1
             if path.startswith("/"):
                 suggestion = to_file.replace("/", "", 1)
                 print >>stderr, "ERROR: The remote filename must not start with a slash"
diff --git a/src/allmydata/scripts/tahoe_rm.py b/src/allmydata/scripts/tahoe_rm.py
index 3e854e97..ba557b36 100644
--- a/src/allmydata/scripts/tahoe_rm.py
+++ b/src/allmydata/scripts/tahoe_rm.py
@@ -1,7 +1,8 @@
 
 import urllib
 from allmydata.scripts.common_http import do_http
-from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
+                                     UnknownAliasError
 
 def rm(options):
     """
@@ -15,7 +16,11 @@ def rm(options):
 
     if nodeurl[-1] != "/":
         nodeurl += "/"
-    rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS)
+    try:
+        rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS)
+    except UnknownAliasError, e:
+        print >>stderr, "error: %s" % e.args[0]
+        return 1
     assert path
     url = nodeurl + "uri/%s" % urllib.quote(rootcap)
     url += "/" + escape_path(path)
diff --git a/src/allmydata/scripts/tahoe_webopen.py b/src/allmydata/scripts/tahoe_webopen.py
index b4e13c14..37d157b0 100644
--- a/src/allmydata/scripts/tahoe_webopen.py
+++ b/src/allmydata/scripts/tahoe_webopen.py
@@ -1,14 +1,20 @@
 
-from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
+                                     UnknownAliasError
 import urllib
 
 def webopen(options, opener=None):
     nodeurl = options['node-url']
+    stderr = options.stderr
     if not nodeurl.endswith("/"):
         nodeurl += "/"
     where = options.where
     if where:
-        rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
+        try:
+            rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
+        except UnknownAliasError, e:
+            print >>stderr, "error: %s" % e.args[0]
+            return 1
         if path == '/':
             path = ''
         url = nodeurl + "uri/%s" % urllib.quote(rootcap)
-- 
2.45.2