It does tho. Creating a file input.xml
and running:
require "file_utils"
FileUtils.ln_s("input.xml", "data.xml")
Results in data.xml -> input.xml
being created. Running it again produces Unhandled exception: Error creating symlink: 'input.xml' -> 'data.xml': File exists (File::AlreadyExistsError)
. But using ln_sf
works fine and updates the modtime of the link.
BUT, I think what’s going on is if you run like:
require "file_utils"
FileUtils.ln_sf("data.txt", "i_dont_exist.txt")
It’ll create i_dont_exist.txt -> data.txt
, but if you run it again, Unhandled exception: Error creating symlink: 'data.txt' -> 'i_dont_exist.txt': File exists (File::AlreadyExistsError)
. Which seems to be because File.file?
within crystal/file_utils.cr at b7377c0419ae5c1ce91e8298f075b3ff15636c54 · crystal-lang/crystal · GitHub, is resolving the symlink and returning true
because the destination of the link is a file. But if you create a symlink to a file that doesn’t exist, it returns false
, and doesn’t delete it.
So in short, that probably just needs to be File.delete(dest_path) if File.symlink?(dest_path)
EDIT: Also the difference in ls -la
and the exception message is super confusing.