From 98ab848cdae2743753d48dda2c34f081496f7e80 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Tue, 28 Jul 2015 17:19:42 -0700 Subject: [PATCH] cp: error on target-filename collisions, rather than overwrite Closes ticket:2447 --- src/allmydata/scripts/tahoe_cp.py | 22 ++++++++++++++++++++-- src/allmydata/test/test_cli_cp.py | 4 ++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/allmydata/scripts/tahoe_cp.py b/src/allmydata/scripts/tahoe_cp.py index b603d6ba..351b6a33 100644 --- a/src/allmydata/scripts/tahoe_cp.py +++ b/src/allmydata/scripts/tahoe_cp.py @@ -496,8 +496,9 @@ class Copier: def try_copy(self): """ - All usage errors are caught here, not in a subroutine. This bottoms - out in copy_file_to_file() or copy_things_to_directory(). + All usage errors (except for target filename collisions) are caught + here, not in a subroutine. This bottoms out in copy_file_to_file() or + copy_things_to_directory(). """ source_specs = self.options.sources destination_spec = self.options.destination @@ -735,6 +736,23 @@ class Copier: # sourceobject) dicts for all the files that need to wind up there. targetmap = self.build_targetmap(sources, target) + # target name collisions are an error + collisions = [] + for target, sources in targetmap.items(): + target_names = {} + for source in sources: + name = source.basename() + if name in target_names: + collisions.append((target, source, target_names[name])) + else: + target_names[name] = source + if collisions: + self.to_stderr("cannot copy multiple files with the same name into the same target directory") + # I'm not sure how to show where the collisions are coming from + #for (target, source1, source2) in collisions: + # self.to_stderr(source1.basename()) + return 1 + # step four: walk through the list of targets. For each one, copy all # the files. If the target is a TahoeDirectory, upload and create # read-caps, then do a set_children to the target directory. diff --git a/src/allmydata/test/test_cli_cp.py b/src/allmydata/test/test_cli_cp.py index 82648307..3c8bc80a 100644 --- a/src/allmydata/test/test_cli_cp.py +++ b/src/allmydata/test/test_cli_cp.py @@ -787,7 +787,7 @@ cp -r $PARENTCAP/dir3/file3 $DIRCAP $PARENTCAP/dir2 $FILECAP to/missing/ : E2-DE cp -r $PARENTCAP/dir4 to : to/dir4/emptydir/ cp -r $PARENTCAP/dir4 to/ : to/dir4/emptydir/ -# name collisions: ensure files are copied in order +# name collisions should cause errors, not overwrites cp -r $PARENTCAP/dir6/dir $PARENTCAP/dir5/dir to : E9-COLLIDING-TARGETS cp -r $PARENTCAP/dir5/dir $PARENTCAP/dir6/dir to : E9-COLLIDING-TARGETS cp -r $DIRCAP6 $DIRCAP5 to : E9-COLLIDING-TARGETS @@ -949,7 +949,7 @@ class CopyOut(GridTestMixin, CLITestMixin, unittest.TestCase): return set(["E6-MANYONE"]) if err == "target is not a directory, but ends with a slash": return set(["E7-BADSLASH"]) - if err == "cannot copy multiple files with the same name from different source directories into the same target directory": + if err == "cannot copy multiple files with the same name into the same target directory": return set(["E9-COLLIDING-TARGETS"]) if (err.startswith("source ") and "is not a directory, but ends with a slash" in err): -- 2.45.2