@@ -29,9 +29,7 @@ import (
29
29
"github.com/compose-spec/compose-go/v2/types"
30
30
"github.com/docker/compose/v2/internal/tracing"
31
31
"github.com/docker/compose/v2/pkg/api"
32
- "github.com/docker/compose/v2/pkg/watch"
33
32
"github.com/eiannone/keyboard"
34
- "github.com/hashicorp/go-multierror"
35
33
"github.com/skratchdot/open-golang/open"
36
34
)
37
35
@@ -71,26 +69,13 @@ func (ke *KeyboardError) error() string {
71
69
}
72
70
73
71
type KeyboardWatch struct {
74
- Watcher watch.Notify
75
72
Watching bool
76
- WatchFn func (ctx context.Context , doneCh chan bool , project * types.Project , services []string , options api.WatchOptions ) error
77
- Ctx context.Context
78
- Cancel context.CancelFunc
73
+ Watcher Toggle
79
74
}
80
75
81
- func (kw * KeyboardWatch ) isWatching () bool {
82
- return kw .Watching
83
- }
84
-
85
- func (kw * KeyboardWatch ) switchWatching () {
86
- kw .Watching = ! kw .Watching
87
- }
88
-
89
- func (kw * KeyboardWatch ) newContext (ctx context.Context ) context.CancelFunc {
90
- ctx , cancel := context .WithCancel (ctx )
91
- kw .Ctx = ctx
92
- kw .Cancel = cancel
93
- return cancel
76
+ type Toggle interface {
77
+ Start (context.Context ) error
78
+ Stop () error
94
79
}
95
80
96
81
type KEYBOARD_LOG_LEVEL int
@@ -110,31 +95,21 @@ type LogKeyboard struct {
110
95
signalChannel chan <- os.Signal
111
96
}
112
97
113
- var (
114
- KeyboardManager * LogKeyboard
115
- eg multierror.Group
116
- )
117
-
118
- func NewKeyboardManager (ctx context.Context , isDockerDesktopActive , isWatchConfigured bool ,
119
- sc chan <- os.Signal ,
120
- watchFn func (ctx context.Context ,
121
- doneCh chan bool ,
122
- project * types.Project ,
123
- services []string ,
124
- options api.WatchOptions ,
125
- ) error ,
126
- ) {
127
- km := LogKeyboard {}
128
- km .IsDockerDesktopActive = isDockerDesktopActive
129
- km .IsWatchConfigured = isWatchConfigured
130
- km .logLevel = INFO
131
-
132
- km .Watch .Watching = false
133
- km .Watch .WatchFn = watchFn
134
-
135
- km .signalChannel = sc
136
-
137
- KeyboardManager = & km
98
+ // FIXME(ndeloof) we should avoid use of such a global reference. see use in logConsumer
99
+ var KeyboardManager * LogKeyboard
100
+
101
+ func NewKeyboardManager (isDockerDesktopActive bool , sc chan <- os.Signal , w bool , watcher Toggle ) * LogKeyboard {
102
+ KeyboardManager = & LogKeyboard {
103
+ Watch : KeyboardWatch {
104
+ Watching : w ,
105
+ Watcher : watcher ,
106
+ },
107
+ IsDockerDesktopActive : isDockerDesktopActive ,
108
+ IsWatchConfigured : true ,
109
+ logLevel : INFO ,
110
+ signalChannel : sc ,
111
+ }
112
+ return KeyboardManager
138
113
}
139
114
140
115
func (lk * LogKeyboard ) ClearKeyboardInfo () {
@@ -233,48 +208,51 @@ func (lk *LogKeyboard) openDockerDesktop(ctx context.Context, project *types.Pro
233
208
if ! lk .IsDockerDesktopActive {
234
209
return
235
210
}
236
- eg .Go (tracing .EventWrapFuncForErrGroup (ctx , "menu/gui" , tracing.SpanOptions {},
237
- func (ctx context.Context ) error {
238
- link := fmt .Sprintf ("docker-desktop://dashboard/apps/%s" , project .Name )
239
- err := open .Run (link )
240
- if err != nil {
241
- err = fmt .Errorf ("could not open Docker Desktop" )
242
- lk .keyboardError ("View" , err )
243
- }
244
- return err
245
- }),
246
- )
211
+ go func () {
212
+ _ = tracing .EventWrapFuncForErrGroup (ctx , "menu/gui" , tracing.SpanOptions {},
213
+ func (ctx context.Context ) error {
214
+ link := fmt .Sprintf ("docker-desktop://dashboard/apps/%s" , project .Name )
215
+ err := open .Run (link )
216
+ if err != nil {
217
+ err = fmt .Errorf ("could not open Docker Desktop" )
218
+ lk .keyboardError ("View" , err )
219
+ }
220
+ return err
221
+ })()
222
+ }()
247
223
}
248
224
249
225
func (lk * LogKeyboard ) openDDComposeUI (ctx context.Context , project * types.Project ) {
250
226
if ! lk .IsDockerDesktopActive {
251
227
return
252
228
}
253
- eg .Go (tracing .EventWrapFuncForErrGroup (ctx , "menu/gui/composeview" , tracing.SpanOptions {},
254
- func (ctx context.Context ) error {
255
- link := fmt .Sprintf ("docker-desktop://dashboard/docker-compose/%s" , project .Name )
256
- err := open .Run (link )
257
- if err != nil {
258
- err = fmt .Errorf ("could not open Docker Desktop Compose UI" )
259
- lk .keyboardError ("View Config" , err )
260
- }
261
- return err
262
- }),
263
- )
229
+ go func () {
230
+ _ = tracing .EventWrapFuncForErrGroup (ctx , "menu/gui/composeview" , tracing.SpanOptions {},
231
+ func (ctx context.Context ) error {
232
+ link := fmt .Sprintf ("docker-desktop://dashboard/docker-compose/%s" , project .Name )
233
+ err := open .Run (link )
234
+ if err != nil {
235
+ err = fmt .Errorf ("could not open Docker Desktop Compose UI" )
236
+ lk .keyboardError ("View Config" , err )
237
+ }
238
+ return err
239
+ })()
240
+ }()
264
241
}
265
242
266
243
func (lk * LogKeyboard ) openDDWatchDocs (ctx context.Context , project * types.Project ) {
267
- eg .Go (tracing .EventWrapFuncForErrGroup (ctx , "menu/gui/watch" , tracing.SpanOptions {},
268
- func (ctx context.Context ) error {
269
- link := fmt .Sprintf ("docker-desktop://dashboard/docker-compose/%s/watch" , project .Name )
270
- err := open .Run (link )
271
- if err != nil {
272
- err = fmt .Errorf ("could not open Docker Desktop Compose UI" )
273
- lk .keyboardError ("Watch Docs" , err )
274
- }
275
- return err
276
- }),
277
- )
244
+ go func () {
245
+ _ = tracing .EventWrapFuncForErrGroup (ctx , "menu/gui/watch" , tracing.SpanOptions {},
246
+ func (ctx context.Context ) error {
247
+ link := fmt .Sprintf ("docker-desktop://dashboard/docker-compose/%s/watch" , project .Name )
248
+ err := open .Run (link )
249
+ if err != nil {
250
+ err = fmt .Errorf ("could not open Docker Desktop Compose UI" )
251
+ lk .keyboardError ("Watch Docs" , err )
252
+ }
253
+ return err
254
+ })()
255
+ }()
278
256
}
279
257
280
258
func (lk * LogKeyboard ) keyboardError (prefix string , err error ) {
@@ -288,39 +266,34 @@ func (lk *LogKeyboard) keyboardError(prefix string, err error) {
288
266
}()
289
267
}
290
268
291
- func (lk * LogKeyboard ) StartWatch (ctx context.Context , doneCh chan bool , project * types. Project , options api.UpOptions ) {
269
+ func (lk * LogKeyboard ) ToggleWatch (ctx context.Context , options api.UpOptions ) {
292
270
if ! lk .IsWatchConfigured {
293
271
return
294
272
}
295
- lk .Watch .switchWatching ()
296
- if ! lk .Watch .isWatching () {
297
- lk .Watch .Cancel ()
273
+ if lk .Watch .Watching {
274
+ err := lk .Watch .Watcher .Stop ()
275
+ if err != nil {
276
+ options .Start .Attach .Err (api .WatchLogger , err .Error ())
277
+ } else {
278
+ lk .Watch .Watching = false
279
+ }
298
280
} else {
299
- eg .Go (tracing .EventWrapFuncForErrGroup (ctx , "menu/watch" , tracing.SpanOptions {},
300
- func (ctx context.Context ) error {
301
- if options .Create .Build == nil {
302
- err := fmt .Errorf ("cannot run watch mode with flag --no-build" )
303
- lk .keyboardError ("Watch" , err )
281
+ go func () {
282
+ _ = tracing .EventWrapFuncForErrGroup (ctx , "menu/watch" , tracing.SpanOptions {},
283
+ func (ctx context.Context ) error {
284
+ err := lk .Watch .Watcher .Start (ctx )
285
+ if err != nil {
286
+ options .Start .Attach .Err (api .WatchLogger , err .Error ())
287
+ } else {
288
+ lk .Watch .Watching = true
289
+ }
304
290
return err
305
- }
306
-
307
- lk .Watch .newContext (ctx )
308
- buildOpts := * options .Create .Build
309
- buildOpts .Quiet = true
310
- err := lk .Watch .WatchFn (lk .Watch .Ctx , doneCh , project , options .Start .Services , api.WatchOptions {
311
- Build : & buildOpts ,
312
- LogTo : options .Start .Attach ,
313
- })
314
- if err != nil {
315
- lk .Watch .switchWatching ()
316
- options .Start .Attach .Err (api .WatchLogger , err .Error ())
317
- }
318
- return err
319
- }))
291
+ })()
292
+ }()
320
293
}
321
294
}
322
295
323
- func (lk * LogKeyboard ) HandleKeyEvents (event keyboard. KeyEvent , ctx context.Context , doneCh chan bool , project * types.Project , options api.UpOptions ) {
296
+ func (lk * LogKeyboard ) HandleKeyEvents (ctx context.Context , event keyboard. KeyEvent , project * types.Project , options api.UpOptions ) {
324
297
switch kRune := event .Rune ; kRune {
325
298
case 'v' :
326
299
lk .openDockerDesktop (ctx , project )
@@ -331,15 +304,16 @@ func (lk *LogKeyboard) HandleKeyEvents(event keyboard.KeyEvent, ctx context.Cont
331
304
lk .openDDWatchDocs (ctx , project )
332
305
}
333
306
// either way we mark menu/watch as an error
334
- eg .Go (tracing .EventWrapFuncForErrGroup (ctx , "menu/watch" , tracing.SpanOptions {},
335
- func (ctx context.Context ) error {
336
- err := fmt .Errorf ("watch is not yet configured. Learn more: %s" , ansiColor (CYAN , "https://docs.docker.com/compose/file-watch/" ))
337
- lk .keyboardError ("Watch" , err )
338
- return err
339
- }))
340
- return
307
+ go func () {
308
+ _ = tracing .EventWrapFuncForErrGroup (ctx , "menu/watch" , tracing.SpanOptions {},
309
+ func (ctx context.Context ) error {
310
+ err := fmt .Errorf ("watch is not yet configured. Learn more: %s" , ansiColor (CYAN , "https://docs.docker.com/compose/file-watch/" ))
311
+ lk .keyboardError ("Watch" , err )
312
+ return err
313
+ })()
314
+ }()
341
315
}
342
- lk .StartWatch (ctx , doneCh , project , options )
316
+ lk .ToggleWatch (ctx , options )
343
317
case 'o' :
344
318
lk .openDDComposeUI (ctx , project )
345
319
}
@@ -350,10 +324,6 @@ func (lk *LogKeyboard) HandleKeyEvents(event keyboard.KeyEvent, ctx context.Cont
350
324
ShowCursor ()
351
325
352
326
lk .logLevel = NONE
353
- if lk .Watch .Watching && lk .Watch .Cancel != nil {
354
- lk .Watch .Cancel ()
355
- _ = eg .Wait ().ErrorOrNil () // Need to print this ?
356
- }
357
327
// will notify main thread to kill and will handle gracefully
358
328
lk .signalChannel <- syscall .SIGINT
359
329
case keyboard .KeyEnter :
0 commit comments