optFlags = [
("recursive", "r", "Copy source directory recursively."),
("verbose", "v", "Be noisy about what is happening."),
+ ("caps-only", None,
+ "When copying to local files, write out filecaps instead of actual "
+ "data. (only useful for debugging and tree-comparison purposes)"),
]
def parseArgs(self, *args):
if len(args) < 2:
import os.path
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_http import do_http
def need_to_copy_bytes(self):
return True
- def open(self):
+ def open(self, caps_only):
return open(self.pathname, "rb")
class LocalFileTarget:
return True
return False
- def open(self):
+ def open(self, caps_only):
+ if caps_only:
+ return StringIO(self.readcap)
url = self.nodeurl + "uri/" + urllib.quote(self.readcap)
return GET_to_file(url)
def progress(message):
print >>self.stderr, message
self.progressfunc = progress
+ self.caps_only = options["caps-only"]
self.cache = {}
try:
self.try_copy()
# if the target is a local directory, this will just write the
# bytes to disk. If it is a tahoe directory, it will upload the
# data, and stash the new filecap for a later set_children call.
- f = source.open()
+ f = source.open(self.caps_only)
target.put_file(f)
return self.announce_success("file copied")
# otherwise we're copying tahoe to tahoe, and using immutable files,
# if the target is a local directory, this will just write the
# bytes to disk. If it is a tahoe directory, it will upload the
# data, and stash the new filecap for a later set_children call.
- f = source.open()
+ f = source.open(self.caps_only)
target.put_file(name, f)
return
# otherwise we're copying tahoe to tahoe, and using immutable files,
def copy(options):
return Copier().do_copy(options)
+
+# error cases that need improvement:
+# local-file-in-the-way
+# touch proposed
+# tahoe cp -r my:docs/proposed/denver.txt proposed/denver.txt
+
+# things that maybe should be errors but aren't
+# local-dir-in-the-way
+# mkdir denver.txt
+# tahoe cp -r my:docs/proposed/denver.txt denver.txt
+# (creates denver.txt/denver.txt)
+
+# error cases that look good:
+# tahoe cp -r my:docs/missing missing
+# disconnect servers
+# tahoe cp -r my:docs/missing missing -> No JSON object could be decoded
+# tahoe-file-in-the-way (when we want to make a directory)
+# tahoe put README my:docs
+# tahoe cp -r docs/proposed my:docs/proposed
# and copy it a second time, which ought to overwrite the same files
d.addCallback(run, "cp", "-r", "tahoe:dir1", dn_copy)
+ # and again, only writing filecaps
+ dn_copy2 = os.path.join(self.basedir, "dir1-copy-capsonly")
+ d.addCallback(run, "cp", "-r", "--caps-only", "tahoe:dir1", dn_copy2)
+ def _check_capsonly((out,err)):
+ # these should all be LITs
+ x = open(os.path.join(dn_copy2, "subdir2", "rfile4")).read()
+ y = uri.from_string_filenode(x)
+ self.failUnlessEqual(y.data, "rfile4")
+ d.addCallback(_check_capsonly)
+
# and tahoe-to-tahoe
d.addCallback(run, "cp", "-r", "tahoe:dir1", "tahoe:dir1-copy")
d.addCallback(run, "ls")