Gomi cannot remove broken symlinks
Summary
gomi cannot remove symlinks that refer to non-existent files.
Version
Because I use a gomi binary built by Nix, gomi -V prints no version information.
$ gomi -V
gomi - a CLI trash manager
https://gomi.dev
version: (devel)
revision: unset
buildDate: unknown
According to the Nix metadata, it seems to be built with v1.6.0.
https://github.com/NixOS/nixpkgs/blob/46e634be05ce9dc6d4db8e664515ba10b78151ae/pkgs/by-name/go/gomi/package.nix#L14
EDIT: with the recent update of Nix, the version information is included in the gomi built by Nix.
$ gomi -V
gomi - a CLI trash manager
https://gomi.dev
version: v1.6.0
revision: da44e9f
buildDate: 2025-03-17T05:38:26Z
How to Reproduce
gomi can remove a symlink that points to a valid file.
$ mkdir -p ~/tmp/gomi
$ cd ~/tmp/gomi
$ touch a
$ ln -s a b
$ ls -l
total 0
-rw-rw-r-- 1 ken ken 0 Apr 30 18:59 a
lrwxrwxrwx 1 ken ken 1 Apr 30 18:59 b -> a
# Gomi successfully removes b.
$ gomi b
$ ls -l
total 0
-rw-rw-r-- 1 ken ken 0 Apr 30 18:59 a
However, it cannot remove a symlink that refers to an invalid file.
$ mkdir -p ~/tmp/gomi
$ cd ~/tmp/gomi
$ touch a
$ ln -s a b
$ ls -l
total 0
-rw-rw-r-- 1 ken ken 0 Apr 30 18:59 a
lrwxrwxrwx 1 ken ken 1 Apr 30 19:00 b -> a
# Remove a, which is referenced by b.
$ rm -f a
$ ls -l
total 0
lrwxrwxrwx 1 ken ken 1 Apr 30 19:00 b -> a
# Gomi failes to remove b.
$ gomi b
gomi: b: no such file or directory
Cause
internal/cli/put.go calls os.Stat() to check if the file to be removed exist:
// Check if file exists
if _, err := os.Stat(path); os.IsNotExist(err) {
if !c.option.Rm.Force {
failed.Append(arg)
return fmt.Errorf("%s: no such file or directory", arg)
}
if c.option.Rm.Verbose {
fmt.Fprintf(os.Stderr, "skipping %s: no such file or directory\n", arg)
}
return nil
}
os.Stat(), however, follows symlinks. As a result, if the symlink points to a non-existent entry, os.Stat() returns a NotExist error.
os.Lstat() seems to be correct for this use case.
https://pkg.go.dev/os#Lstat
If the file is a symbolic link, the returned FileInfo describes the symbolic link. Lstat makes no attempt to follow the link.
I ran into this today as well.
I ran into this recently as well. lol