sfdupes dwim: scan / with the default excludes, then print duplicate trees largest first #154

Closed
opened 2026-11-06 18:47:23 +01:00 by clawbot · 2 comments
Collaborator

sneak, in chat on 6 November:

add a “sfdupes dwim” command (do what i mean) that does a full scan of / (using the excludes built in like /proc etc) and then prints the list of duplicate trees by size descending. i want to be able to one-shot it on a new box and come back to it a day later and see what needs cleanup.

Definition of done:

  • sfdupes dwim takes no path. It runs scan / with the built-in default excludes (/proc and the rest, as scan applies them), then prints the duplicate-tree report (trees), largest trees first.
  • It needs no setup on a new box: no database, config file or flags beyond what scan already creates on its own. It runs unattended to the end, showing the same progress as scan.
  • When it ends, the report is still on the screen. Its last line says how to print the report again (sfdupes trees), so it can be read a day later even if the terminal was lost.
  • --help and the README's subcommand list describe it in one line each.
  • A test runs it against a temporary root in place of / and checks that the trees come out largest first.
  • make check passes.

Model: opus-5-5

sneak, in chat on 6 November: > add a “sfdupes dwim” command (do what i mean) that does a full scan of / (using the excludes built in like /proc etc) and then prints the list of duplicate trees by size descending. i want to be able to one-shot it on a new box and come back to it a day later and see what needs cleanup. **Definition of done:** - `sfdupes dwim` takes no path. It runs `scan /` with the built-in default excludes (`/proc` and the rest, as `scan` applies them), then prints the duplicate-tree report (`trees`), largest trees first. - It needs no setup on a new box: no database, config file or flags beyond what `scan` already creates on its own. It runs unattended to the end, showing the same progress as `scan`. - When it ends, the report is still on the screen. Its last line says how to print the report again (`sfdupes trees`), so it can be read a day later even if the terminal was lost. - `--help` and the README's subcommand list describe it in one line each. - A test runs it against a temporary root in place of `/` and checks that the trees come out largest first. - `make check` passes. Model: opus-5-5
clawbot self-assigned this 2026-11-06 18:47:23 +01:00
Author
Collaborator

For the worker: plan for sneak's order above.

Branch off current next; PR into next, title ending (closes #154). Package main, as for every other subcommand.

Behaviour:

  • sfdupes dwim takes no positional argument and no flag of its own; an argument is a usage error, exit 2, like trees with one.
  • It runs exactly what sfdupes scan / runs with no flags: --workers at its default, the default excludes on, crossing into other filesystems as scan does by default. Then it runs exactly what sfdupes trees runs, writing the report to stdout. trees already orders groups by total size, largest first; nothing about the order changes.
  • stderr carries what scan prints, then what trees prints, then one last line: dwim: run "sfdupes trees" to print this report again. It goes on stderr so that stdout stays the same tab-separated data trees prints.
  • SIGINT or SIGTERM stops it as it stops scan: the scan keeps what it has hashed, exits 1, and no report is printed. A fatal scan error also ends it before the report, with the same message and exit code as scan. Per-file warnings do not stop it, and it exits 0 as scan does.
  • No new setup: the database path, its creation and the scan lock are those of scan.

Code:

  • New dwim.go: runDwim(ctx, root string, stdout io.Writer) error calls runScan on root and then runTrees, then prints the last line. The command in main.go passes /; tests pass a temporary directory. No other parameter.
  • main.go: a dwim command built like trees (cobra.NoArgs), with the interrupt handling scan uses, and the package doc's usage block gains sfdupes dwim.
  • --help lists it with one line: "Scan / with the default excludes, then print the duplicate-tree report".

Tests (new dwim_test.go):

  • runDwim on a temporary root holding two duplicate-tree pairs of different total sizes prints the larger pair first on stdout, and stderr ends with the last line above.
  • sfdupes dwim extra exits 2.
  • Use realTempDir(t) for every directory scanned or compared.

README (README.md), then make fmt:

  • "Description": four subcommands becomes five, with one sentence for dwim.
  • "Subcommands": one bullet, and sfdupes dwim in the usage block.
  • A short dwim mode section in "Reference", after trees: what it runs, that it should run as root as scan should, what it prints and where, the last line, and the interrupt and error cases above.
  • "Error handling and exit codes": dwim with a positional argument is a usage error.
  • TODO.md: the step at the top of "Completed Steps", per its workflow.

Done when the issue's definition of done holds, make check passes on a fresh clone, and the PR body says what changed for a user in plain words.

Model: opus-5-5

For the worker: plan for sneak's order above. Branch off current `next`; PR into `next`, title ending ` (closes #154)`. Package `main`, as for every other subcommand. Behaviour: - `sfdupes dwim` takes no positional argument and no flag of its own; an argument is a usage error, exit 2, like `trees` with one. - It runs exactly what `sfdupes scan /` runs with no flags: `--workers` at its default, the default excludes on, crossing into other filesystems as `scan` does by default. Then it runs exactly what `sfdupes trees` runs, writing the report to stdout. `trees` already orders groups by total size, largest first; nothing about the order changes. - stderr carries what `scan` prints, then what `trees` prints, then one last line: `dwim: run "sfdupes trees" to print this report again`. It goes on stderr so that stdout stays the same tab-separated data `trees` prints. - `SIGINT` or `SIGTERM` stops it as it stops `scan`: the scan keeps what it has hashed, exits 1, and no report is printed. A fatal scan error also ends it before the report, with the same message and exit code as `scan`. Per-file warnings do not stop it, and it exits 0 as `scan` does. - No new setup: the database path, its creation and the scan lock are those of `scan`. Code: - New `dwim.go`: `runDwim(ctx, root string, stdout io.Writer) error` calls `runScan` on `root` and then `runTrees`, then prints the last line. The command in `main.go` passes `/`; tests pass a temporary directory. No other parameter. - `main.go`: a `dwim` command built like `trees` (`cobra.NoArgs`), with the interrupt handling `scan` uses, and the package doc's usage block gains `sfdupes dwim`. - `--help` lists it with one line: "Scan / with the default excludes, then print the duplicate-tree report". Tests (new `dwim_test.go`): - `runDwim` on a temporary root holding two duplicate-tree pairs of different total sizes prints the larger pair first on stdout, and stderr ends with the last line above. - `sfdupes dwim extra` exits 2. - Use `realTempDir(t)` for every directory scanned or compared. README (`README.md`), then `make fmt`: - "Description": four subcommands becomes five, with one sentence for `dwim`. - "Subcommands": one bullet, and `sfdupes dwim` in the usage block. - A short `dwim` mode section in "Reference", after `trees`: what it runs, that it should run as root as `scan` should, what it prints and where, the last line, and the interrupt and error cases above. - "Error handling and exit codes": `dwim` with a positional argument is a usage error. - `TODO.md`: the step at the top of "Completed Steps", per its workflow. Done when the issue's definition of done holds, `make check` passes on a fresh clone, and the PR body says what changed for a user in plain words. Model: opus-5-5
Author
Collaborator

Built as planned in #156: new dwim.go (runDwim), the dwim command in main.go, dwim_test.go, README and TODO.md. One deviation: the usage-error test for sfdupes dwim extra is a case in the existing table in main_test.go.

Model: opus-5-5

Built as planned in https://git.eeqj.de/sneak/sfdupes/pulls/156: new `dwim.go` (`runDwim`), the `dwim` command in `main.go`, `dwim_test.go`, README and `TODO.md`. One deviation: the usage-error test for `sfdupes dwim extra` is a case in the existing table in `main_test.go`. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/sfdupes#154