Repository: pkolaczk/fclones (language: rust)

Issue:
--unique shows non unique files
Hi - I'm new to using fclones and have found it to be a huge improvement over the other duplicate file finders out there. However, I'm having a hard time making sense of the `--unique` flag. For example,

```
mkdir foo
echo a > foo/a
echo b > foo/b
echo c > foo/c
echo c > foo/copy_of_c
```

Output of `fclones group --unique foo`:
```
[2022-08-25 16:03:47.382] fclones:  info: Started grouping
[2022-08-25 16:03:47.384] fclones:  info: Scanned 5 file entries
[2022-08-25 16:03:47.384] fclones:  info: Found 4 (8 B) files matching selection criteria
[2022-08-25 16:03:47.384] fclones:  info: Found 0 (0 B) candidates after grouping by size
[2022-08-25 16:03:47.384] fclones:  info: Found 0 (0 B) candidates after grouping by paths
[2022-08-25 16:03:47.386] fclones:  info: Found 2 (4 B) candidates after grouping by prefix
[2022-08-25 16:03:47.386] fclones:  info: Found 2 (4 B) candidates after grouping by suffix
[2022-08-25 16:03:47.386] fclones:  info: Found 2 (4 B) unique files
# Report by fclones 0.27.0
# Timestamp: 2022-08-25 16:03:47.386 -0400
# Command: fclones group --unique foo
# Base dir: /home/dan
# Total: 8 B (8 B) in 4 files in 3 groups
# Redundant: 0 B (0 B) in 0 files
# Missing: 4 B (4 B) in 2 files
6f973377854c3f70db84707e1de8d1a0, 2 B (2 B) * 1:
    /home/dan/foo/a
57f77e37a6de146f34541732cef23436, 2 B (2 B) * 2:
    /home/dan/foo/c
    /home/dan/foo/copy_of_c
13385bf32d48b5c03331333a6a16c7bd, 2 B (2 B) * 1:
    /home/dan/foo/b  
```

I'm surprised to be seeing `c` and `copy_of_c` at all. The csv format makes it easiest to distinguish the difference because of the file count column:
```
[2022-08-25 16:04:51.621] fclones:  info: Started grouping
[2022-08-25 16:04:51.622] fclones:  info: Scanned 5 file entries
[2022-08-25 16:04:51.622] fclones:  info: Found 4 (8 B) files matching selection criteria
[2022-08-25 16:04:51.623] fclones:  info: Found 0 (0 B) candidates after grouping by size
[2022-08-25 16:04:51.623] fclones:  info: Found 0 (0 B) candidates after grouping by paths
[2022-08-25 16:04:51.628] fclones:  info: Found 2 (4 B) candidates after grouping by prefix
[2022-08-25 16:04:51.628] fclones:  info: Found 2 (4 B) candidates after grouping by suffix
[2022-08-25 16:04:51.628] fclones:  info: Found 2 (4 B) unique files
size,hash,count,files
2,6f973377854c3f70db84707e1de8d1a0,1,/home/dan/foo/a
2,57f77e37a6de146f34541732cef23436,2,/home/dan/foo/c,/home/dan/foo/copy_of_c
2,13385bf32d48b5c03331333a6a16c7bd,1,/home/dan/foo/b  
```

Though it's still dependent on me doing a filter of the output. This is complicated by the CSV not escaping the commas, so typical CLI tools consider it an invalid CSV (would you accept a PR quoting the files column?).

Is it expected to display non-unique files in the output of `group --unique`? I had expected it to only produce groups of files of size 1, the inverse of the normal behavior.

Thanks!


Discussion / hints:

Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 8678318..9dc0f5f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -324,7 +324,7 @@ dependencies = [
 
 [[package]]
 name = "fclones"
-version = "0.27.0"
+version = "0.27.1"
 dependencies = [
  "atomic-counter",
  "bincode",
diff --git a/Cargo.toml b/Cargo.toml
index fa02865..3fbb3cd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "fclones"
-version = "0.27.0"
+version = "0.27.1"
 description = "Finds duplicate, unique, under- or over-replicated files"
 authors = ["Piotr Kołaczkowski <pkolaczk@gmail.com>"]
 homepage = "https://github.com/pkolaczk/fclones"
diff --git a/src/config.rs b/src/config.rs
index f6ec0c0..fd39889 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -109,7 +109,7 @@ fn is_positive_int(v: String) -> Result<(), String> {
             return Ok(());
         }
     }
-    return Err(format!("Not a positive integer: {}", &*v));
+    Err(format!("Not a positive integer: {}", &*v))
 }
 
 #[derive(Clone, Copy, Debug)]
diff --git a/src/group.rs b/src/group.rs
index 80345c5..c67f239 100644
--- a/src/group.rs
+++ b/src/group.rs
@@ -607,8 +607,8 @@ where
             file_hash: hash,
             files: files.to_vec(),
         })
-        .filter(group_post_filter)
         .chain(groups_to_pass.into_iter())
+        .filter(group_post_filter)
         .collect()
 }
 
@@ -1790,6 +1790,28 @@ mod test {
         })
     }
 
+    #[test]
+    fn unique_files() {
+        with_dir("main/unique_files", |root| {
+            let file1 = root.join("file1");
+            let file2 = root.join("file2");
+            let file3 = root.join("file3");
+            write_test_file(&file1, b"duplicate", b"", b"");
+            write_test_file(&file2, b"duplicate", b"", b"");
+            write_test_file(&file3, b"unique", b"", b"");
+
+            let file3 = Path::from(file3);
+
+            let log = test_log();
+            let mut config = GroupConfig::default();
+            config.unique = true;
+            config.paths = vec![file1.into(), file2.into(), file3.clone()];
+            let results = group_files(&config, &log).unwrap();
+            assert_eq!(results.len(), 1);
+            assert_eq!(results[0].files[0].path, file3);
+        });
+    }
+
     #[test]
     fn report() {
         with_dir("main/report", |root| {


Test patch: