From 3875e13fadecb828ccbc30e663ae0b6016164868 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Thu, 17 Jul 2025 15:14:58 +0200 Subject: [PATCH] simpler stop UI Signed-off-by: Nicolas De Loof --- cmd/formatter/ansi.go | 7 --- cmd/formatter/stopping.go | 119 -------------------------------------- pkg/compose/up.go | 6 +- 3 files changed, 1 insertion(+), 131 deletions(-) delete mode 100644 cmd/formatter/stopping.go diff --git a/cmd/formatter/ansi.go b/cmd/formatter/ansi.go index 0d59cf501..14429687b 100644 --- a/cmd/formatter/ansi.go +++ b/cmd/formatter/ansi.go @@ -42,13 +42,6 @@ func restoreCursor() { fmt.Print(ansi("8")) } -func hideCursor() { - if disableAnsi { - return - } - fmt.Print(ansi("[?25l")) -} - func showCursor() { if disableAnsi { return diff --git a/cmd/formatter/stopping.go b/cmd/formatter/stopping.go deleted file mode 100644 index afa248673..000000000 --- a/cmd/formatter/stopping.go +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright 2024 Docker Compose CLI authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package formatter - -import ( - "fmt" - "strings" - "time" - - "github.com/buger/goterm" - "github.com/docker/compose/v2/pkg/api" - "github.com/docker/compose/v2/pkg/progress" -) - -type Stopping struct { - api.LogConsumer - enabled bool - spinner *progress.Spinner - ticker *time.Ticker - startedAt time.Time -} - -func NewStopping(l api.LogConsumer) *Stopping { - s := &Stopping{} - s.LogConsumer = logDecorator{ - decorated: l, - Before: s.clear, - After: s.print, - } - return s -} - -func (s *Stopping) ApplicationTermination() { - if progress.Mode != progress.ModeAuto { - // User explicitly opted for output format - return - } - if disableAnsi { - return - } - s.enabled = true - s.spinner = progress.NewSpinner() - hideCursor() - s.startedAt = time.Now() - s.ticker = time.NewTicker(100 * time.Millisecond) - go func() { - for { - <-s.ticker.C - s.print() - } - }() -} - -func (s *Stopping) Close() { - showCursor() - if s.ticker != nil { - s.ticker.Stop() - } - s.clear() -} - -func (s *Stopping) clear() { - if !s.enabled { - return - } - - height := goterm.Height() - carriageReturn() - saveCursor() - - // clearLine() - for i := 0; i < height; i++ { - moveCursorDown(1) - clearLine() - } - restoreCursor() -} - -const stoppingBanner = "Gracefully Stopping... (press Ctrl+C again to force)" - -func (s *Stopping) print() { - if !s.enabled { - return - } - - height := goterm.Height() - width := goterm.Width() - carriageReturn() - saveCursor() - - moveCursor(height, 0) - clearLine() - elapsed := time.Since(s.startedAt).Seconds() - timer := fmt.Sprintf("%.1fs ", elapsed) - pad := width - len(timer) - len(stoppingBanner) - 5 - fmt.Printf("%s %s %s %s", - progress.CountColor(s.spinner.String()), - stoppingBanner, - strings.Repeat(" ", pad), - progress.TimerColor(timer), - ) - - carriageReturn() - restoreCursor() -} diff --git a/pkg/compose/up.go b/pkg/compose/up.go index d3515538e..51ea55c2f 100644 --- a/pkg/compose/up.go +++ b/pkg/compose/up.go @@ -92,10 +92,6 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options } } - tui := formatter.NewStopping(logConsumer) - defer tui.Close() - logConsumer = tui - watcher, err := NewWatcher(project, options, s.watch, logConsumer) if err != nil && options.Start.Watch { return err @@ -112,7 +108,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options first := true gracefulTeardown := func() { first = false - tui.ApplicationTermination() + fmt.Println("Gracefully Stopping... press Ctrl+C again to force") eg.Go(func() error { return progress.RunWithLog(context.WithoutCancel(ctx), func(ctx context.Context) error { return s.stop(ctx, project.Name, api.StopOptions{