Skip to content

Write machine-readable list output to os.Stdout in a single write - #1501

Merged
Slach merged 3 commits into
masterfrom
fix_list_json_stdout_splice
Aug 14, 2026
Merged

Write machine-readable list output to os.Stdout in a single write#1501
Slach merged 3 commits into
masterfrom
fix_list_json_stdout_splice

Conversation

@Slach

@Slach Slach commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

PrintBackup routed every format through a tabwriter over os.Stdout. tabwriter auto-flushes lines that contain no tabs, but emits the payload and its terminating newline as two separate Write calls. Since zerolog logs to stderr, a log line can land between them whenever both streams are merged - e.g. docker exec, where the daemon reads the container's stdout and stderr from separate pipes with no ordering guarantee. The result is a spliced line, ...}]2026-08-11 18:29:25 INF ..., which made list remote --format=json unparseable and flaked TestRebaseFTP with "invalid character '2' after top-level value".

json/yaml/csv/tsv now write straight to os.Stdout in one Fprintln, so the payload and its newline reach the pipe as a single write. This also removes an inconsistency: those branches never called w.Flush() and worked only by way of tabwriter's implicit single-cell flush. tabwriter stays in the "text" branch, the only one that needs column alignment.

Slach added 2 commits August 12, 2026 08:07
PrintBackup routed every format through a tabwriter over os.Stdout.
tabwriter auto-flushes lines that contain no tabs, but emits the payload
and its terminating newline as two separate Write calls. Since zerolog
logs to stderr, a log line can land between them whenever both streams
are merged - e.g. `docker exec`, where the daemon reads the container's
stdout and stderr from separate pipes with no ordering guarantee. The
result is a spliced line, `...}]2026-08-11 18:29:25 INF ...`, which made
`list remote --format=json` unparseable and flaked TestRebaseFTP with
"invalid character '2' after top-level value".

json/yaml/csv/tsv now write straight to os.Stdout in one Fprintln, so
the payload and its newline reach the pipe as a single write. This also
removes an inconsistency: those branches never called w.Flush() and
worked only by way of tabwriter's implicit single-cell flush. tabwriter
stays in the "text" branch, the only one that needs column alignment.
@coveralls

coveralls commented Aug 13, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 31726025878

Coverage at 69.241% (no base build to compare)

Details

  • Coverage remained the same as the base build.
  • Patch coverage: 12 of 12 lines across 2 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 25316
Covered Lines: 17529
Line Coverage: 69.24%
Coverage Strength: 45203.28 hits per line

💛 - Coveralls

@Slach
Slach merged commit 66ec441 into master Aug 14, 2026
55 of 56 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants