Skip to content

Conversation

@wpjunior
Copy link
Member

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.

@codecov-commenter
Copy link

codecov-commenter commented Jan 30, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 82.92683% with 14 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@8656a07). Learn more about missing BASE report.

Files with missing lines Patch % Lines
tsuru/formatter/stream.go 0.00% 9 Missing ⚠️
tsuru/client/deploy.go 25.00% 2 Missing and 1 partial ⚠️
tsuru/cmd/render.go 0.00% 1 Missing and 1 partial ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI left a 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.

@wpjunior wpjunior force-pushed the feature/colored-streams branch from 745bd12 to 945cfd0 Compare January 30, 2026 16:38
wpjunior and others added 3 commits January 30, 2026 16:30
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]>
@wpjunior wpjunior force-pushed the feature/colored-streams branch from 2e5f09c to bdc357a Compare January 30, 2026 19:57
wpjunior and others added 2 commits January 30, 2026 18:52
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]>
Copy link
Contributor

Copilot AI left a 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.

Comment on lines +58 to +79
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)
Copy link

Copilot AI Jan 30, 2026

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.

Copilot uses AI. Check for mistakes.
func prepareUploadStreams(context *cmd.Context, buf *safe.Buffer) io.Writer {
context.Stdout = &safeWriter{w: context.Stdout}

if v2.ColorStream() {
Copy link

Copilot AI Jan 30, 2026

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.

Suggested change
if v2.ColorStream() {
if v2.ColorStream() {
fmt.Fprint(context.Stdout, " ok\n")

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +44
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
}
Copy link

Copilot AI Jan 30, 2026

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).

Copilot uses AI. Check for mistakes.
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