Skip to main content

Merge pull request #81 from alexwlchan/cli-tests

ID
6ad6f39
date
2026-02-26 14:12:57+00:00
author
Alex Chan <alex@alexwlchan.net>
parents
6702fdf, e0c24bf
message
Merge pull request #81 from alexwlchan/cli-tests

cli: allow running `emptydir .` to delete current dir
changed files
5 files, 248 additions, 17 deletions

Changed files

CHANGELOG.md (1793) → CHANGELOG.md (1934)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index a34c182..a800f87 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+## v1.3.1 - 2026-02-26
+
+`emptydir` can now clean up the current directory by running `emptydir .`; previously this returned an os error 22.
+
 ## v1.3.0 - 2025-12-16
 
 If `emptydir` looks at a directory but there's a reason the directory can't be deleted, it now prints the reason.

Cargo.lock (11082) → Cargo.lock (15519)

diff --git a/Cargo.lock b/Cargo.lock
index 8f425fb..68ead52 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,6 +3,15 @@
 version = 4
 
 [[package]]
+name = "aho-corasick"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
 name = "anstream"
 version = "0.6.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -58,12 +67,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
 
 [[package]]
+name = "assert_cmd"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c5bcfa8749ac45dd12cb11055aeeb6b27a3895560d60d71e3c23bf979e60514"
+dependencies = [
+ "anstyle",
+ "bstr",
+ "libc",
+ "predicates",
+ "predicates-core",
+ "predicates-tree",
+ "wait-timeout",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+
+[[package]]
 name = "bitflags"
 version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
 
 [[package]]
+name = "bstr"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab"
+dependencies = [
+ "memchr",
+ "regex-automata",
+ "serde",
+]
+
+[[package]]
 name = "cfg-if"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -125,12 +166,20 @@ dependencies = [
 ]
 
 [[package]]
+name = "difflib"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
+
+[[package]]
 name = "emptydir"
-version = "1.3.0"
+version = "1.3.1"
 dependencies = [
+ "assert_cmd",
  "clap",
  "colored",
  "num-format",
+ "predicates",
  "tempfile",
  "walkdir",
 ]
@@ -152,6 +201,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
 
 [[package]]
+name = "float-cmp"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
 name = "getrandom"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -194,6 +252,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
 
 [[package]]
+name = "memchr"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+
+[[package]]
+name = "normalize-line-endings"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
+
+[[package]]
 name = "num-format"
 version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -204,12 +274,51 @@ dependencies = [
 ]
 
 [[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
 name = "once_cell"
 version = "1.19.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
 
 [[package]]
+name = "predicates"
+version = "3.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe"
+dependencies = [
+ "anstyle",
+ "difflib",
+ "float-cmp",
+ "normalize-line-endings",
+ "predicates-core",
+ "regex",
+]
+
+[[package]]
+name = "predicates-core"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144"
+
+[[package]]
+name = "predicates-tree"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2"
+dependencies = [
+ "predicates-core",
+ "termtree",
+]
+
+[[package]]
 name = "proc-macro2"
 version = "1.0.85"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -228,6 +337,35 @@ dependencies = [
 ]
 
 [[package]]
+name = "regex"
+version = "1.12.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
+
+[[package]]
 name = "rustix"
 version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -250,6 +388,26 @@ dependencies = [
 ]
 
 [[package]]
+name = "serde"
+version = "1.0.210"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.210"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "strsim"
 version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -280,6 +438,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "termtree"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
+
+[[package]]
 name = "unicode-ident"
 version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -292,6 +456,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 
 [[package]]
+name = "wait-timeout"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11"
+dependencies = [
+ "libc",
+]
+
+[[package]]
 name = "walkdir"
 version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"

Cargo.toml (200) → Cargo.toml (238)

diff --git a/Cargo.toml b/Cargo.toml
index d69133b..f5f5d4e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,11 +1,13 @@
 [package]
 name = "emptydir"
-version = "1.3.0"
+version = "1.3.1"
 edition = "2021"
 
 [dependencies]
+assert_cmd = "2.1.2"
 clap = { version = "4.5.60", features = ["derive"] }
 colored = "3.1.1"
 num-format = "0.4.4"
+predicates = "3"
 tempfile = "3"
 walkdir = "2"

src/emptydir.rs (7038) → src/emptydir.rs (6734)

diff --git a/src/emptydir.rs b/src/emptydir.rs
index a8802bd..beaff71 100644
--- a/src/emptydir.rs
+++ b/src/emptydir.rs
@@ -105,18 +105,6 @@ mod test_emptydir {
     }
 
     #[test]
-    fn it_doesnt_delete_my_do_not_backup() {
-        let dir = Path::new("/Users/alexwlchan/Desktop/do not back up");
-        assert_eq!(
-            emptydir(dir),
-            EmptydirResult {
-                count_deleted: 0,
-                count_errors: 0
-            }
-        );
-    }
-
-    #[test]
     fn it_doesnt_delete_a_non_existent_directory() {
         let dir = Path::new("/does/not/exist");
         assert_eq!(

src/main.rs (1233) → src/main.rs (2819)

diff --git a/src/main.rs b/src/main.rs
index 7c2319a..39aad81 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,8 @@
 #![deny(warnings)]
 
+use std::fs;
 use std::path::Path;
+use std::process;
 
 use clap::Parser;
 use colored::*;
@@ -20,17 +22,21 @@ struct Cli {
 fn main() -> Result<(), std::io::Error> {
     let cli = Cli::parse();
 
-    let root = Path::new(&cli.root);
-    let result = emptydir::emptydir(root);
+    let root = fs::canonicalize(Path::new(&cli.root))?;
+    let result = emptydir::emptydir(&root);
 
     match (result.count_deleted, result.count_errors) {
         (0, 0) => match can_be_deleted::can_be_deleted(&root) {
             can_be_deleted::DeleteDecision::CannotDelete(reason) => {
                 eprintln!("{}", reason.to_string().red());
+                process::exit(1);
             }
             _ => (),
         },
-        (0, _) => println!("{}", "Unable to delete empty directories".red()),
+        (0, _) => {
+            println!("{}", "Unable to delete empty directories".red());
+            process::exit(1);
+        }
         (1, _) => println!("{}", "1 directory deleted".green()),
         _ => {
             let message = format!(
@@ -43,3 +49,61 @@ fn main() -> Result<(), std::io::Error> {
 
     Ok(())
 }
+
+#[cfg(test)]
+mod test_emptydir {
+    use std::fs;
+    use std::path::PathBuf;
+
+    use assert_cmd::Command;
+    use predicates::prelude::*;
+
+    fn test_dir() -> PathBuf {
+        let tmp_dir = tempfile::tempdir().unwrap();
+        let path = tmp_dir.path();
+        path.to_owned()
+    }
+
+    fn create_dir(dir: &PathBuf) {
+        fs::create_dir_all(dir).unwrap();
+    }
+
+    #[expect(
+        deprecated,
+        reason = "cargo_bin is deprecated, cargo_bin! is not, `use` does not differenciate them"
+    )]
+    #[test]
+    fn it_prints_the_version() {
+        // Match strings like `emptydir 1.2.3`
+        let is_version_string =
+            predicate::str::is_match(r"^emptydir [0-9]+\.[0-9]+\.[0-9]+\n$").unwrap();
+
+        Command::cargo_bin("emptydir")
+            .unwrap()
+            .arg("--version")
+            .assert()
+            .success()
+            .stdout(is_version_string)
+            .stderr("");
+    }
+
+    #[expect(
+        deprecated,
+        reason = "cargo_bin is deprecated, cargo_bin! is not, `use` does not differenciate them"
+    )]
+    #[test]
+    fn it_deletes_dot_directory() {
+        let dir = test_dir();
+
+        // Create the directory, but don't put anything in it
+        create_dir(&dir);
+
+        Command::cargo_bin("emptydir")
+            .unwrap()
+            .current_dir(&dir)
+            .arg(".")
+            .assert()
+            .success();
+        assert_eq!(dir.exists(), false);
+    }
+}