diff --git a/pkg/compose/build.go b/pkg/compose/build.go index 7028bace96..c8f5995d61 100644 --- a/pkg/compose/build.go +++ b/pkg/compose/build.go @@ -51,7 +51,7 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti return progress.RunWithTitle(ctx, func(ctx context.Context) error { _, err := s.build(ctx, project, options) return err - }, s.stderr(), "Building") + }, s.stdinfo(), "Building") } func (s *composeService) build(ctx context.Context, project *types.Project, options api.BuildOptions) (map[string]string, error) { //nolint:gocyclo diff --git a/pkg/compose/compose.go b/pkg/compose/compose.go index 329a408fed..8012dfd4bb 100644 --- a/pkg/compose/compose.go +++ b/pkg/compose/compose.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "io" + "os" "strconv" "strings" @@ -40,6 +41,15 @@ import ( "github.com/docker/compose/v2/pkg/api" ) +var stdioToStdout bool + +func init() { + out, ok := os.LookupEnv("COMPOSE_STATUS_STDOUT") + if ok { + stdioToStdout, _ = strconv.ParseBool(out) + } +} + // NewComposeService create a local implementation of the compose.Service API func NewComposeService(dockerCli command.Cli) api.Service { return &composeService{ @@ -97,6 +107,13 @@ func (s *composeService) stderr() io.Writer { return s.dockerCli.Err() } +func (s *composeService) stdinfo() io.Writer { + if stdioToStdout { + return s.dockerCli.Out() + } + return s.dockerCli.Err() +} + func getCanonicalContainerName(c moby.Container) string { if len(c.Names) == 0 { // corner case, sometime happens on removal. return short ID as a safeguard value diff --git a/pkg/compose/cp.go b/pkg/compose/cp.go index 3f43584629..0b87320ab0 100644 --- a/pkg/compose/cp.go +++ b/pkg/compose/cp.go @@ -46,7 +46,7 @@ const ( func (s *composeService) Copy(ctx context.Context, projectName string, options api.CopyOptions) error { return progress.RunWithTitle(ctx, func(ctx context.Context) error { return s.copy(ctx, projectName, options) - }, s.stderr(), "Copying") + }, s.stdinfo(), "Copying") } func (s *composeService) copy(ctx context.Context, projectName string, options api.CopyOptions) error { diff --git a/pkg/compose/create.go b/pkg/compose/create.go index 854387289c..0d5930b7c3 100644 --- a/pkg/compose/create.go +++ b/pkg/compose/create.go @@ -51,7 +51,7 @@ import ( func (s *composeService) Create(ctx context.Context, project *types.Project, options api.CreateOptions) error { return progress.RunWithTitle(ctx, func(ctx context.Context) error { return s.create(ctx, project, options) - }, s.stderr(), "Creating") + }, s.stdinfo(), "Creating") } func (s *composeService) create(ctx context.Context, project *types.Project, options api.CreateOptions) error { diff --git a/pkg/compose/down.go b/pkg/compose/down.go index a9877fbb87..1046b764bb 100644 --- a/pkg/compose/down.go +++ b/pkg/compose/down.go @@ -41,7 +41,7 @@ type downOp func() error func (s *composeService) Down(ctx context.Context, projectName string, options api.DownOptions) error { return progress.Run(ctx, func(ctx context.Context) error { return s.down(ctx, strings.ToLower(projectName), options) - }, s.stderr()) + }, s.stdinfo()) } func (s *composeService) down(ctx context.Context, projectName string, options api.DownOptions) error { diff --git a/pkg/compose/kill.go b/pkg/compose/kill.go index b7a1faf168..ca7039ceeb 100644 --- a/pkg/compose/kill.go +++ b/pkg/compose/kill.go @@ -31,7 +31,7 @@ import ( func (s *composeService) Kill(ctx context.Context, projectName string, options api.KillOptions) error { return progress.RunWithTitle(ctx, func(ctx context.Context) error { return s.kill(ctx, strings.ToLower(projectName), options) - }, s.stderr(), "Killing") + }, s.stdinfo(), "Killing") } func (s *composeService) kill(ctx context.Context, projectName string, options api.KillOptions) error { @@ -57,7 +57,8 @@ func (s *composeService) kill(ctx context.Context, projectName string, options a containers = containers.filter(isService(project.ServiceNames()...)) } if len(containers) == 0 { - fmt.Fprintf(s.stderr(), "no container to kill") + fmt.Fprintf(s.stdinfo(), "no container to kill") + return nil } eg, ctx := errgroup.WithContext(ctx) diff --git a/pkg/compose/pause.go b/pkg/compose/pause.go index cc303da128..5752228461 100644 --- a/pkg/compose/pause.go +++ b/pkg/compose/pause.go @@ -30,7 +30,7 @@ import ( func (s *composeService) Pause(ctx context.Context, projectName string, options api.PauseOptions) error { return progress.RunWithTitle(ctx, func(ctx context.Context) error { return s.pause(ctx, strings.ToLower(projectName), options) - }, s.stderr(), "Pausing") + }, s.stdinfo(), "Pausing") } func (s *composeService) pause(ctx context.Context, projectName string, options api.PauseOptions) error { @@ -62,7 +62,7 @@ func (s *composeService) pause(ctx context.Context, projectName string, options func (s *composeService) UnPause(ctx context.Context, projectName string, options api.PauseOptions) error { return progress.Run(ctx, func(ctx context.Context) error { return s.unPause(ctx, strings.ToLower(projectName), options) - }, s.stderr()) + }, s.stdinfo()) } func (s *composeService) unPause(ctx context.Context, projectName string, options api.PauseOptions) error { diff --git a/pkg/compose/pull.go b/pkg/compose/pull.go index 5dcd2a63eb..96191c39d8 100644 --- a/pkg/compose/pull.go +++ b/pkg/compose/pull.go @@ -44,7 +44,7 @@ func (s *composeService) Pull(ctx context.Context, project *types.Project, optio } return progress.RunWithTitle(ctx, func(ctx context.Context) error { return s.pull(ctx, project, options) - }, s.stderr(), "Pulling") + }, s.stdinfo(), "Pulling") } func (s *composeService) pull(ctx context.Context, project *types.Project, opts api.PullOptions) error { //nolint:gocyclo @@ -305,7 +305,7 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types. } } return err - }, s.stderr()) + }, s.stdinfo()) } func isServiceImageToBuild(service types.ServiceConfig, services []types.ServiceConfig) bool { diff --git a/pkg/compose/push.go b/pkg/compose/push.go index cc520edb00..c60262b6f9 100644 --- a/pkg/compose/push.go +++ b/pkg/compose/push.go @@ -42,7 +42,7 @@ func (s *composeService) Push(ctx context.Context, project *types.Project, optio } return progress.RunWithTitle(ctx, func(ctx context.Context) error { return s.push(ctx, project, options) - }, s.stderr(), "Pushing") + }, s.stdinfo(), "Pushing") } func (s *composeService) push(ctx context.Context, project *types.Project, options api.PushOptions) error { diff --git a/pkg/compose/remove.go b/pkg/compose/remove.go index b5804d5c85..0d684a12bf 100644 --- a/pkg/compose/remove.go +++ b/pkg/compose/remove.go @@ -75,10 +75,10 @@ func (s *composeService) Remove(ctx context.Context, projectName string, options stoppedContainers.forEach(func(c moby.Container) { names = append(names, getCanonicalContainerName(c)) }) - fmt.Fprintln(s.stderr(), names) + fmt.Fprintln(s.stdinfo(), names) if len(names) == 0 { - fmt.Fprintln(s.stderr(), "No stopped containers") + fmt.Fprintln(s.stdinfo(), "No stopped containers") return nil } msg := fmt.Sprintf("Going to remove %s", strings.Join(names, ", ")) @@ -95,7 +95,7 @@ func (s *composeService) Remove(ctx context.Context, projectName string, options } return progress.RunWithTitle(ctx, func(ctx context.Context) error { return s.remove(ctx, stoppedContainers, options) - }, s.stderr(), "Removing") + }, s.stdinfo(), "Removing") } func (s *composeService) remove(ctx context.Context, containers Containers, options api.RemoveOptions) error { diff --git a/pkg/compose/restart.go b/pkg/compose/restart.go index 8a3b9c2599..e091acb6e0 100644 --- a/pkg/compose/restart.go +++ b/pkg/compose/restart.go @@ -31,7 +31,7 @@ import ( func (s *composeService) Restart(ctx context.Context, projectName string, options api.RestartOptions) error { return progress.RunWithTitle(ctx, func(ctx context.Context) error { return s.restart(ctx, strings.ToLower(projectName), options) - }, s.stderr(), "Restarting") + }, s.stdinfo(), "Restarting") } func (s *composeService) restart(ctx context.Context, projectName string, options api.RestartOptions) error { diff --git a/pkg/compose/start.go b/pkg/compose/start.go index 443097b25a..bd2ebcacd9 100644 --- a/pkg/compose/start.go +++ b/pkg/compose/start.go @@ -38,7 +38,7 @@ import ( func (s *composeService) Start(ctx context.Context, projectName string, options api.StartOptions) error { return progress.Run(ctx, func(ctx context.Context) error { return s.start(ctx, strings.ToLower(projectName), options, nil) - }, s.stderr()) + }, s.stdinfo()) } func (s *composeService) start(ctx context.Context, projectName string, options api.StartOptions, listener api.ContainerEventListener) error { diff --git a/pkg/compose/stop.go b/pkg/compose/stop.go index 07d70502b0..a7f6d68db5 100644 --- a/pkg/compose/stop.go +++ b/pkg/compose/stop.go @@ -28,7 +28,7 @@ import ( func (s *composeService) Stop(ctx context.Context, projectName string, options api.StopOptions) error { return progress.RunWithTitle(ctx, func(ctx context.Context) error { return s.stop(ctx, strings.ToLower(projectName), options) - }, s.stderr(), "Stopping") + }, s.stdinfo(), "Stopping") } func (s *composeService) stop(ctx context.Context, projectName string, options api.StopOptions) error { diff --git a/pkg/compose/up.go b/pkg/compose/up.go index a90f0a19d9..98066cd615 100644 --- a/pkg/compose/up.go +++ b/pkg/compose/up.go @@ -40,7 +40,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options return s.start(ctx, project.Name, options.Start, nil) } return nil - }, s.stderr()) + }, s.stdinfo()) if err != nil { return err } @@ -59,7 +59,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) stopFunc := func() error { - fmt.Fprintln(s.stderr(), "Aborting on container exit...") + fmt.Fprintln(s.stdinfo(), "Aborting on container exit...") ctx := context.Background() return progress.Run(ctx, func(ctx context.Context) error { go func() { @@ -74,7 +74,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options Services: options.Create.Services, Project: project, }) - }, s.stderr()) + }, s.stdinfo()) } var isTerminated bool @@ -83,7 +83,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options <-signalChan isTerminated = true printer.Cancel() - fmt.Fprintln(s.stderr(), "Gracefully stopping... (press Ctrl+C again to force)") + fmt.Fprintln(s.stdinfo(), "Gracefully stopping... (press Ctrl+C again to force)") eg.Go(stopFunc) }() diff --git a/pkg/compose/watch.go b/pkg/compose/watch.go index 1712f83906..b57b97b3e0 100644 --- a/pkg/compose/watch.go +++ b/pkg/compose/watch.go @@ -155,7 +155,7 @@ func (s *composeService) Watch(ctx context.Context, project *types.Project, serv return err } - fmt.Fprintf(s.stderr(), "watching %s\n", bc) + fmt.Fprintf(s.stdinfo(), "watching %s\n", bc) err = watcher.Start() if err != nil { return err @@ -207,7 +207,7 @@ WATCH: continue } - fmt.Fprintf(s.stderr(), "change detected on %s\n", hostPath) + fmt.Fprintf(s.stdinfo(), "change detected on %s\n", hostPath) f := fileMapping{ HostPath: hostPath, @@ -283,7 +283,7 @@ func (s *composeService) makeRebuildFn(ctx context.Context, project *types.Proje } fmt.Fprintf( - s.stderr(), + s.stdinfo(), "Rebuilding %s after changes were detected:%s\n", strings.Join(serviceNames, ", "), strings.Join(append([]string{""}, allPaths.Elements()...), "\n - "), @@ -319,7 +319,7 @@ func (s *composeService) makeSyncFn(ctx context.Context, project *types.Project, if err != nil { return err } - fmt.Fprintf(s.stderr(), "%s updated\n", opt.ContainerPath) + fmt.Fprintf(s.stdinfo(), "%s updated\n", opt.ContainerPath) } else if errors.Is(statErr, fs.ErrNotExist) { _, err := s.Exec(ctx, project.Name, api.RunOptions{ Service: opt.Service, @@ -329,7 +329,7 @@ func (s *composeService) makeSyncFn(ctx context.Context, project *types.Project, if err != nil { logrus.Warnf("failed to delete %q from %s: %v", opt.ContainerPath, opt.Service, err) } - fmt.Fprintf(s.stderr(), "%s deleted from container\n", opt.ContainerPath) + fmt.Fprintf(s.stdinfo(), "%s deleted from container\n", opt.ContainerPath) } } }