fs_extra
fs_extra copied to clipboard
remove_items silently fails on broken symlinks
Currently fs_extra::remove_items does not act on symlinks that point to not-existing targets. It is not clear from the documentation what the intended behavior is, so I am not sure if this asks for fixing, or just documenting.
Reproduce
Assume a directory that contains symlinks, both to existing and non-existing targets:
mkdir dir/
touch dir/file-1
ln -s dir/file-1 dir/link-1
ln -s dir/file-2 dir/link-2
A minimal rust program for reproduction:
fn main() {
for arg in std::env::args().skip(1) {
let path = Path::new(&arg);
println!("Removing path {:?}", path);
match fs_extra::remove_items(&[path]) {
Ok(_) => println!(" -> OK"),
Err(err) => println!(" -> Err: {}", err)
}
}
}
And then:
$ tree dir
dir
├── file-1
├── link-1 -> file-1
└── link-2 -> file-2
1 directory, 3 files
$ cargo run -- dir/link*
Removing path "dir/link-1"
-> OK
Removing path "dir/link-2"
-> OK
$ tree dir
dir
├── file-1
└── link-2 -> file-2
1 directory, 2 files
(above tested on MacOS and Linux)
Expected
Up to the maintainers of the library:
-
Remove All: Delete all provided paths. Here:
link-1andlink-2are both removed.file-1stays (unchanged). -
Document Symlink: Be clear that
remove_itemshascaveat (or maybe more broadly: recommend not to use with symlinks?) - Error: Return an error in case symlink is "unclean" (is that a thing?)
I think (1) makes the most sense. Alas this was my expectation when using remove_items.
Causal
-
remove_itemsusesfile::remove, in case the item is not a directory -
file::removeonly removes when the path exists - Check whether path exists is done via
std::path::Path::exists, that evaluates the symlink target (which here is missing) and not the symlink itself