mirror of
https://github.com/docker/compose.git
synced 2025-07-26 23:24:05 +02:00
(reactoring) avoid a global variable by introducing logConsumer decorator
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
2c69fc3d4d
commit
6fa173124a
@ -118,10 +118,6 @@ func (l *logConsumer) write(w io.Writer, container, message string) {
|
||||
if l.ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
if KeyboardManager != nil {
|
||||
KeyboardManager.ClearKeyboardInfo()
|
||||
}
|
||||
|
||||
p := l.getPresenter(container)
|
||||
timestamp := time.Now().Format(jsonmessage.RFC3339NanoFixed)
|
||||
for _, line := range strings.Split(message, "\n") {
|
||||
@ -131,10 +127,6 @@ func (l *logConsumer) write(w io.Writer, container, message string) {
|
||||
_, _ = fmt.Fprintf(w, "%s%s\n", p.prefix, line)
|
||||
}
|
||||
}
|
||||
|
||||
if KeyboardManager != nil {
|
||||
KeyboardManager.PrintKeyboardInfo()
|
||||
}
|
||||
}
|
||||
|
||||
func (l *logConsumer) Status(container, msg string) {
|
||||
@ -168,3 +160,31 @@ func (p *presenter) setPrefix(width int) {
|
||||
}
|
||||
p.prefix = p.colors(fmt.Sprintf("%-"+strconv.Itoa(width)+"s | ", p.name))
|
||||
}
|
||||
|
||||
type logDecorator struct {
|
||||
decorated api.LogConsumer
|
||||
Before func()
|
||||
After func()
|
||||
}
|
||||
|
||||
func (l logDecorator) Log(containerName, message string) {
|
||||
l.Before()
|
||||
l.decorated.Log(containerName, message)
|
||||
l.After()
|
||||
}
|
||||
|
||||
func (l logDecorator) Err(containerName, message string) {
|
||||
l.Before()
|
||||
l.decorated.Err(containerName, message)
|
||||
l.After()
|
||||
}
|
||||
|
||||
func (l logDecorator) Status(container, msg string) {
|
||||
l.Before()
|
||||
l.decorated.Status(container, msg)
|
||||
l.After()
|
||||
}
|
||||
|
||||
func (l logDecorator) Register(container string) {
|
||||
l.decorated.Register(container)
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"reflect"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@ -70,12 +69,12 @@ func (ke *KeyboardError) error() string {
|
||||
}
|
||||
|
||||
type KeyboardWatch struct {
|
||||
Watching bool
|
||||
Watcher Toggle
|
||||
IsConfigured bool
|
||||
Watching bool
|
||||
Watcher Feature
|
||||
}
|
||||
|
||||
type Toggle interface {
|
||||
// Feature is an compose feature that can be started/stopped by a menu command
|
||||
type Feature interface {
|
||||
Start(context.Context) error
|
||||
Stop() error
|
||||
}
|
||||
@ -90,31 +89,26 @@ const (
|
||||
|
||||
type LogKeyboard struct {
|
||||
kError KeyboardError
|
||||
Watch KeyboardWatch
|
||||
Watch *KeyboardWatch
|
||||
IsDockerDesktopActive bool
|
||||
logLevel KEYBOARD_LOG_LEVEL
|
||||
signalChannel chan<- os.Signal
|
||||
}
|
||||
|
||||
// FIXME(ndeloof) we should avoid use of such a global reference. see use in logConsumer
|
||||
var KeyboardManager *LogKeyboard
|
||||
|
||||
func NewKeyboardManager(isDockerDesktopActive bool, sc chan<- os.Signal, w bool, watcher Toggle) *LogKeyboard {
|
||||
KeyboardManager = &LogKeyboard{
|
||||
Watch: KeyboardWatch{
|
||||
Watching: w,
|
||||
Watcher: watcher,
|
||||
IsConfigured: !reflect.ValueOf(watcher).IsNil(),
|
||||
},
|
||||
func NewKeyboardManager(isDockerDesktopActive bool, sc chan<- os.Signal) *LogKeyboard {
|
||||
return &LogKeyboard{
|
||||
IsDockerDesktopActive: isDockerDesktopActive,
|
||||
logLevel: INFO,
|
||||
signalChannel: sc,
|
||||
}
|
||||
return KeyboardManager
|
||||
}
|
||||
|
||||
func (lk *LogKeyboard) ClearKeyboardInfo() {
|
||||
lk.clearNavigationMenu()
|
||||
func (lk *LogKeyboard) Decorate(l api.LogConsumer) api.LogConsumer {
|
||||
return logDecorator{
|
||||
decorated: l,
|
||||
Before: lk.clearNavigationMenu,
|
||||
After: lk.PrintKeyboardInfo,
|
||||
}
|
||||
}
|
||||
|
||||
func (lk *LogKeyboard) PrintKeyboardInfo() {
|
||||
@ -185,7 +179,7 @@ func (lk *LogKeyboard) navigationMenu() string {
|
||||
watchInfo = navColor(" ")
|
||||
}
|
||||
isEnabled := " Enable"
|
||||
if lk.Watch.Watching {
|
||||
if lk.Watch != nil && lk.Watch.Watching {
|
||||
isEnabled = " Disable"
|
||||
}
|
||||
watchInfo = watchInfo + shortcutKeyColor("w") + navColor(isEnabled+" Watch")
|
||||
@ -268,7 +262,7 @@ func (lk *LogKeyboard) keyboardError(prefix string, err error) {
|
||||
}
|
||||
|
||||
func (lk *LogKeyboard) ToggleWatch(ctx context.Context, options api.UpOptions) {
|
||||
if !lk.Watch.IsConfigured {
|
||||
if lk.Watch == nil {
|
||||
return
|
||||
}
|
||||
if lk.Watch.Watching {
|
||||
@ -299,7 +293,7 @@ func (lk *LogKeyboard) HandleKeyEvents(ctx context.Context, event keyboard.KeyEv
|
||||
case 'v':
|
||||
lk.openDockerDesktop(ctx, project)
|
||||
case 'w':
|
||||
if !lk.Watch.IsConfigured {
|
||||
if lk.Watch == nil {
|
||||
// we try to open watch docs if DD is installed
|
||||
if lk.IsDockerDesktopActive {
|
||||
lk.openDDWatchDocs(ctx, project)
|
||||
@ -333,6 +327,13 @@ func (lk *LogKeyboard) HandleKeyEvents(ctx context.Context, event keyboard.KeyEv
|
||||
}
|
||||
}
|
||||
|
||||
func (lk *LogKeyboard) EnableWatch(enabled bool, watcher Feature) {
|
||||
lk.Watch = &KeyboardWatch{
|
||||
Watching: enabled,
|
||||
Watcher: watcher,
|
||||
}
|
||||
}
|
||||
|
||||
func allocateSpace(lines int) {
|
||||
for i := 0; i < lines; i++ {
|
||||
ClearLine()
|
||||
|
@ -22,15 +22,12 @@ import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
func KeyboardMetrics(ctx context.Context, enabled, isDockerDesktopActive, isWatchConfigured bool) {
|
||||
func KeyboardMetrics(ctx context.Context, enabled, isDockerDesktopActive bool) {
|
||||
commandAvailable := []string{}
|
||||
if isDockerDesktopActive {
|
||||
commandAvailable = append(commandAvailable, "gui")
|
||||
commandAvailable = append(commandAvailable, "gui/composeview")
|
||||
}
|
||||
if isWatchConfigured {
|
||||
commandAvailable = append(commandAvailable, "watch")
|
||||
}
|
||||
|
||||
AddAttributeToSpan(ctx,
|
||||
attribute.Bool("navmenu.enabled", enabled),
|
||||
|
@ -70,15 +70,12 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
|
||||
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
defer signal.Stop(signalChan)
|
||||
var isTerminated atomic.Bool
|
||||
printer := newLogPrinter(options.Start.Attach)
|
||||
|
||||
watcher, err := NewWatcher(project, options, s.watch)
|
||||
if err != nil && options.Start.Watch {
|
||||
return err
|
||||
}
|
||||
|
||||
var navigationMenu *formatter.LogKeyboard
|
||||
var kEvents <-chan keyboard.KeyEvent
|
||||
var (
|
||||
logConsumer = options.Start.Attach
|
||||
navigationMenu *formatter.LogKeyboard
|
||||
kEvents <-chan keyboard.KeyEvent
|
||||
)
|
||||
if options.Start.NavigationMenu {
|
||||
kEvents, err = keyboard.GetKeys(100)
|
||||
if err != nil {
|
||||
@ -87,11 +84,23 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
|
||||
} else {
|
||||
defer keyboard.Close() //nolint:errcheck
|
||||
isDockerDesktopActive := s.isDesktopIntegrationActive()
|
||||
tracing.KeyboardMetrics(ctx, options.Start.NavigationMenu, isDockerDesktopActive, watcher != nil)
|
||||
navigationMenu = formatter.NewKeyboardManager(isDockerDesktopActive, signalChan, options.Start.Watch, watcher)
|
||||
tracing.KeyboardMetrics(ctx, options.Start.NavigationMenu, isDockerDesktopActive)
|
||||
navigationMenu = formatter.NewKeyboardManager(isDockerDesktopActive, signalChan)
|
||||
logConsumer = navigationMenu.Decorate(logConsumer)
|
||||
}
|
||||
}
|
||||
|
||||
watcher, err := NewWatcher(project, options, s.watch, logConsumer)
|
||||
if err != nil && options.Start.Watch {
|
||||
return err
|
||||
}
|
||||
|
||||
if navigationMenu != nil && watcher != nil {
|
||||
navigationMenu.EnableWatch(options.Start.Watch, watcher)
|
||||
}
|
||||
|
||||
printer := newLogPrinter(logConsumer)
|
||||
|
||||
doneCh := make(chan bool)
|
||||
eg.Go(func() error {
|
||||
first := true
|
||||
|
@ -55,7 +55,7 @@ type Watcher struct {
|
||||
errCh chan error
|
||||
}
|
||||
|
||||
func NewWatcher(project *types.Project, options api.UpOptions, w WatchFunc) (*Watcher, error) {
|
||||
func NewWatcher(project *types.Project, options api.UpOptions, w WatchFunc, consumer api.LogConsumer) (*Watcher, error) {
|
||||
for i := range project.Services {
|
||||
service := project.Services[i]
|
||||
|
||||
@ -65,7 +65,7 @@ func NewWatcher(project *types.Project, options api.UpOptions, w WatchFunc) (*Wa
|
||||
return &Watcher{
|
||||
project: project,
|
||||
options: api.WatchOptions{
|
||||
LogTo: options.Start.Attach,
|
||||
LogTo: consumer,
|
||||
Build: build,
|
||||
},
|
||||
watchFn: w,
|
||||
|
Loading…
x
Reference in New Issue
Block a user