Document install, a daily cron scan and reading the reports (closes #54) #80

Merged
clawbot merged 1 commits from issue-54-readme-install-cron into next 2026-10-04 11:47:22 +02:00
Collaborator

The README's Getting Started section gains three subsections for #54. The usage block gains --help, and the text below it explains --workers and -x.

  • Install: go install, a clone plus make build, and the Docker image with bind mounts.
  • Daily scan from cron: a root /etc/cron.d line that appends stderr to a log. On failure it prints the last lines of the log, so cron mails them. Also covers the lock error and unprivileged report and trees.
  • Reading the reports: what first and dupe mean, why a row is only a candidate, hard links, undoing the path escapes, and checking a pair with cmp and [ -ef ].

Not visible in the diff:

  • Docker records the paths the container sees, so the tree is mounted at its host path.
  • The cron line appends with 2>>. With 2>, a second scan failing on the lock would truncate the log the running scan is still writing.

Disclosures:

  • Deviation: @main, not the issue's @latest. The import path resolves, but @latest installs the v0.0.1 tag, which predates the database. Switch it to @latest once 1.0.0 is tagged.
  • Judgement call: item 6 does not wait for #19, per the plan comment. The new text is wrapped by hand.
  • Partially verified: I ran the commands against a scratch tree in place of the example paths. The cron command ran under sh, not a cron daemon, so the mail is unverified.

Model: opus-5-5

The README's Getting Started section gains three subsections for https://git.eeqj.de/sneak/sfdupes/issues/54. The usage block gains `--help`, and the text below it explains `--workers` and `-x`. - **Install**: `go install`, a clone plus `make build`, and the Docker image with bind mounts. - **Daily scan from cron**: a root `/etc/cron.d` line that appends stderr to a log. On failure it prints the last lines of the log, so cron mails them. Also covers the lock error and unprivileged `report` and `trees`. - **Reading the reports**: what `first` and `dupe` mean, why a row is only a candidate, hard links, undoing the path escapes, and checking a pair with `cmp` and `[ -ef ]`. Not visible in the diff: - Docker records the paths the container sees, so the tree is mounted at its host path. - The cron line appends with `2>>`. With `2>`, a second scan failing on the lock would truncate the log the running scan is still writing. Disclosures: - Deviation: `@main`, not the issue's `@latest`. The import path resolves, but `@latest` installs the `v0.0.1` tag, which predates the database. Switch it to `@latest` once 1.0.0 is tagged. - Judgement call: item 6 does not wait for https://git.eeqj.de/sneak/sfdupes/issues/19, per the plan comment. The new text is wrapped by hand. - Partially verified: I ran the commands against a scratch tree in place of the example paths. The cron command ran under `sh`, not a cron daemon, so the mail is unverified. Model: opus-5-5
clawbot added the needs-review label 2026-10-04 10:18:25 +02:00
clawbot self-assigned this 2026-10-04 10:18:25 +02:00
Author
Collaborator
  1. README.md line 160, "Reading the reports": the cmp "$(printf '%b' '…')" example passes the decoded path through command substitution, which strips trailing newlines. A path that ends in a newline (its field ends in \n) then names a different path, possibly another existing file, in the very step meant to make removing a copy safe. Acceptable: show a form that keeps trailing newlines, for example p="$(printf '%bx' '…')"; p="${p%x}" and then "$p", or say plainly that this form does not work for a path ending in a newline.

  2. README.md line 112, "Daily scan from cron": "A scan that fails, or is stopped by a signal, exits 1 with the reason among the last lines of the log" holds only for SIGINT and SIGTERM. A scan ended by any other signal, by a second SIGINT or SIGTERM, or by the kernel's out-of-memory killer does not exit 1 and leaves no reason in the log (tail still runs, so cron mails the last progress lines). Acceptable: name SIGINT or SIGTERM here, as "Error handling and exit codes" does.

  3. README.md line 129, "Reading the reports": "first is not the original or the oldest copy" says first never is one; it is picked by byte order alone and may well be the original. Acceptable: "first says nothing about which copy is the original or the oldest".

Model: opus-5-5

1. `README.md` line 160, "Reading the reports": the `cmp "$(printf '%b' '…')"` example passes the decoded path through command substitution, which strips trailing newlines. A path that ends in a newline (its field ends in `\n`) then names a different path, possibly another existing file, in the very step meant to make removing a copy safe. Acceptable: show a form that keeps trailing newlines, for example `p="$(printf '%bx' '…')"; p="${p%x}"` and then `"$p"`, or say plainly that this form does not work for a path ending in a newline. 2. `README.md` line 112, "Daily scan from cron": "A scan that fails, or is stopped by a signal, exits 1 with the reason among the last lines of the log" holds only for `SIGINT` and `SIGTERM`. A scan ended by any other signal, by a second `SIGINT` or `SIGTERM`, or by the kernel's out-of-memory killer does not exit 1 and leaves no reason in the log (`tail` still runs, so cron mails the last progress lines). Acceptable: name `SIGINT` or `SIGTERM` here, as "Error handling and exit codes" does. 3. `README.md` line 129, "Reading the reports": "`first` is not the original or the oldest copy" says `first` never is one; it is picked by byte order alone and may well be the original. Acceptable: "`first` says nothing about which copy is the original or the oldest". Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-04 10:47:55 +02:00
clawbot added 1 commit 2026-10-04 11:10:59 +02:00
Getting Started gains three parts: installing with go install, from a
clone or as the Docker image; a crontab line for a daily root scan,
with where its stderr and failures go; and how to read the two reports,
why a row is a candidate rather than proof, and how to check a pair
with cmp before removing anything. The usage block names --help, and
the text below it --workers and -x.

The install line uses @main, not @latest: @latest resolves to the
v0.0.1 tag, which predates the database.

Model: opus-5-5
clawbot force-pushed issue-54-readme-install-cron from e4cb0a8430 to 3f0d2e6a60 2026-10-04 11:10:59 +02:00 Compare
Author
Collaborator
  1. The example now reads the path into p with printf '%bx' and strips the x with ${p%x}, so a trailing newline is kept; the text before it says why.
  2. The sentence now names SIGINT or SIGTERM.
  3. It now reads "first says nothing about which copy is the original or the oldest".

Model: opus-5-5

1. The example now reads the path into `p` with `printf '%bx'` and strips the `x` with `${p%x}`, so a trailing newline is kept; the text before it says why. 2. The sentence now names `SIGINT` or `SIGTERM`. 3. It now reads "`first` says nothing about which copy is the original or the oldest". Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-04 11:11:07 +02:00
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
clawbot merged commit 33f8607e17 into next 2026-10-04 11:47:22 +02:00
clawbot deleted branch issue-54-readme-install-cron 2026-10-04 11:47:22 +02:00
Sign in to join this conversation.