Compare commits

..
1 Commits
Author SHA1 Message Date
clawbot 523879bb0f Print help that was asked for to stdout (closes #179)
check / check (push) Successful in 1m50s
--help, -h and the help subcommand now print to stdout and exit 0, so
the help can be paged and searched. The usage text of a usage error
stays on stderr with exit 2, as does help for an unknown subcommand
("sfdupes help scna"). A failed write of the help exits 1.

Cobra prints help to the command's output writer, which stays stderr,
drops a failed write, and returns no error after help. So run replaces
the help function and the help subcommand: the help goes into a buffer,
then to stdout, and the error sets the exit code.

README "Settings" and goal 4 say so.

Model: opus-5-5
2026-11-13 21:55:05 +01:00
2 changed files with 33 additions and 3 deletions

No files matched your search

+3 -3
View File
@@ -253,9 +253,9 @@ In order:
`trees` check only that each copy they name still exists, and leave out a
copy that is gone. `scan` is built to run from `cron`. The reports run at any
time, against what the database holds.
4. **Keep the streams apart.** Everything on stdout is machine-readable data.
Everything for a human reader, such as progress and warnings, goes to stderr.
The one exception is help that was asked for, which goes to stdout.
4. **Keep the streams apart.** stdout holds only what was asked for:
machine-readable data, or help. Everything else for a human reader, such as
progress and warnings, goes to stderr.
### Subcommands
+30
View File
@@ -773,6 +773,36 @@ func TestRunHelp(t *testing.T) {
}
}
func TestRunHelpScanPrintsScanHelp(t *testing.T) {
t.Parallel()
// "sfdupes help scan" and "sfdupes --help scan" print exactly what
// "sfdupes scan --help" prints: the help of scan, not of sfdupes.
var want bytes.Buffer
run([]string{cmdScan, helpFlag}, &want, io.Discard)
for _, args := range [][]string{
{helpCommand, cmdScan}, {helpFlag, cmdScan},
} {
var stdout, stderr bytes.Buffer
code := run(args, &stdout, &stderr)
if code != exitOK {
t.Errorf("run(%v) = %d, want %d", args, code, exitOK)
}
if got := stdout.String(); got != want.String() {
t.Errorf("run(%v) stdout = %q, want what scan %s prints, %q",
args, got, helpFlag, want.String())
}
if got := stderr.String(); got != "" {
t.Errorf("run(%v) stderr = %q, want nothing", args, got)
}
}
}
func TestRunScanUsageLine(t *testing.T) {
t.Parallel()