Repository: sharkdp/fd (language: rust)

Issue:
Make sure --list-details works on Windows and MacOS
- [x] MacOS (use `gls`, if available. otherwise, use `ls`)
- [x] Windows

see comments in #556


Discussion / hints:

Fix patch:
diff --git a/src/main.rs b/src/main.rs
index 5bfd08072..969ffbcf9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -163,16 +163,75 @@ fn run() -> Result<ExitCode> {
         let color = matches.value_of("color").unwrap_or("auto");
         let color_arg = ["--color=", color].concat();
 
-        Some(
-            CommandTemplate::new_batch(&[
-                "ls",
+        #[allow(unused)]
+        let gnu_ls = |command_name| {
+            vec![
+                command_name,
                 "-l",               // long listing format
                 "--human-readable", // human readable file sizes
                 "--directory",      // list directories themselves, not their contents
-                &color_arg,         // enable colorized output, if enabled
-            ])
-            .unwrap(),
-        )
+                &color_arg,
+            ]
+        };
+
+        let cmd: Vec<&str> = if cfg!(unix) {
+            if !cfg!(target_os = "macos") {
+                // Non-MacOS Unix
+                gnu_ls("ls")
+            } else {
+                // MacOS
+                use std::process::{Command, Stdio};
+
+                // Use GNU ls, if available (support for --color=auto, better LS_COLORS support)
+                let gnu_ls_exists = Command::new("gls")
+                    .arg("--version")
+                    .stdout(Stdio::null())
+                    .stderr(Stdio::null())
+                    .status()
+                    .is_ok();
+
+                if gnu_ls_exists {
+                    gnu_ls("gls")
+                } else {
+                    let mut cmd = vec![
+                        "ls", // MacOS version of ls
+                        "-l", // long listing format
+                        "-h", // '--human-readable' is not available on MacOS, '-h' is
+                        "-d", // '--directory' is not available, but '-d' is
+                    ];
+
+                    if colored_output {
+                        cmd.push("-G");
+                    }
+
+                    cmd
+                }
+            }
+        } else if cfg!(windows) {
+            use std::process::{Command, Stdio};
+
+            // Use GNU ls, if available
+            let gnu_ls_exists = Command::new("ls")
+                .arg("--version")
+                .stdout(Stdio::null())
+                .stderr(Stdio::null())
+                .status()
+                .is_ok();
+
+            if gnu_ls_exists {
+                gnu_ls("ls")
+            } else {
+                return Err(anyhow!(
+                    "'fd --list-details' is not supported on Windows unless GNU 'ls' is installed."
+                ));
+            }
+        } else {
+            return Err(anyhow!(
+                "'fd --list-details' is not supported on this platform."
+            ));
+        };
+
+        Some(CommandTemplate::new_batch(&cmd).unwrap())
     } else {
         None
     };


Test patch:
diff --git a/tests/tests.rs b/tests/tests.rs
index 360d3db9c..e1ab05cda 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -1558,3 +1558,11 @@ fn test_exec_invalid_utf8() {
         b"test_\xFEinvalid\n",
     );
 }
+
+#[test]
+fn test_list_details() {
+    let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
+
+    // Make sure we can execute 'fd --list-details' without any errors.
+    te.assert_success_and_get_output(".", &["--list-details"]);
+}