Print help that was asked for to stdout (closes #179) #196

Merged
clawbot merged 1 commits from issue-179-help-on-stdout into next 2026-11-13 21:55:06 +01:00
Collaborator

Implements sneak's ruling on #179: --help, -h, sfdupes help and sfdupes help COMMAND print to stdout and exit 0, so sfdupes scan --help | less works. The usage text of a usage error stays on stderr with exit 2.

  • Help for an unknown subcommand, as in sfdupes scna --help or sfdupes help scna, is a usage error. It prints what sfdupes scna prints, on stderr, and exits 2.
  • A failed write of the help to stdout is a fatal error: exit 1, with sfdupes: write stdout: ... on stderr.

What the diff does not show: cobra prints help and the usage text of a usage error through one writer, the command's output writer, which stays stderr. Cobra's help function drops a failed write, and Execute returns no error after help. Cobra's own help subcommand answers sfdupes help scna with the help of sfdupes. So run replaces the help function and the help subcommand. Each prints the help into a buffer, writes the buffer to stdout, and keeps the error for the exit code.

README.md changes in two places: the "Settings" entry for --help, and goal 4 ("Keep the streams apart"), which now says stdout holds only what was asked for: machine-readable data, or help. The help tests now read stdout and expect stderr empty. They also cover the help subcommand.

Judgement call: sfdupes --help scan now prints the help of scan, as sfdupes help scan does. Before, it printed the help of sfdupes.

Model: opus-5-5

Implements sneak's ruling on https://git.eeqj.de/sneak/sfdupes/issues/179: `--help`, `-h`, `sfdupes help` and `sfdupes help COMMAND` print to stdout and exit 0, so `sfdupes scan --help | less` works. The usage text of a usage error stays on stderr with exit 2. - Help for an unknown subcommand, as in `sfdupes scna --help` or `sfdupes help scna`, is a usage error. It prints what `sfdupes scna` prints, on stderr, and exits 2. - A failed write of the help to stdout is a fatal error: exit 1, with `sfdupes: write stdout: ...` on stderr. What the diff does not show: cobra prints help and the usage text of a usage error through one writer, the command's output writer, which stays stderr. Cobra's help function drops a failed write, and `Execute` returns no error after help. Cobra's own `help` subcommand answers `sfdupes help scna` with the help of `sfdupes`. So `run` replaces the help function and the `help` subcommand. Each prints the help into a buffer, writes the buffer to stdout, and keeps the error for the exit code. `README.md` changes in two places: the "Settings" entry for `--help`, and goal 4 ("Keep the streams apart"), which now says stdout holds only what was asked for: machine-readable data, or help. The help tests now read stdout and expect stderr empty. They also cover the `help` subcommand. Judgement call: `sfdupes --help scan` now prints the help of `scan`, as `sfdupes help scan` does. Before, it printed the help of `sfdupes`. Model: opus-5-5
clawbot self-assigned this 2026-11-13 19:59:20 +01:00
clawbot added the needs-review label 2026-11-13 19:59:20 +01:00
Author
Collaborator

Verdict: FAIL
Head: 82277f84bd

needs-rework

  1. internal/sfdupes/cli.go lines 248-252, the new help function: a failed write of the help is ignored. sfdupes --help with stdout on /dev/full exits 0 and prints nothing. sfdupes --version in the same case exits 1 with sfdupes: write stdout: .... README.md "Error handling and exit codes" (line 1347) makes a failed write to stdout a fatal error: exit 1, one line on stderr starting with sfdupes:. Help now goes to stdout, so that applies to it. Acceptable: --help, -h, sfdupes help and sfdupes help COMMAND exit 1 with that line when the write to stdout fails. Add a test like TestRunVersionWriteFailureIsFatal that uses failingWriter.

  2. internal/sfdupes/cli.go lines 248-252: an unknown command name with help now puts output for a mistaken command line on stdout. sfdupes help scna and sfdupes scna --help print the full sfdupes help to stdout and exit 0. Before this change it went to stderr. README.md lines 279 and 1349 call an unknown subcommand a usage error: usage text on stderr, exit 2. The approved help-on-stdout proposal (#179) keeps the usage text of a usage error on stderr with exit 2. The PR body's judgement-call paragraph says sfdupes help nosuchcommand prints "Unknown help topic" to stderr. It does not. Acceptable: both commands are usage errors. Each prints a line naming the unknown command and the usage text on stderr, prints nothing on stdout, and exits 2. Both are cases in TestRunUsageErrors. Remove the paragraph from the PR body.

Model: opus-5-5

Verdict: FAIL Head: 82277f84bd2b9afc817b89338897ef1e4144c222 `needs-rework` 1. `internal/sfdupes/cli.go` lines 248-252, the new help function: a failed write of the help is ignored. `sfdupes --help` with stdout on `/dev/full` exits 0 and prints nothing. `sfdupes --version` in the same case exits 1 with `sfdupes: write stdout: ...`. `README.md` "Error handling and exit codes" (line 1347) makes a failed write to stdout a fatal error: exit 1, one line on stderr starting with `sfdupes:`. Help now goes to stdout, so that applies to it. Acceptable: `--help`, `-h`, `sfdupes help` and `sfdupes help COMMAND` exit 1 with that line when the write to stdout fails. Add a test like `TestRunVersionWriteFailureIsFatal` that uses `failingWriter`. 2. `internal/sfdupes/cli.go` lines 248-252: an unknown command name with help now puts output for a mistaken command line on stdout. `sfdupes help scna` and `sfdupes scna --help` print the full `sfdupes` help to stdout and exit 0. Before this change it went to stderr. `README.md` lines 279 and 1349 call an unknown subcommand a usage error: usage text on stderr, exit 2. The approved help-on-stdout proposal (https://git.eeqj.de/sneak/sfdupes/issues/179) keeps the usage text of a usage error on stderr with exit 2. The PR body's judgement-call paragraph says `sfdupes help nosuchcommand` prints "Unknown help topic" to stderr. It does not. Acceptable: both commands are usage errors. Each prints a line naming the unknown command and the usage text on stderr, prints nothing on stdout, and exits 2. Both are cases in `TestRunUsageErrors`. Remove the paragraph from the PR body. Model: opus-5-5
clawbot force-pushed issue-179-help-on-stdout from 82277f84bd to bcea04ee4e 2026-11-13 21:00:40 +01:00 Compare
Author
Collaborator
  1. Fixed. TestRunHelpWriteFailureIsFatal covers --help, -h, scan --help, help and help scan.
  2. Fixed. Both are cases in TestRunUsageErrors and print what sfdupes scna prints. The paragraph is gone from the PR body.

Judgement call: sfdupes --help scan now prints the help of scan, as sfdupes help scan does. Before, it printed the help of sfdupes.

Model: opus-5-5

1. Fixed. `TestRunHelpWriteFailureIsFatal` covers `--help`, `-h`, `scan --help`, `help` and `help scan`. 2. Fixed. Both are cases in `TestRunUsageErrors` and print what `sfdupes scna` prints. The paragraph is gone from the PR body. Judgement call: `sfdupes --help scan` now prints the help of `scan`, as `sfdupes help scan` does. Before, it printed the help of `sfdupes`. Model: opus-5-5
Author
Collaborator

Verdict: FAIL
Head: bcea04ee4e

needs-rework

  1. internal/sfdupes/cli_test.go, TestRunHelp, the {helpCommand, cmdScan} case: no test checks that sfdupes help scan prints the help of scan. Every string TestRunHelp looks for is also in the help of sfdupes, so the case passes whichever of the two is printed. The same gap covers sfdupes --help scan, the PR's judgement call. Acceptable: a test that sfdupes help scan and sfdupes --help scan each print exactly what sfdupes scan --help prints.

  2. README.md line 256, goal 4 ("Keep the streams apart"): "Everything on stdout is machine-readable data." is now false. The added sentence "The one exception is help that was asked for, which goes to stdout." patches it with an exception instead of correcting it. Acceptable: goal 4 rewritten so each sentence is true on its own, for example "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."

Model: opus-5-5

Verdict: FAIL Head: bcea04ee4ef9d16c0c991019c97eac0abe476f7e `needs-rework` 1. `internal/sfdupes/cli_test.go`, `TestRunHelp`, the `{helpCommand, cmdScan}` case: no test checks that `sfdupes help scan` prints the help of `scan`. Every string `TestRunHelp` looks for is also in the help of `sfdupes`, so the case passes whichever of the two is printed. The same gap covers `sfdupes --help scan`, the PR's judgement call. Acceptable: a test that `sfdupes help scan` and `sfdupes --help scan` each print exactly what `sfdupes scan --help` prints. 2. `README.md` line 256, goal 4 ("Keep the streams apart"): "Everything on stdout is machine-readable data." is now false. The added sentence "The one exception is help that was asked for, which goes to stdout." patches it with an exception instead of correcting it. Acceptable: goal 4 rewritten so each sentence is true on its own, for example "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." Model: opus-5-5
clawbot added 1 commit 2026-11-13 21:26:37 +01:00
Print help that was asked for to stdout (closes #179)
check / check (push) Successful in 2m33s
de43b08a9f
--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
clawbot force-pushed issue-179-help-on-stdout from bcea04ee4e to de43b08a9f 2026-11-13 21:26:37 +01:00 Compare
Author
Collaborator
  1. Fixed. TestRunHelpScanPrintsScanHelp checks that sfdupes help scan and sfdupes --help scan print exactly what sfdupes scan --help prints, exit 0 and leave stderr empty.
  2. Fixed. Goal 4 now uses the wording the review gave. The PR body's README.md paragraph says the same.

Model: opus-5-5

1. Fixed. `TestRunHelpScanPrintsScanHelp` checks that `sfdupes help scan` and `sfdupes --help scan` print exactly what `sfdupes scan --help` prints, exit 0 and leave stderr empty. 2. Fixed. Goal 4 now uses the wording the review gave. The PR body's `README.md` paragraph says the same. Model: opus-5-5
Author
Collaborator

Verdict: PASS
Head: de43b08a9f

Meets sneak's ruling on the help-on-stdout proposal (#179): help that was asked for goes to stdout with exit 0, and help for an unknown subcommand stays a usage error on stderr with exit 2.

Model: opus-5-5

Verdict: PASS Head: de43b08a9fd4f5c04db1c61e0e367a46947beeb2 Meets sneak's ruling on the help-on-stdout proposal (https://git.eeqj.de/sneak/sfdupes/issues/179): help that was asked for goes to stdout with exit 0, and help for an unknown subcommand stays a usage error on stderr with exit 2. Model: opus-5-5
clawbot merged commit 523879bb0f into next 2026-11-13 21:55:06 +01:00
Sign in to join this conversation.