-
Notifications
You must be signed in to change notification settings - Fork 82
Add colored stream output support for deploy logs #256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #256 +/- ##
=======================================
Coverage ? 73.03%
=======================================
Files ? 70
Lines ? 10850
Branches ? 0
=======================================
Hits ? 7924
Misses ? 1961
Partials ? 965 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Adds an opt-in colorized deploy/build log output mode to improve readability, controlled by TSURU_COLOR_STREAM and honoring TSURU_DISABLE_COLORS.
Changes:
- Introduces a new colored stream writer that adds timestamps and visual indicators for sections/actions/errors.
- Adds a
ColorStream()config helper (v2) and wires it into streaming output paths. - Updates dependencies (notably
github.com/tsuru/tsuru) to support/align with the new formatting behavior.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tsuru/formatter/stream.go | Enables colored streaming for JSON-stream API responses when ColorStream() is enabled. |
| tsuru/formatter/coloredstream.go | New colored/timestamped writer that formats section/action/error lines with indicators and ANSI colors. |
| tsuru/formatter/coloredstream_test.go | Unit tests for the colored stream writer behavior. |
| tsuru/cmd/v2/config.go | Adds ColorStream() configuration gate (env/config driven). |
| tsuru/cmd/v2/root_test.go | Adds tests for ColorStream() behavior across env var combinations. |
| tsuru/client/deploy.go | Uses the colored stream writer for deploy/build output when enabled. |
| go.mod | Bumps github.com/tsuru/tsuru and adjusts indirect dependencies. |
| go.sum | Updates checksums for the dependency changes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
745bd12 to
945cfd0
Compare
Introduce a new colorized log formatter that enhances readability of deploy output by adding visual indicators and timestamps. The formatter categorizes log lines as section headers (blue), actions (green), errors (red), or regular output, making it easier to follow deployment progress. The feature is opt-in via the TSURU_COLOR_STREAM environment variable and respects the existing TSURU_DISABLE_COLORS setting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Co-authored-by: Copilot <[email protected]>
2e5f09c to
bdc357a
Compare
The Write method now buffers incomplete lines across calls, ensuring chunked input (common with streaming HTTP responses) is handled correctly. Also adds defense-in-depth checks for malformed section and error lines. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| elapsedSeconds := time.Since(w.Started).Seconds() | ||
|
|
||
| for { | ||
| idx := bytes.IndexByte(data, '\n') | ||
| if idx == -1 { | ||
| // No newline found; save remainder for next Write call | ||
| if len(data) > 0 { | ||
| w.pending = make([]byte, len(data)) | ||
| copy(w.pending, data) | ||
| } | ||
| break | ||
| } | ||
|
|
||
| line := string(data[:idx]) | ||
| data = data[idx+1:] | ||
|
|
||
| if len(line) == 0 { | ||
| continue | ||
| } | ||
|
|
||
| w.writeTimestamp(elapsedSeconds) | ||
| w.writeFormattedLine(line) |
Copilot
AI
Jan 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
elapsedSeconds is computed once per Write call and reused for every line in the chunk, so multiple lines can end up with identical timestamps even if processing spans noticeable time (and it also makes timestamps for buffered/chunked output less accurate). Recompute time.Since(w.Started).Seconds() inside the loop right before writeTimestamp so each emitted line gets an accurate elapsed time.
| func prepareUploadStreams(context *cmd.Context, buf *safe.Buffer) io.Writer { | ||
| context.Stdout = &safeWriter{w: context.Stdout} | ||
|
|
||
| if v2.ColorStream() { |
Copilot
AI
Jan 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When ColorStream() is enabled, this path stops using firstWriter (which writes a one-time " ok\n" before the first server output). That ok is currently what terminates the "Uploading files ..." progress line started in uploadFiles (tsuru/client/build.go:166), so colored mode will leave the progress line without the expected completion marker and can interleave oddly with the first streamed output. Consider keeping the firstWriter behavior (or emitting an equivalent " ok\n" once) before starting colored streaming.
| if v2.ColorStream() { | |
| if v2.ColorStream() { | |
| fmt.Fprint(context.Stdout, " ok\n") |
| func ColorStream() bool { | ||
| if ColorDisabled() { | ||
| return false | ||
| } | ||
|
|
||
| def := term.IsTerminal(int(os.Stdout.Fd())) | ||
|
|
||
| key := "color-stream" | ||
| if defaultViper.IsSet(key) { | ||
| return defaultViper.GetBool(key) | ||
| } | ||
| return def | ||
| } |
Copilot
AI
Jan 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ColorStream() currently defaults to term.IsTerminal(os.Stdout.Fd()), which effectively enables the feature by default on interactive terminals. This conflicts with the PR description stating the feature is opt-in via TSURU_COLOR_STREAM, and it can also enable colored streaming in cases where the command is writing to a non-terminal context.Stdout (tests/embedded usage), since the check is tied to os.Stdout rather than the actual output writer. To match the opt-in behavior and avoid surprising output, consider defaulting to false unless TSURU_COLOR_STREAM/config explicitly enables it (and/or moving the terminal detection closer to where the actual writer is known).
Introduce a new colorized log formatter that enhances readability of deploy output by adding visual indicators and timestamps. The formatter categorizes log lines as section headers (blue), actions (green), errors (red), or regular output, making it easier to follow deployment progress.
The feature is opt-in via the TSURU_COLOR_STREAM environment variable and respects the existing TSURU_DISABLE_COLORS setting.