Repository: eza-community/eza (language: rust)

Issue:
feat: Windows Hidden Files Support
So I installed eza on my work laptop (which unfortunately has Windows 11 installed) because I wanted a more Linux-ey way to search for files in PowerShell. 

Something that would make eza an even better alternative to PowerShell's Get-ChildItem would be to hide Windows hidden files when `-a` isn't specified. The current behaviour only hides dot files.

I don't think this would be too hard to implement as the hidden flag is included when running `eza -l` so the information is there.
![image](https://github.com/eza-community/eza/assets/127202207/86ebbcd7-6c29-4de4-8d00-031cbc2e17ca)

I may take a look into this at the weekend if I get the chance & no one has any complaints with this change.


Discussion / hints:
> I may take a look into this at the weekend if I get the chance & no one has any complaints with this change.

That would be cool to see, I'm assuming this makes sense, but if people disagree they should feel free to voice concerns in this issue.
Little bit more complicated than I'd imagined. The actual dot filter happens in the Iterator impl on `Files`, before the `File` is created. main.rs line 236 inside of `print_dirs` is the first time we unwrap the `Result<File>` so I opted to just skip pushing into `children` but I don't know if I'm a fan of this approach.
![image](https://github.com/eza-community/eza/assets/127202207/ca739bab-0bce-4fd8-9a1e-3bde91812600)

I could maybe move the error checking into these methods so `Item = Result<File ...>` becomes `Item = File` & `next_visible_file` can filter on attributes().hidden during the dot file check
![image](https://github.com/eza-community/eza/assets/127202207/8a02e19d-3ae3-41c8-9c58-fb93710a0952)

for reference next_visible_file is where it feels like the hidden file check 'belongs'
![image](https://github.com/eza-community/eza/assets/127202207/060c1d8b-e4b2-48cc-84af-2595f79edf27)

I'll give the Iterator refactoring a go tomorrow and get a PR up to get some eyes on it

Or this could work, rather than return `Some(File::from_args(...))` match on the result of from_args & skip the Windows hidden files or wrap it back up in the Option<Result<>> for the calling code to handle
![image](https://github.com/eza-community/eza/assets/127202207/4d40e792-b3f0-4cef-8838-c5afa29987f5)

I have been playing with this myself for the last half hour. I do agree that this seems like the most idiomatic place for this check...

How does that perform? I tried various other options but never that exact one
Default behaviour with `eza -l` (my alias is just ls -> eza.exe)
![image](https://github.com/eza-community/eza/assets/127202207/22cd9b28-3161-41be-81bd-7f8d6bb89936)

It does hide symlinks which differs from default ls behaviour, but in my experience symlinks aren't as important or widely used in Windows so I think I prefer this (they're also hidden in the file system by default). It does a bit better better than PowerShell's Get-ChildItem which hides hidden files and symlinks but not dot files.

Running with -a or -A gives the following:
![image](https://github.com/eza-community/eza/assets/127202207/3d1ca00d-f51f-4b8d-bd70-cf36a9cecc56)

Symlinks + Windows hidden files & folders now appear (as well as dot files).

So it doesn't behave exactly the same way as a Linux ls with the symlinks, but it behaves in a way that makes more sense inside of Windows IMO

I was wrong, it doesn't hide symlinks, it just hides Window's "file junctions" because these are marked as hidden by the system

Anyway the PR is up #225, I opted to put the whole match in the Windows block so the non-windows behaviour is hopefully a bit clearer.

Fix patch:
diff --git a/.github/workflows/conventional-commits.yml b/.github/workflows/conventional-commits.yml
new file mode 100644
index 000000000..b860275c1
--- /dev/null
+++ b/.github/workflows/conventional-commits.yml
@@ -0,0 +1,19 @@
+name: Conventional Commits
+
+on:
+  push:
+    branches: [ main ]
+  pull_request:
+    branches: [ main ]
+
+jobs:
+  build:
+    name: Conventional Commits
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+
+      - uses: webiny/action-conventional-commits@v1.1.0
+        # optional, required for private repos
+        # with:
+        #   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/devtools/deb-package.sh b/devtools/deb-package.sh
index 8ec278d81..d67fef6f5 100755
--- a/devtools/deb-package.sh
+++ b/devtools/deb-package.sh
@@ -9,7 +9,7 @@ TAG=$(git describe --tags --abbrev=0)
 VERSION=${TAG:1}
 
 echo "checkout tag ${TAG}"
-git checkout --quiet ${TAG}
+git checkout --quiet "${TAG}"
 
 echo "build man pages"
 just man
@@ -20,7 +20,7 @@ TARGETS["arm64"]="aarch64-unknown-linux-gnu"
 TARGETS["armhf"]="arm-unknown-linux-gnueabihf"
 
 echo "download release notes"
-RELEASE_NOTES=$(curl -s ${REPO_URL}/releases/tag/${TAG})
+RELEASE_NOTES=$(curl -s "${REPO_URL}/releases/tag/${TAG}")
 
 for ARCH in "${!TARGETS[@]}"; do
     echo "building ${ARCH} package:"
@@ -40,29 +40,29 @@ for ARCH in "${!TARGETS[@]}"; do
     echo "    checksum ok"
 
     echo " -> creating directory structure"
-    mkdir -p ${DEB_TMP_DIR}
-    mkdir -p ${DEB_TMP_DIR}${DESTDIR}
-    mkdir -p ${DEB_TMP_DIR}${DOCDIR}
-    mkdir -p ${DEB_TMP_DIR}${DOCDIR}/man1
-    mkdir -p ${DEB_TMP_DIR}${DOCDIR}/man5
-    mkdir -p ${DEB_TMP_DIR}/DEBIAN
-    mkdir -p ${DEB_TMP_DIR}/usr/share/doc/${NAME}
-    chmod 755 -R ${DEB_TMP_DIR}
-    
+    mkdir -p "${DEB_TMP_DIR}"
+    mkdir -p "${DEB_TMP_DIR}${DESTDIR}"
+    mkdir -p "${DEB_TMP_DIR}${DOCDIR}"
+    mkdir -p "${DEB_TMP_DIR}${DOCDIR}/man1"
+    mkdir -p "${DEB_TMP_DIR}${DOCDIR}/man5"
+    mkdir -p "${DEB_TMP_DIR}/DEBIAN"
+    mkdir -p "${DEB_TMP_DIR}/usr/share/doc/${NAME}"
+    chmod 755 -R "${DEB_TMP_DIR}"
+
     echo " -> extract executable"
     tar -xzf "${ARCH}.tar.gz"
-    cp ${NAME} ${DEB_TMP_DIR}${DESTDIR}
-    chmod 755 ${DEB_TMP_DIR}${DESTDIR}/${NAME}
+    cp ${NAME} "${DEB_TMP_DIR}${DESTDIR}"
+    chmod 755 "${DEB_TMP_DIR}${DESTDIR}/${NAME}"
 
     echo " -> compress man pages"
-    gzip -cn9 target/man/eza.1 > ${DEB_TMP_DIR}${DOCDIR}man1/eza.1.gz
-    gzip -cn9 target/man/eza_colors.5 > ${DEB_TMP_DIR}${DOCDIR}man5/eza_colors.5.gz
-    gzip -cn9 target/man/eza_colors-explanation.5 > ${DEB_TMP_DIR}${DOCDIR}man5/eza_colors-explanation.5.gz
-    chmod 644 ${DEB_TMP_DIR}${DOCDIR}/**/*.gz
-    
+    gzip -cn9 target/man/eza.1 > "${DEB_TMP_DIR}${DOCDIR}man1/eza.1.gz"
+    gzip -cn9 target/man/eza_colors.5 > "${DEB_TMP_DIR}${DOCDIR}man5/eza_colors.5.gz"
+    gzip -cn9 target/man/eza_colors-explanation.5 > "${DEB_TMP_DIR}${DOCDIR}man5/eza_colors-explanation.5.gz"
+    chmod 644 "${DEB_TMP_DIR}${DOCDIR}"/**/*.gz
+
     echo " -> create control file"
-    touch ${DEB_TMP_DIR}/DEBIAN/control
-    cat > ${DEB_TMP_DIR}/DEBIAN/control <<EOM
+    touch "${DEB_TMP_DIR}/DEBIAN/control"
+    cat > "${DEB_TMP_DIR}/DEBIAN/control" <<EOM
 Package: ${NAME}
 Version: ${VERSION}
 Section: utils
@@ -78,17 +78,17 @@ Description: Modern replacement for ls
  It also has extra features not present in the original ls, such as viewing the
  Git status for a directory, or recursing into directories with a tree view.
 EOM
-    chmod 644 ${DEB_TMP_DIR}/DEBIAN/control
-    
+    chmod 644 "${DEB_TMP_DIR}/DEBIAN/control"
+
     echo " -> copy changelog"
-    cp CHANGELOG.md ${DEB_TMP_DIR}/usr/share/doc/${NAME}/changelog
-    gzip -cn9 ${DEB_TMP_DIR}/usr/share/doc/${NAME}/changelog > ${DEB_TMP_DIR}/usr/share/doc/${NAME}/changelog.gz
-    rm ${DEB_TMP_DIR}/usr/share/doc/${NAME}/changelog
-    chmod 644 ${DEB_TMP_DIR}/usr/share/doc/${NAME}/changelog.gz
-    
+    cp CHANGELOG.md "${DEB_TMP_DIR}/usr/share/doc/${NAME}/changelog"
+    gzip -cn9 "${DEB_TMP_DIR}/usr/share/doc/${NAME}/changelog" > "${DEB_TMP_DIR}/usr/share/doc/${NAME}/changelog.gz"
+    rm "${DEB_TMP_DIR}/usr/share/doc/${NAME}/changelog"
+    chmod 644 "${DEB_TMP_DIR}/usr/share/doc/${NAME}/changelog.gz"
+
     echo " -> create copyright file"
-    touch ${DEB_TMP_DIR}/usr/share/doc/${NAME}/copyright
-    cat > ${DEB_TMP_DIR}/usr/share/doc/${NAME}/copyright << EOM
+    touch "${DEB_TMP_DIR}/usr/share/doc/${NAME}/copyright"
+    cat > "${DEB_TMP_DIR}/usr/share/doc/${NAME}/copyright" << EOM
 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 Upstream-Name: ${NAME}
 Upstream-Contact: Christina Sørensen <christina@cafkafk.com>
@@ -121,16 +121,16 @@ License: MIT
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
 EOM
-    chmod 644 ${DEB_TMP_DIR}/usr/share/doc/${NAME}/copyright
-    
+    chmod 644 "${DEB_TMP_DIR}/usr/share/doc/${NAME}/copyright"
+
     echo " -> build ${ARCH} package"
-    dpkg-deb --build --root-owner-group ${DEB_TMP_DIR} > /dev/null
-    
+    dpkg-deb --build --root-owner-group "${DEB_TMP_DIR}" > /dev/null
+
     echo " -> cleanup"
-    rm -rf ${DEB_TMP_DIR} ${ARCH}.tar.gz ${NAME}
-    
+    rm -rf "${DEB_TMP_DIR}" "${ARCH}.tar.gz" "${NAME}"
+
     # gierens: this does not work on my arch at the moment and
     #          i'm verifying on the repo host anyway thus the || true
     echo " -> lint ${ARCH} package"
-    lintian ${DEB_PACKAGE} || true
+    lintian "${DEB_PACKAGE}" || true
 done
diff --git a/treefmt.nix b/treefmt.nix
index 9ea5c043c..fc57580bf 100644
--- a/treefmt.nix
+++ b/treefmt.nix
@@ -3,5 +3,6 @@
   programs = {
     alejandra.enable = true;
     rustfmt.enable = true;
+    shellcheck.enable = true;
   };
 }


Test patch:
diff --git a/devtools/generate-trycmd-test.sh b/devtools/generate-trycmd-test.sh
new file mode 100755
index 000000000..a3386905b
--- /dev/null
+++ b/devtools/generate-trycmd-test.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+# Generate test data for the program
+
+if [ $# -ne 2 ]; then
+    echo "Usage: $0 <test name> <test argument>"
+    exit 1
+fi
+
+# Clean up previous test data
+
+if [ -f tests/cmd/"$1".toml ]; then
+    rm tests/cmd/"$1".toml
+fi
+
+if [ -f tests/cmd/"$1".stdout ]; then
+    rm tests/cmd/"$1".stdout
+fi
+
+if [ -f tests/cmd/"$1".stderr ]; then
+    rm tests/cmd/"$1".stderr
+fi
+
+# Generate test data
+
+touch tests/cmd/"$1".toml
+
+echo 'bin.name = "eza"' >> tests/cmd/"$1".toml
+echo 'args = "'"$2"'"' >> tests/cmd/"$1".toml
+
+# Generate expected output
+
+if [ -f target/debug/eza ]; then
+    target/debug/eza "$2" > tests/cmd/"$1".stdout 2> tests/cmd/"$1".stderr
+    returncode=$?
+    if [ $returncode -ne 0 ]; then
+        echo -e 'status.code = '$returncode'' >> tests/cmd/"$1".toml
+        exit 0
+    fi
+else
+    echo "Please build the program first"
+    exit 1
+fi
diff --git a/tests/cmd/inexistant_file_unix.stderr b/tests/cmd/inexistant_file_unix.stderr
new file mode 100644
index 000000000..e5536d89e
--- /dev/null
+++ b/tests/cmd/inexistant_file_unix.stderr
@@ -0,0 +1,1 @@
+"nonexistentdir": No such file or directory (os error 2)
diff --git a/tests/cmd/inexistant_file_unix.stdout b/tests/cmd/inexistant_file_unix.stdout
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/inexistant_file_unix.toml b/tests/cmd/inexistant_file_unix.toml
new file mode 100644
index 000000000..3ab93c176
--- /dev/null
+++ b/tests/cmd/inexistant_file_unix.toml
@@ -0,0 +1,3 @@
+bin.name = "eza"
+args = "nonexistentdir"
+status.code = 2
diff --git a/tests/cmd/long_binary_bytes_unix.stderr b/tests/cmd/long_binary_bytes_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/long_binary_bytes_unix.stdout b/tests/cmd/long_binary_bytes_unix.stdout
new file mode 100644
index 000000000..4ad8aa333
--- /dev/null
+++ b/tests/cmd/long_binary_bytes_unix.stdout
@@ -0,0 +1,21 @@
+ 0 a
+ 0 b
+ 0 c
+ 0 d
+ 0 e
+ - exa
+ 0 f
+ 0 g
+ 0 h
+ 0 i
+ 0 image.jpg.img.c.rs.log.png
+19 index.svg
+ 0 j
+ 0 k
+ 0 l
+ 0 m
+ 0 n
+ 0 o
+ 0 p
+ 0 q
+ - vagrant
diff --git a/tests/cmd/long_binary_bytes_unix.toml b/tests/cmd/long_binary_bytes_unix.toml
new file mode 100644
index 000000000..6669788a1
--- /dev/null
+++ b/tests/cmd/long_binary_bytes_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --long --no-user --no-time --no-permissions --binary"
diff --git a/tests/cmd/long_file_size_unix.stderr b/tests/cmd/long_file_size_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/long_file_size_unix.stdout b/tests/cmd/long_file_size_unix.stdout
new file mode 100644
index 000000000..4ad8aa333
--- /dev/null
+++ b/tests/cmd/long_file_size_unix.stdout
@@ -0,0 +1,21 @@
+ 0 a
+ 0 b
+ 0 c
+ 0 d
+ 0 e
+ - exa
+ 0 f
+ 0 g
+ 0 h
+ 0 i
+ 0 image.jpg.img.c.rs.log.png
+19 index.svg
+ 0 j
+ 0 k
+ 0 l
+ 0 m
+ 0 n
+ 0 o
+ 0 p
+ 0 q
+ - vagrant
diff --git a/tests/cmd/long_file_size_unix.toml b/tests/cmd/long_file_size_unix.toml
new file mode 100644
index 000000000..30512bb56
--- /dev/null
+++ b/tests/cmd/long_file_size_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --long --no-user --no-time --no-permissions"
diff --git a/tests/cmd/long_header_unix.stderr b/tests/cmd/long_header_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/long_header_unix.stdout b/tests/cmd/long_header_unix.stdout
new file mode 100644
index 000000000..4589ad441
--- /dev/null
+++ b/tests/cmd/long_header_unix.stdout
@@ -0,0 +1,22 @@
+Size Name
+   0 a
+   0 b
+   0 c
+   0 d
+   0 e
+   - exa
+   0 f
+   0 g
+   0 h
+   0 i
+   0 image.jpg.img.c.rs.log.png
+  19 index.svg
+   0 j
+   0 k
+   0 l
+   0 m
+   0 n
+   0 o
+   0 p
+   0 q
+   - vagrant
diff --git a/tests/cmd/long_header_unix.toml b/tests/cmd/long_header_unix.toml
new file mode 100644
index 000000000..421963773
--- /dev/null
+++ b/tests/cmd/long_header_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --long --no-user --no-time --header --no-permissions"
diff --git a/tests/cmd/long_links_recurse_unix.stderr b/tests/cmd/long_links_recurse_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/long_links_recurse_unix.stdout b/tests/cmd/long_links_recurse_unix.stdout
new file mode 100644
index 000000000..4d41d1a1a
--- /dev/null
+++ b/tests/cmd/long_links_recurse_unix.stdout
@@ -0,0 +1,47 @@
+1 a
+1 b
+1 c
+1 d
+1 e
+3 exa
+1 f
+1 g
+1 h
+1 i
+1 image.jpg.img.c.rs.log.png
+1 index.svg
+1 j
+1 k
+1 l
+1 m
+1 n
+1 o
+1 p
+1 q
+5 vagrant
+
+tests/itest/exa:
+1 file.c -> djihisudjuhfius
+2 sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
+
+tests/itest/exa/sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss:
+1 Makefile
+
+tests/itest/vagrant:
+2 debug
+2 dev
+3 log
+
+tests/itest/vagrant/debug:
+1 symlinking -> a
+
+tests/itest/vagrant/dev:
+1 main.bf
+
+tests/itest/vagrant/log:
+1 file.png
+2 run
+
+tests/itest/vagrant/log/run:
+1 run.log.text
+1 sps.log.text
diff --git a/tests/cmd/long_links_recurse_unix.toml b/tests/cmd/long_links_recurse_unix.toml
new file mode 100644
index 000000000..6be95c6d2
--- /dev/null
+++ b/tests/cmd/long_links_recurse_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --long --no-user --no-time --no-filesize --no-permissions --recurse --links"
diff --git a/tests/cmd/long_recurse_with_level_unix.stderr b/tests/cmd/long_recurse_with_level_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/long_recurse_with_level_unix.stdout b/tests/cmd/long_recurse_with_level_unix.stdout
new file mode 100644
index 000000000..a61f5881f
--- /dev/null
+++ b/tests/cmd/long_recurse_with_level_unix.stdout
@@ -0,0 +1,21 @@
+a
+b
+c
+d
+e
+exa
+f
+g
+h
+i
+image.jpg.img.c.rs.log.png
+index.svg
+j
+k
+l
+m
+n
+o
+p
+q
+vagrant
diff --git a/tests/cmd/long_recurse_with_level_unix.toml b/tests/cmd/long_recurse_with_level_unix.toml
new file mode 100644
index 000000000..1c6b2c47f
--- /dev/null
+++ b/tests/cmd/long_recurse_with_level_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --long --no-user --no-permissions --no-time --no-filesize --recurse --level 2"
diff --git a/tests/cmd/long_unix.stdout b/tests/cmd/long_unix.stdout
index 8a156f195..a61f5881f 100644
--- a/tests/cmd/long_unix.stdout
+++ b/tests/cmd/long_unix.stdout
@@ -1,21 +1,21 @@
-.rw-r--r-- a
-.rw-r--r-- b
-.rw-r--r-- c
-.rw-r--r-- d
-.rw-r--r-- e
-drwxr-xr-x exa
-.rw-r--r-- f
-.rw-r--r-- g
-.rw-r--r-- h
-.rw-r--r-- i
-.rw-r--r-- image.jpg.img.c.rs.log.png
-.rw-r--r-- index.svg
-.rw-r--r-- j
-.rw-r--r-- k
-.rw-r--r-- l
-.rw-r--r-- m
-.rw-r--r-- n
-.rw-r--r-- o
-.rw-r--r-- p
-.rw-r--r-- q
-drwxr-xr-x vagrant
+a
+b
+c
+d
+e
+exa
+f
+g
+h
+i
+image.jpg.img.c.rs.log.png
+index.svg
+j
+k
+l
+m
+n
+o
+p
+q
+vagrant
diff --git a/tests/cmd/long_unix.toml b/tests/cmd/long_unix.toml
index 8ea21e7a3..396b622af 100644
--- a/tests/cmd/long_unix.toml
+++ b/tests/cmd/long_unix.toml
@@ -1,2 +1,2 @@
 bin.name = "eza"
-args = "tests/itest --long --no-user --no-time --no-filesize"
+args = "tests/itest --long --no-user --no-time --no-filesize --no-permissions"
diff --git a/tests/cmd/only_dir_recursive_long_unix.stderr b/tests/cmd/only_dir_recursive_long_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/only_dir_recursive_long_unix.stdout b/tests/cmd/only_dir_recursive_long_unix.stdout
new file mode 100644
index 000000000..8e1cb0b74
--- /dev/null
+++ b/tests/cmd/only_dir_recursive_long_unix.stdout
@@ -0,0 +1,21 @@
+exa
+vagrant
+
+tests/itest/exa:
+sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
+
+tests/itest/exa/sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss:
+
+tests/itest/vagrant:
+debug
+dev
+log
+
+tests/itest/vagrant/debug:
+
+tests/itest/vagrant/dev:
+
+tests/itest/vagrant/log:
+run
+
+tests/itest/vagrant/log/run:
diff --git a/tests/cmd/only_dir_recursive_long_unix.toml b/tests/cmd/only_dir_recursive_long_unix.toml
new file mode 100644
index 000000000..f7c2a1dd5
--- /dev/null
+++ b/tests/cmd/only_dir_recursive_long_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --recurse --long --no-user --no-time --no-filesize --no-permissions --only-dirs"
diff --git a/tests/cmd/only_dir_recursive_unix.stderr b/tests/cmd/only_dir_recursive_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/only_dir_recursive_unix.stdout b/tests/cmd/only_dir_recursive_unix.stdout
new file mode 100644
index 000000000..8e1cb0b74
--- /dev/null
+++ b/tests/cmd/only_dir_recursive_unix.stdout
@@ -0,0 +1,21 @@
+exa
+vagrant
+
+tests/itest/exa:
+sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
+
+tests/itest/exa/sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss:
+
+tests/itest/vagrant:
+debug
+dev
+log
+
+tests/itest/vagrant/debug:
+
+tests/itest/vagrant/dev:
+
+tests/itest/vagrant/log:
+run
+
+tests/itest/vagrant/log/run:
diff --git a/tests/cmd/only_dir_recursive_unix.toml b/tests/cmd/only_dir_recursive_unix.toml
new file mode 100644
index 000000000..f7cce03da
--- /dev/null
+++ b/tests/cmd/only_dir_recursive_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --only-dirs --recurse"
diff --git a/tests/cmd/only_dir_unix.stderr b/tests/cmd/only_dir_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/only_dir_unix.stdout b/tests/cmd/only_dir_unix.stdout
new file mode 100644
index 000000000..2489a9247
--- /dev/null
+++ b/tests/cmd/only_dir_unix.stdout
@@ -0,0 +1,2 @@
+exa
+vagrant
diff --git a/tests/cmd/only_dir_unix.toml b/tests/cmd/only_dir_unix.toml
new file mode 100644
index 000000000..acbf5740a
--- /dev/null
+++ b/tests/cmd/only_dir_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --only-dirs"
diff --git a/tests/cmd/recursive_long_unix.stderr b/tests/cmd/recursive_long_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/recursive_long_unix.stdout b/tests/cmd/recursive_long_unix.stdout
new file mode 100644
index 000000000..16313857d
--- /dev/null
+++ b/tests/cmd/recursive_long_unix.stdout
@@ -0,0 +1,47 @@
+a
+b
+c
+d
+e
+exa
+f
+g
+h
+i
+image.jpg.img.c.rs.log.png
+index.svg
+j
+k
+l
+m
+n
+o
+p
+q
+vagrant
+
+tests/itest/exa:
+file.c -> djihisudjuhfius
+sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
+
+tests/itest/exa/sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss:
+Makefile
+
+tests/itest/vagrant:
+debug
+dev
+log
+
+tests/itest/vagrant/debug:
+symlinking -> a
+
+tests/itest/vagrant/dev:
+main.bf
+
+tests/itest/vagrant/log:
+file.png
+run
+
+tests/itest/vagrant/log/run:
+run.log.text
+sps.log.text
diff --git a/tests/cmd/recursive_long_unix.toml b/tests/cmd/recursive_long_unix.toml
new file mode 100644
index 000000000..bb21a3b28
--- /dev/null
+++ b/tests/cmd/recursive_long_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --recurse --long --no-user --no-time --no-filesize --no-permissions"
diff --git a/tests/cmd/recursive_unix.stderr b/tests/cmd/recursive_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/recursive_unix.stdout b/tests/cmd/recursive_unix.stdout
new file mode 100644
index 000000000..16313857d
--- /dev/null
+++ b/tests/cmd/recursive_unix.stdout
@@ -0,0 +1,47 @@
+a
+b
+c
+d
+e
+exa
+f
+g
+h
+i
+image.jpg.img.c.rs.log.png
+index.svg
+j
+k
+l
+m
+n
+o
+p
+q
+vagrant
+
+tests/itest/exa:
+file.c -> djihisudjuhfius
+sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
+
+tests/itest/exa/sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss:
+Makefile
+
+tests/itest/vagrant:
+debug
+dev
+log
+
+tests/itest/vagrant/debug:
+symlinking -> a
+
+tests/itest/vagrant/dev:
+main.bf
+
+tests/itest/vagrant/log:
+file.png
+run
+
+tests/itest/vagrant/log/run:
+run.log.text
+sps.log.text
diff --git a/tests/cmd/recursive_unix.toml b/tests/cmd/recursive_unix.toml
new file mode 100644
index 000000000..5c8cca9e6
--- /dev/null
+++ b/tests/cmd/recursive_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --recurse"
diff --git a/tests/cmd/tree_long_unix.stderr b/tests/cmd/tree_long_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/tree_long_unix.stdout b/tests/cmd/tree_long_unix.stdout
new file mode 100644
index 000000000..2ea6bd949
--- /dev/null
+++ b/tests/cmd/tree_long_unix.stdout
@@ -0,0 +1,34 @@
+tests/itest
+├── a
+├── b
+├── c
+├── d
+├── e
+├── exa
+│  ├── file.c -> djihisudjuhfius
+│  └── sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
+│     └── Makefile
+├── f
+├── g
+├── h
+├── i
+├── image.jpg.img.c.rs.log.png
+├── index.svg
+├── j
+├── k
+├── l
+├── m
+├── n
+├── o
+├── p
+├── q
+└── vagrant
+   ├── debug
+   │  └── symlinking -> a
+   ├── dev
+   │  └── main.bf
+   └── log
+      ├── file.png
+      └── run
+         ├── run.log.text
+         └── sps.log.text
diff --git a/tests/cmd/tree_long_unix.toml b/tests/cmd/tree_long_unix.toml
new file mode 100644
index 000000000..dc3930dd4
--- /dev/null
+++ b/tests/cmd/tree_long_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --tree --long --no-user --no-time --no-filesize --no-permissions"
diff --git a/tests/cmd/tree_unix.stderr b/tests/cmd/tree_unix.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmd/tree_unix.stdout b/tests/cmd/tree_unix.stdout
new file mode 100644
index 000000000..2ea6bd949
--- /dev/null
+++ b/tests/cmd/tree_unix.stdout
@@ -0,0 +1,34 @@
+tests/itest
+├── a
+├── b
+├── c
+├── d
+├── e
+├── exa
+│  ├── file.c -> djihisudjuhfius
+│  └── sssssssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
+│     └── Makefile
+├── f
+├── g
+├── h
+├── i
+├── image.jpg.img.c.rs.log.png
+├── index.svg
+├── j
+├── k
+├── l
+├── m
+├── n
+├── o
+├── p
+├── q
+└── vagrant
+   ├── debug
+   │  └── symlinking -> a
+   ├── dev
+   │  └── main.bf
+   └── log
+      ├── file.png
+      └── run
+         ├── run.log.text
+         └── sps.log.text
diff --git a/tests/cmd/tree_unix.toml b/tests/cmd/tree_unix.toml
new file mode 100644
index 000000000..62ec7172b
--- /dev/null
+++ b/tests/cmd/tree_unix.toml
@@ -0,0 +1,2 @@
+bin.name = "eza"
+args = "tests/itest --tree"