Skip to content

Commit

Permalink
partial cleanup
Browse files Browse the repository at this point in the history
Signed-off-by: Joana Hrotko <joana.hrotko@docker.com>
  • Loading branch information
jhrotko committed Mar 13, 2024
1 parent d71a2de commit 3bafd93
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 130 deletions.
19 changes: 8 additions & 11 deletions cmd/formatter/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand All @@ -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) {
Expand Down
174 changes: 103 additions & 71 deletions cmd/formatter/shortcut.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,53 @@ 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()) {
fmt.Print("\033[?25l") // hide cursor
defer fmt.Printf("\033[?25h") // show cursor

if lk.started {
lk.ClearInfo()
lk.clearInfo()
} else {
lk.started = true
}
Expand All @@ -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
Expand All @@ -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())
}
}

Expand All @@ -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(", ")
}
Expand All @@ -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
}
Expand All @@ -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)
}
}
}
53 changes: 5 additions & 48 deletions pkg/compose/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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():
Expand Down

0 comments on commit 3bafd93

Please sign in to comment.