pop-os / freedesktop-desktop-entry

Rust crate for navigating Freedesktop desktop entries
Mozilla Public License 2.0
31 stars 18 forks source link

Regression in finding desktop entries that are symlinks #30

Closed panekj closed 1 week ago

panekj commented 2 weeks ago

Commit https://github.com/pop-os/freedesktop-desktop-entry/commit/4ae8d55468fea45aac43f22e977d6b21b7d7cd81 that fixed https://github.com/pop-os/freedesktop-desktop-entry/issues/1 broke finding symlinks, specifically this change:

-                        } else if (file_type.is_file() || file_type.is_symlink())
+                        } else if file_type.is_file()

This is because it was changed to path being canonicalized

                if let Ok(entry) = entry {
                    let mut path = entry.path();

                    path = match path.canonicalize() {
                        Ok(canonicalized) => canonicalized,
                        Err(err) => continue 'inner,
                    };

but we are obtaining a file type of entry: DirEntry, not path: PathBuf

                    if let Ok(file_type) = entry.file_type() {
                        if file_type.is_dir() {
                            self.directories_to_walk.push(path);
                        } else if file_type.is_file()
                            && path.extension().map_or(false, |ext| ext == "desktop")
                        {

so the file type will remain a symlink and is_file()/is_dir()/is_symlink() are all mutually exclusive.

[/home/pj/.cargo/git/checkouts/freedesktop-desktop-entry-8e38dec930cfe15c/06ea579/src/iter.rs:69:29] file_type = FileType {
    is_file: false,
    is_dir: false,
    is_symlink: true,
    ..
}
panekj commented 2 weeks ago

Replacing entry with path and call to fs::metadata should fix the issue

(Opened PR as well since I needed to use patch)

diff --git a/src/iter.rs b/src/iter.rs
index 9ff853a..880a88c 100644
--- a/src/iter.rs
+++ b/src/iter.rs
@@ -51,10 +51,10 @@ impl Iterator for Iter {
                         Err(_) => continue 'inner,
                     };

-                    if let Ok(file_type) = entry.file_type() {
-                        if file_type.is_dir() {
+                    if let Ok(metadata) = path.metadata() {
+                        if metadata.is_dir() {
                             self.directories_to_walk.push(path);
-                        } else if file_type.is_file()
+                        } else if metadata.is_file()
                             && path.extension().map_or(false, |ext| ext == "desktop")
                         {
                             self.actively_walking = Some(iterator);