Questions about FileUtils.ln_sf and existing symlinks

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.