From 3bafd9351967e477427bf1d2a9fdd1b521ea3fba Mon Sep 17 00:00:00 2001 From: Joana Hrotko Date: Wed, 13 Mar 2024 11:43:50 +0000 Subject: [PATCH] partial cleanup Signed-off-by: Joana Hrotko --- cmd/formatter/logs.go | 19 ++--- cmd/formatter/shortcut.go | 174 ++++++++++++++++++++++---------------- pkg/compose/up.go | 53 ++---------- 3 files changed, 116 insertions(+), 130 deletions(-) diff --git a/cmd/formatter/logs.go b/cmd/formatter/logs.go index 6fda379c9d7..1d5712201ba 100644 --- a/cmd/formatter/logs.go +++ b/cmd/formatter/logs.go @@ -109,16 +109,7 @@ func (l *logConsumer) write(w io.Writer, container, message string) { if l.ctx.Err() != nil { return } - // p := l.getPresenter(container) - // timestamp := time.Now().Format(jsonmessage.RFC3339NanoFixed) - // for _, line := range strings.Split(message, "\n") { - // if l.timestamp { - // fmt.Fprintf(w, "%s%s%s\n", p.prefix, timestamp, line) - // } else { - // fmt.Fprintf(w, "%s%s\n", p.prefix, line) - // } - // } - KeyboardManager.PrintKeyboardInfo(func() { + print := func() { p := l.getPresenter(container) timestamp := time.Now().Format(jsonmessage.RFC3339NanoFixed) for _, line := range strings.Split(message, "\n") { @@ -128,7 +119,13 @@ func (l *logConsumer) write(w io.Writer, container, message string) { fmt.Fprintf(w, "\033[K%s%s\n", p.prefix, line) } } - }) + } + if KeyboardManager != nil { + KeyboardManager.PrintKeyboardInfo(print) + } else { + // FIXME: Need to handle this case + print() + } } func (l *logConsumer) Status(container, msg string) { diff --git a/cmd/formatter/shortcut.go b/cmd/formatter/shortcut.go index 35a3807d557..795e9fd0ae7 100644 --- a/cmd/formatter/shortcut.go +++ b/cmd/formatter/shortcut.go @@ -7,30 +7,45 @@ import ( "time" "github.com/buger/goterm" + "github.com/compose-spec/compose-go/v2/types" + "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/watch" + "github.com/eiannone/keyboard" + "github.com/skratchdot/open-golang/open" ) var DISPLAY_ERROR_TIME = 10 +type KeyboardError struct { + err error + errStart time.Time +} +type KeyboardWatch struct { + Watcher watch.Notify + Watching bool + WatchFn func(ctx context.Context, project *types.Project, services []string, options api.WatchOptions) error + Ctx context.Context + Cancel context.CancelFunc +} type LogKeyboard struct { - err error - errStart time.Time + ErrorHandle KeyboardError + Watch KeyboardWatch started bool IsDockerDesktopActive bool - Watcher watch.Notify - Watching bool - Ctx context.Context - Cancel context.CancelFunc + IsWatchConfigured bool } -var KeyboardManager = LogKeyboard{Watching: true} +var KeyboardManager *LogKeyboard + var errorColor = "\x1b[1;33m" -func (lk *LogKeyboard) NewContext(ctx context.Context) context.CancelFunc { - ctx, cancel := context.WithCancel(ctx) - lk.Ctx = ctx - lk.Cancel = cancel - return cancel +func NewKeyboardManager(isDockerDesktopActive, IsWatchConfigured bool, watchFn func(ctx context.Context, project *types.Project, services []string, options api.WatchOptions) error) { + km := LogKeyboard{} + KeyboardManager = &km + KeyboardManager.Watch.Watching = true + KeyboardManager.IsDockerDesktopActive = true + KeyboardManager.IsWatchConfigured = true + KeyboardManager.Watch.WatchFn = watchFn } func (lk *LogKeyboard) PrintKeyboardInfo(print func()) { @@ -38,7 +53,7 @@ func (lk *LogKeyboard) PrintKeyboardInfo(print func()) { defer fmt.Printf("\033[?25h") // show cursor if lk.started { - lk.ClearInfo() + lk.clearInfo() } else { lk.started = true } @@ -47,13 +62,24 @@ func (lk *LogKeyboard) PrintKeyboardInfo(print func()) { lk.printInfo() } -func (lk *LogKeyboard) SError(err string) { - lk.errStart = time.Now() - lk.err = fmt.Errorf(err) -} func (lk *LogKeyboard) Error(err error) { - lk.errStart = time.Now() - lk.err = err + lk.ErrorHandle.errStart = time.Now() + lk.ErrorHandle.err = err +} + +func (lk *LogKeyboard) isWatching() bool { + return lk.Watch.Watching +} + +func (lk *LogKeyboard) switchWatching() { + lk.Watch.Watching = !lk.Watch.Watching +} + +func (lk *LogKeyboard) newContext(ctx context.Context) context.CancelFunc { + ctx, cancel := context.WithCancel(ctx) + lk.Watch.Ctx = ctx + lk.Watch.Cancel = cancel + return cancel } // This avoids incorrect printing at the end of the terminal @@ -64,9 +90,9 @@ func (lk *LogKeyboard) createBuffer() { } func (lk *LogKeyboard) printError(height int) { - if lk.err != nil && int(time.Since(lk.errStart).Seconds()) < DISPLAY_ERROR_TIME { + if lk.ErrorHandle.err != nil && int(time.Since(lk.ErrorHandle.errStart).Seconds()) < DISPLAY_ERROR_TIME { fmt.Printf("\033[%d;0H", height-1) // Move to before last line - fmt.Printf("\033[K" + errorColor + "[Error] " + lk.err.Error()) + fmt.Printf("\033[K" + errorColor + "[Error] " + lk.ErrorHandle.err.Error()) } } @@ -85,7 +111,7 @@ func (lk *LogKeyboard) infoMessage() { if lk.IsDockerDesktopActive { options = options + keyColor("^V") + navColor("iew containers in Docker Desktop") } - if lk.Watching { + if lk.IsWatchConfigured { if strings.Contains(options, "Docker Desktop") { options = options + navColor(", ") } @@ -95,10 +121,10 @@ func (lk *LogKeyboard) infoMessage() { fmt.Print("\033[K" + options) } -func (lk *LogKeyboard) ClearInfo() { +func (lk *LogKeyboard) clearInfo() { height := goterm.Height() fmt.Print("\0337") // save cursor position - if lk.err != nil { + if lk.ErrorHandle.err != nil { fmt.Printf("\033[%d;0H", height-1) fmt.Print("\033[2K") // clear line } @@ -108,53 +134,59 @@ func (lk *LogKeyboard) ClearInfo() { } func (lk *LogKeyboard) PrintEnter() { - lk.ClearInfo() + lk.clearInfo() lk.printInfo() } -// func HandleKeyEvents(ctx context.Context, event keyboard.KeyEvent, project types.Project, options api.UpOptions, handleTearDown func()) { -// switch key := event.Key; key { -// case keyboard.KeyCtrlC: -// keyboard.Close() -// KeyboardManager.ClearInfo() -// handleTearDown() -// case keyboard.KeyCtrlG: -// if KeyboardManager.IsDockerDesktopActive { -// link := fmt.Sprintf("docker-desktop://dashboard/apps/%s", project.Name) -// err := open.Run(link) -// if err != nil { -// KeyboardManager.SError("Could not open Docker Desktop") -// } else { -// KeyboardManager.Error(nil) -// } -// } -// case keyboard.KeyCtrlW: -// if KeyboardManager.Watching { -// KeyboardManager.Watching = !KeyboardManager.Watching -// fmt.Println("watching shortcut", KeyboardManager.Watching) - -// if KeyboardManager.Watching { -// KeyboardManager.Cancel() -// } else { -// KeyboardManager.NewContext(ctx) -// quit := make(chan error) -// go func() { -// buildOpts := *options.Create.Build -// buildOpts.Quiet = true -// err := s.Watch(KeyboardManager.Ctx, project, options.Start.Services, api.WatchOptions{ -// Build: &buildOpts, -// LogTo: options.Start.Attach, -// }) -// quit <- err -// }() -// KeyboardManager.Error(<-quit) -// } -// } -// case keyboard.KeyEnter: -// KeyboardManager.PrintEnter() -// default: -// if key != 0 { // If some key is pressed -// fmt.Println("key pressed: ", key) -// } -// } -// } +func (lk *LogKeyboard) openDockerDesktop(project *types.Project) { + if lk.IsDockerDesktopActive { + link := fmt.Sprintf("docker-desktop://dashboard/apps/%s", project.Name) + err := open.Run(link) + if err != nil { + lk.Error(fmt.Errorf("Could not open Docker Desktop")) + } else { + lk.Error(nil) + } + } +} +func (lk *LogKeyboard) StartWatch(ctx context.Context, project *types.Project, options api.UpOptions) { + lk.switchWatching() + if lk.isWatching() { + fmt.Println("watching shortcut") + lk.Watch.Cancel() + } else { + lk.newContext(ctx) + errW := make(chan error) + go func() { + buildOpts := *options.Create.Build + buildOpts.Quiet = true + err := lk.Watch.WatchFn(lk.Watch.Ctx, project, options.Start.Services, api.WatchOptions{ + Build: &buildOpts, + LogTo: options.Start.Attach, + }) + errW <- err + }() + lk.Error(<-errW) + } +} + +func (lk *LogKeyboard) HandleKeyEvents(ctx context.Context, event keyboard.KeyEvent, project *types.Project, options api.UpOptions, handleTearDown func()) { + switch kRune := event.Rune; kRune { + case 'V': + lk.openDockerDesktop(project) + case 'W': + lk.StartWatch(ctx, project, options) + } + switch key := event.Key; key { + case keyboard.KeyCtrlC: + keyboard.Close() + lk.clearInfo() + handleTearDown() + case keyboard.KeyEnter: + lk.PrintEnter() + default: + if key != 0 { // If some key is pressed + fmt.Println("key pressed: ", key) + } + } +} diff --git a/pkg/compose/up.go b/pkg/compose/up.go index 9ef2e103e18..3a71d5001a4 100644 --- a/pkg/compose/up.go +++ b/pkg/compose/up.go @@ -31,7 +31,6 @@ import ( "github.com/docker/compose/v2/pkg/progress" "github.com/eiannone/keyboard" "github.com/hashicorp/go-multierror" - "github.com/skratchdot/open-golang/open" ) func (s *composeService) Up(ctx context.Context, project *types.Project, options api.UpOptions) error { //nolint:gocyclo @@ -78,10 +77,11 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options if err != nil { panic(err) } - // formatter.KeyboardInfo.IsDockerDesktopActive = s.isDesktopIntegrationActive() - formatter.KeyboardManager.IsDockerDesktopActive = true - // formatter.KeyboardInfo.Watching = s.shouldWatch(project) + formatter.NewKeyboardManager(true, true, s.Watch) // change after test + // kManager.IsDockerDesktopActive = s.isDesktopIntegrationActive() + // kManager.IsWatchConfigured = s.shouldWatch(project) defer keyboard.Close() + first := true gracefulTeardown := func() { printer.Cancel() @@ -100,50 +100,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options for { select { case event := <-kEvents: - switch key := event.Key; key { - case keyboard.KeyCtrlC: - keyboard.Close() - formatter.KeyboardManager.ClearInfo() - gracefulTeardown() - case keyboard.KeyCtrlG: - if formatter.KeyboardManager.IsDockerDesktopActive { - link := fmt.Sprintf("docker-desktop://dashboard/apps/%s", project.Name) - err := open.Run(link) - if err != nil { - formatter.KeyboardManager.SError("Could not open Docker Desktop") - } else { - formatter.KeyboardManager.Error(nil) - } - } - case keyboard.KeyCtrlW: - if formatter.KeyboardManager.Watching { - formatter.KeyboardManager.Watching = !formatter.KeyboardManager.Watching - fmt.Println("watching shortcut", formatter.KeyboardManager.Watching) - - if formatter.KeyboardManager.Watching { - formatter.KeyboardManager.Cancel() - } else { - formatter.KeyboardManager.NewContext(ctx) - errW := make(chan error) - go func() { - buildOpts := *options.Create.Build - buildOpts.Quiet = true - err := s.Watch(formatter.KeyboardManager.Ctx, project, options.Start.Services, api.WatchOptions{ - Build: &buildOpts, - LogTo: options.Start.Attach, - }) - errW <- err - }() - formatter.KeyboardManager.Error(<-errW) - } - } - case keyboard.KeyEnter: - formatter.KeyboardManager.PrintEnter() - default: - if key != 0 { // If some key is pressed - fmt.Println("key pressed: ", key) - } - } + formatter.KeyboardManager.HandleKeyEvents(ctx, event, project, options, gracefulTeardown) case <-doneCh: return nil case <-ctx.Done():