Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dir_copy() is not idempotent when overwrite = F #431

Open
thomascwells opened this issue Sep 26, 2023 · 3 comments
Open

dir_copy() is not idempotent when overwrite = F #431

thomascwells opened this issue Sep 26, 2023 · 3 comments

Comments

@thomascwells
Copy link

The results of a second execution of dir_copy() when overwrite = F are not as I expected. I expected an error message, but instead it copied the source directory into the target, but nested one level deeper than during the first execution.

Here's an example

library(fs)

# create test source directory
dir_create("a/b")
file_create("a/b/test.txt")
dir_tree("a")

# a
# └── b
#     └── test.txt

# first copy: contents of 'a' are copied to 'c' = c/b/test.txt
# this is what I expected
dir_copy("a", "c", overwrite = F)
dir_tree("c")

# c
# └── b
#     └── test.txt

# second copy: 'a' and it's contents are copied to 'c' = c/a/b/test.txt
# expected: error about overwriting
# this is the step that seems incorrect to me
dir_copy("a", "c", overwrite = F)
dir_tree("c")

# c
# ├── a
# │   └── b
# │       └── test.txt
# └── b
#     └── test.txt

# third copy: error about overwriting
dir_copy("a", "c", overwrite = F)
# Error: [EEXIST] Failed to copy 'a/b/test.txt' to 'c/a/b/test.txt': file already exists

# test with overwrite = T

# first copy - same results as before: d/b/test.txt
dir_copy("a", "d", overwrite = T)
dir_tree("d")

# d
# └── b
#     └── test.txt

# second copy - expected results: silent overwrite
dir_copy("a", "d", overwrite = T)
dir_tree("d")

# d
# └── b
#     └── test.txt

# cleanup
dir_delete("a")
dir_delete("c")
dir_delete("d")
@gaborcsardi
Copy link
Member

I am afraid that this is how copying usually works. If the target is an existing directory, then it copied everything inside the directory. E.g. the command line cp:

❯ mkdir x1
❯ touch x1/foo
❯ cp -r x1 x2
❯ cp -r x1 x2
❯ find x2
x2
x2/x1
x2/x1/foo
x2/foo

Changing this behavior now would be a breaking change.

@thomascwells
Copy link
Author

Understood regarding the breaking change.

Would it be worth adding a note in the documentation about this condition?

@gaborcsardi
Copy link
Member

Yeah, that would make sense I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants