1 Commits
Author SHA1 Message Date
sneak c87304135b Rewrite README.md sentence by sentence for a newcomer
check / check (push) Canceled after 0s
Rewrites `README.md` from scratch for
#135. Every statement was checked
against the code on `next` and against what the built binary prints on
small trees under `/var/tmp`. The headings that the code comments cite
are kept. Five `main_test.go` comments cite "Settings", two cite what
"Error handling" says about a failed write to stdout, and one comment
each in `scan_test.go`, `trees_test.go` and `exclude_test.go` cites what
the README now says.

Where the old text and the repository disagreed, the new text states
what the code does: `@latest` installs the newest tagged release, ten
million files in both "Rationale" and "Design", no Windows excludes, and
an operand reached through a symlinked directory below another operand
is dropped (#144).

Model: fable-5-1
2026-10-26 17:13:19 +00:00
2 changed files with 14 additions and 13 deletions
+10 -9
View File
@@ -365,7 +365,7 @@ default. An operand may be a directory or a regular file.
- No other case keeps an operand under another. An operand reached through a
symlinked directory below the outer operand is dropped too, without a line.
The outer operand's walk does not follow the symlink, so no file under the
inner operand is scanned. The records an earlier scan left under it are
inner operand is scanned. The records that an earlier scan left under it are
deleted.
- An operand that is neither a regular file nor a directory is not scanned.
`scan` prints a warning naming the path and what it is. It counts the operand
@@ -466,8 +466,8 @@ walk practical on large or busy storage pools.
operand at the path given, even when that path runs through a symlinked
directory. Such an operand can lead to the database files, and the walk
passes over them there as well. The walk prints no line for the database
files and does not count them as skipped. A record an earlier scan left for
one of them is deleted.
files and does not count them as skipped. A record that an earlier scan left
for one of them is deleted.
- By default the walk enters directories on other filesystems than its
operand's. With `-x`, it never enters a directory on a different filesystem
@@ -556,7 +556,8 @@ walk practical on large or busy storage pools.
- A file or directory that disappears while the scan runs is not an error. The
scan prints no line for it and does not count it as skipped. A path gone when
the walk reaches it gets no record, and so does a file gone when the hash
phase opens it. The records an earlier scan left at or below it are deleted.
phase opens it. The records that an earlier scan left at or below it are
deleted.
#### Concurrency
@@ -668,8 +669,8 @@ Four bytes are written as escapes:
Every other byte is written unchanged, including bytes that are not valid UTF-8,
the usual text encoding. Undoing the four escapes gives back the stored path.
Grouping and ordering use the stored path. The warnings that `scan` prints are
escaped the same way, so each warning stays one line.
Grouping and ordering use the stored path. The warnings about skipped paths that
`scan` prints are escaped the same way, so each stays one line.
The summary line on stderr gives:
@@ -1037,9 +1038,9 @@ On a terminal:
- the elapsed time;
- the time remaining.
On a terminal narrower than about 75 columns, a line is cut short only hours
into a scan of millions of files. A terminal made narrower during a phase is
fitted at the next draw.
On a terminal 80 columns wide, no line is cut short, even hours into a scan
of millions of files. A terminal made narrower during a phase is fitted at
the next draw.
- A warning printed during a phase lands on a line of its own, never inside the
display. So does every line written to stdout when stdout and stderr are the
+4 -4
View File
@@ -773,8 +773,8 @@ func TestBuildVersion(t *testing.T) {
func TestRunVersionWriteFailureIsFatal(t *testing.T) {
t.Parallel()
// README §Error handling: a stdout write failure exits 1, reported
// in one line on stderr.
// README §Error handling: a failed write to stdout is a fatal error,
// exit 1, reported on stderr starting with "sfdupes:".
var stderr bytes.Buffer
code := run([]string{"--version"}, failingWriter{}, &stderr)
@@ -1445,8 +1445,8 @@ func TestRunReportsDuringScan(t *testing.T) {
}
func TestRunStdoutClosedIsFatal(t *testing.T) {
// README §Error handling: a stdout write failure exits 1, reported
// in one line on stderr.
// README §Error handling: a failed write to stdout is a fatal error,
// exit 1, reported on stderr starting with "sfdupes:".
for _, name := range []string{cmdReport, cmdTrees, cmdInfo} {
t.Run(name, func(t *testing.T) {
t.Setenv(databaseEnv, testDBPath(t))