CLI: add 'ln', just like move but without the delete
authorBrian Warner <warner@allmydata.com>
Tue, 20 May 2008 20:30:31 +0000 (13:30 -0700)
committerBrian Warner <warner@allmydata.com>
Tue, 20 May 2008 20:30:31 +0000 (13:30 -0700)
src/allmydata/scripts/cli.py
src/allmydata/scripts/tahoe_mv.py
src/allmydata/test/test_system.py

index 56a1b88e6ca639a42e8c1ad311cd49c088eeb9f7..f965e24b70397be179a3ae316844f89f8428fb09 100644 (file)
@@ -160,6 +160,14 @@ class MvOptions(VDriveOptions):
     def getSynopsis(self):
         return "%s mv FROM TO" % (os.path.basename(sys.argv[0]),)
 
+class LnOptions(VDriveOptions):
+    def parseArgs(self, frompath, topath):
+        self.from_file = frompath
+        self.to_file = topath
+
+    def getSynopsis(self):
+        return "%s ln FROM TO" % (os.path.basename(sys.argv[0]),)
+
 class WebopenOptions(VDriveOptions):
     def parseArgs(self, vdrive_pathname=""):
         self['vdrive_pathname'] = vdrive_pathname
@@ -177,6 +185,7 @@ subCommands = [
     ["put", None, PutOptions, "Upload a file into the virtual drive."],
     ["rm", None, RmOptions, "Unlink a file or directory in the virtual drive."],
     ["mv", None, MvOptions, "Move a file within the virtual drive."],
+    ["ln", None, LnOptions, "Make an additional link to an existing file."],
     ["webopen", None, WebopenOptions, "Open a webbrowser to the root_dir"],
     ["repl", None, ReplOptions, "Open a python interpreter"],
     ]
@@ -258,7 +267,18 @@ def mv(config, stdout, stderr):
                      config.aliases,
                      config.from_file,
                      config.to_file,
-                     stdout, stderr)
+                     stdout, stderr,
+                     mode="move")
+    return rc
+
+def ln(config, stdout, stderr):
+    from allmydata.scripts import tahoe_mv
+    rc = tahoe_mv.mv(config['node-url'],
+                     config.aliases,
+                     config.from_file,
+                     config.to_file,
+                     stdout, stderr,
+                     mode="link")
     return rc
 
 def webopen(config, stdout, stderr):
@@ -284,6 +304,7 @@ dispatch = {
     "put": put,
     "rm": rm,
     "mv": mv,
+    "ln": ln,
     "webopen": webopen,
     "repl": repl,
     }
index d3867d8ab8dfd23fe54d062fc891c957bd347a9c..41bb5fd95471ecb505794ea9b85fd4c8dfa987f6 100644 (file)
@@ -5,7 +5,9 @@ import simplejson
 from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
 from allmydata.scripts.common_http import do_http
 
-def mv(nodeurl, aliases, from_file, to_file, stdout, stderr):
+# this script is used for both 'mv' and 'ln'
+
+def mv(nodeurl, aliases, from_file, to_file, stdout, stderr, mode="move"):
     if nodeurl[-1] != "/":
         nodeurl += "/"
     rootcap, path = get_alias(aliases, from_file, DEFAULT_ALIAS)
@@ -35,14 +37,16 @@ def mv(nodeurl, aliases, from_file, to_file, stdout, stderr):
     if not re.search(r'^2\d\d$', str(status)):
         print >>stderr, "error, got %s %s" % (resp.status, resp.reason)
         print >>stderr, resp.read()
-        print >>stderr, "NOT removing the original"
+        if mode == "move":
+            print >>stderr, "NOT removing the original"
         return
 
-    # now remove the original
-    resp = do_http("DELETE", from_url)
-    if not re.search(r'^2\d\d$', str(status)):
-        print >>stderr, "error, got %s %s" % (resp.status, resp.reason)
-        print >>stderr, resp.read()
+    if mode == "move":
+        # now remove the original
+        resp = do_http("DELETE", from_url)
+        if not re.search(r'^2\d\d$', str(status)):
+            print >>stderr, "error, got %s %s" % (resp.status, resp.reason)
+            print >>stderr, resp.read()
 
     print >>stdout, "OK"
     return
index 843bff7f530cc04c8057bb21c9106c6afb292433..00b4891d06e1c43f8430f4298e1757eae4a28bcd 100644 (file)
@@ -1699,6 +1699,10 @@ class SystemTest(testutil.SignalMixin, testutil.PollMixin, testutil.StallMixin,
         d.addCallback(run, "ls")
         d.addCallback(_check_ls, ["tahoe-moved"], ["tahoe-file-stdin"])
 
+        d.addCallback(run, "ln", "tahoe-moved", "newlink")
+        d.addCallback(run, "ls")
+        d.addCallback(_check_ls, ["tahoe-moved", "newlink"])
+
         # tahoe_ls doesn't currently handle the error correctly: it tries to
         # JSON-parse a traceback.
 ##         def _ls_missing(res):