Builder diagnostics go to stderr; stdout is the result alone

The logging added a line to stdout, and the genesis path parses the builder's
stdout as JSON — so the first log line broke the parse with "invalid character
'c'", the c from "[clone]". A build that had worked stopped working because of a
print statement.

The installer's runner captures stdout alone (cmd.Output), and the contract was
already stdout=result, stderr=everything else. The fix is to honour it: every
builder diagnostic — the step log, the per-command echo, the module path's own
lines — goes to stderr. Stdout carries only once.go's result JSON.

And a unit test now fails if any fmt.Print to stdout appears in the two builder
command files, except the three that belong there: the result, --version, and
--help. A guard, because this was invisible until a 20-minute run hit it, and the
same class of mistake should fail in milliseconds next time.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
2026-09-15 23:01:04 +02:00
parent 9070d2502c
commit 2fb700d61b
4 changed files with 57 additions and 13 deletions
+1 -1
View File
@@ -85,7 +85,7 @@ func buildOnce(ctx context.Context, args []string) error {
fmt.Fprintln(os.Stderr)
built, buildErr := builder.Build(ctx, builder.Command, publisher, repository, *path, *ref, where, bases,
func(step, message string) { fmt.Printf(" [%s] %s\n", step, message) })
func(step, message string) { fmt.Fprintf(os.Stderr, " [%s] %s\n", step, message) })
if buildErr != nil {
return buildErr
}