Skip to content

fix: provider output handling and watch rebuild re-invocation#13732

Merged
glours merged 1 commit intomainfrom
fix/provider-output-handling
Apr 14, 2026
Merged

fix: provider output handling and watch rebuild re-invocation#13732
glours merged 1 commit intomainfrom
fix/provider-output-handling

Conversation

@glours
Copy link
Copy Markdown
Contributor

@glours glours commented Apr 14, 2026

What I did
Provider info and error messages containing newlines broke the TTY progress display (timer drifting to a new line, broken cursor movement). Extract only the first line for progress events via firstLine(). Full messages remain available through the provider's own debug message type.

Skip provider services during watch rebuild convergence by adding a SkipProviders flag to CreateOptions, set only by the watch rebuild path. This prevents unnecessary re-invocation of providers on every file change while preserving normal provider execution for all other commands (up, create, run, scale).

Related issue
N/A

(not mandatory) A picture of a cute animal, if possible in relation to what you did
image

Provider info and error messages containing newlines broke the TTY
progress display (timer drifting to a new line, broken cursor
movement). Extract only the first line for progress events via
firstLine(). Full messages remain available through the provider's
own debug message type.

Skip provider services during watch rebuild convergence by adding a
SkipProviders flag to CreateOptions, set only by the watch rebuild
path. This prevents unnecessary re-invocation of providers on every
file change while preserving normal provider execution for all other
commands (up, create, run, scale).

Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
@glours glours requested a review from a team as a code owner April 14, 2026 09:31
@glours glours requested review from Copilot and ndeloof April 14, 2026 09:31
Copy link
Copy Markdown
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

This PR improves watch-mode stability and reduces unnecessary work by (1) sanitizing provider progress messages that contain newlines (which break TTY progress rendering) and (2) avoiding repeated provider re-invocation during watch-triggered rebuild convergence.

Changes:

  • Truncate provider info/error progress events to the first line via firstLine() to keep TTY progress rendering stable.
  • Add SkipProviders to api.CreateOptions and use it from the watch rebuild path to prevent provider services from re-running on each file change.
  • Implement provider skipping in convergence when SkipProviders is enabled.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
pkg/compose/watch.go Sets SkipProviders: true when recreating services during watch rebuilds.
pkg/compose/plugins.go Uses firstLine() for provider progress events and adds the firstLine helper.
pkg/compose/convergence.go Skips provider services during convergence when options.SkipProviders is set.
pkg/api/api.go Extends CreateOptions with a SkipProviders flag.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/compose/plugins.go
Comment on lines +287 to +289
s = strings.TrimRight(s, "\n")
if i := strings.IndexByte(s, '\n'); i >= 0 {
return s[:i]
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

firstLine only trims \n, so CRLF messages ("\r\n") will leave a trailing \r in the returned first line. That can still interfere with TTY cursor control and makes the doc comment (“stripping any trailing newlines”) inaccurate on Windows. Consider trimming "\r\n" and/or explicitly stripping a trailing \r from the first line segment.

Suggested change
s = strings.TrimRight(s, "\n")
if i := strings.IndexByte(s, '\n'); i >= 0 {
return s[:i]
s = strings.TrimRight(s, "\r\n")
if i := strings.IndexByte(s, '\n'); i >= 0 {
return strings.TrimRight(s[:i], "\r")

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +107
// Skip provider services when the caller opted out (e.g. watch rebuild),
// since providers were already set up during initial "up".
if service.Provider != nil && options.SkipProviders {
return nil
}
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New SkipProviders behavior is introduced here, but there doesn’t appear to be any test exercising convergence when provider services are present and SkipProviders is true. Given how central convergence is, adding a unit test that asserts provider services are not invoked (and dependent services still converge) would help prevent regressions.

Copilot uses AI. Check for mistakes.
@glours glours merged commit 9eb8966 into main Apr 14, 2026
49 checks passed
@glours glours deleted the fix/provider-output-handling branch April 14, 2026 09:43
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.

3 participants