@@ -36,6 +36,7 @@ import (
36
36
"github.com/compose-spec/compose-go/types"
37
37
"github.com/sirupsen/logrus"
38
38
"github.com/spf13/cobra"
39
+ "golang.org/x/sync/errgroup"
39
40
)
40
41
41
42
// composeOptions hold options common to `up` and `run` to run compose project
@@ -57,6 +58,8 @@ type upOptions struct {
57
58
cascadeStop bool
58
59
exitCodeFrom string
59
60
scale []string
61
+ noColor bool
62
+ noPrefix bool
60
63
}
61
64
62
65
func (o upOptions ) recreateStrategy () string {
@@ -102,6 +105,8 @@ func upCommand(p *projectOptions, contextType string) *cobra.Command {
102
105
flags .BoolVar (& opts .Build , "build" , false , "Build images before starting containers." )
103
106
flags .BoolVar (& opts .removeOrphans , "remove-orphans" , false , "Remove containers for services not defined in the Compose file." )
104
107
flags .StringArrayVar (& opts .scale , "scale" , []string {}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present." )
108
+ flags .BoolVar (& opts .noColor , "no-color" , false , "Produce monochrome output." )
109
+ flags .BoolVar (& opts .noPrefix , "no-log-prefix" , false , "Don't print prefix in logs." )
105
110
106
111
switch contextType {
107
112
case store .AciContextType :
@@ -199,6 +204,16 @@ func runCreateStart(ctx context.Context, opts upOptions, services []string) erro
199
204
stopFunc () // nolint:errcheck
200
205
}()
201
206
207
+ consumer := formatter .NewLogConsumer (ctx , os .Stdout , ! opts .noColor , ! opts .noPrefix )
208
+
209
+ var exitCode int
210
+ eg , ctx := errgroup .WithContext (ctx )
211
+ eg .Go (func () error {
212
+ code , err := printer .run (ctx , opts .cascadeStop , opts .exitCodeFrom , consumer , stopFunc )
213
+ exitCode = code
214
+ return err
215
+ })
216
+
202
217
err = c .ComposeService ().Start (ctx , project , compose.StartOptions {
203
218
Attach : func (event compose.ContainerEvent ) {
204
219
queue <- event
@@ -208,7 +223,7 @@ func runCreateStart(ctx context.Context, opts upOptions, services []string) erro
208
223
return err
209
224
}
210
225
211
- exitCode , err := printer . run ( ctx , opts . cascadeStop , opts . exitCodeFrom , stopFunc )
226
+ err = eg . Wait ( )
212
227
if exitCode != 0 {
213
228
return cmd.ExitCodeError {ExitCode : exitCode }
214
229
}
@@ -298,27 +313,37 @@ type printer struct {
298
313
queue chan compose.ContainerEvent
299
314
}
300
315
301
- func (p printer ) run (ctx context.Context , cascadeStop bool , exitCodeFrom string , stopFn func () error ) (int , error ) { //nolint:unparam
302
- consumer := formatter .NewLogConsumer (ctx , os .Stdout )
316
+ func (p printer ) run (ctx context.Context , cascadeStop bool , exitCodeFrom string , consumer compose.LogConsumer , stopFn func () error ) (int , error ) { //nolint:unparam
303
317
var aborting bool
318
+ var count int
304
319
for {
305
320
event := <- p .queue
306
321
switch event .Type {
322
+ case compose .ContainerEventAttach :
323
+ consumer .Register (event .Service , event .Source )
324
+ count ++
307
325
case compose .ContainerEventExit :
308
326
if ! aborting {
309
327
consumer .Status (event .Service , event .Source , fmt .Sprintf ("exited with code %d" , event .ExitCode ))
310
328
}
311
- if cascadeStop && ! aborting {
312
- aborting = true
313
- fmt .Println ("Aborting on container exit..." )
314
- err := stopFn ()
315
- if err != nil {
316
- return 0 , err
329
+ if cascadeStop {
330
+ if ! aborting {
331
+ aborting = true
332
+ fmt .Println ("Aborting on container exit..." )
333
+ err := stopFn ()
334
+ if err != nil {
335
+ return 0 , err
336
+ }
337
+ }
338
+ if exitCodeFrom == "" || exitCodeFrom == event .Service {
339
+ logrus .Error (event .ExitCode )
340
+ return event .ExitCode , nil
317
341
}
318
342
}
319
- if exitCodeFrom == "" || exitCodeFrom == event .Service {
320
- logrus .Error (event .ExitCode )
321
- return event .ExitCode , nil
343
+ count --
344
+ if count == 0 {
345
+ // Last container terminated, done
346
+ return 0 , nil
322
347
}
323
348
case compose .ContainerEventLog :
324
349
if ! aborting {
0 commit comments