Skip to content

Commit

Permalink
don't assume os.Stdout and rely on dockerCLI.streams
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
  • Loading branch information
ndeloof committed Dec 20, 2022
1 parent dacf243 commit 24f8327
Show file tree
Hide file tree
Showing 21 changed files with 138 additions and 104 deletions.
4 changes: 2 additions & 2 deletions cmd/compose/build.go
Expand Up @@ -73,7 +73,7 @@ var printerModes = []string{
buildx.PrinterModeQuiet,
}

func buildCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func buildCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
opts := buildOptions{
ProjectOptions: p,
}
Expand All @@ -82,7 +82,7 @@ func buildCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
Short: "Build or rebuild services",
PreRunE: Adapt(func(ctx context.Context, args []string) error {
if opts.memory != "" {
fmt.Println("WARNING --memory is ignored as not supported in buildkit.")
fmt.Fprintln(streams.Err(), "WARNING --memory is ignored as not supported in buildkit.")
}
if opts.quiet {
opts.progress = buildx.PrinterModeQuiet
Expand Down
29 changes: 14 additions & 15 deletions cmd/compose/compose.go
Expand Up @@ -31,7 +31,6 @@ import (
"github.com/docker/buildx/util/logutil"
dockercli "github.com/docker/cli/cli"
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli/command"
"github.com/morikuni/aec"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -243,7 +242,7 @@ func RunningAsStandalone() bool {
}

// RootCommand returns the compose command with its child commands
func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command { //nolint:gocyclo
func RootCommand(streams api.Streams, backend api.Service) *cobra.Command { //nolint:gocyclo
// filter out useless commandConn.CloseWrite warning message that can occur
// when using a remote context that is unreachable: "commandConn.CloseWrite: commandconn: failed to wait: signal: killed"
// https://github.com/docker/cli/blob/e1f24d3c93df6752d3c27c8d61d18260f141310c/cli/connhelper/commandconn/commandconn.go#L203-L215
Expand Down Expand Up @@ -305,7 +304,7 @@ func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command { //
if verbose {
logrus.SetLevel(logrus.TraceLevel)
}
formatter.SetANSIMode(ansi)
formatter.SetANSIMode(streams, ansi)
switch ansi {
case "never":
progress.Mode = progress.ModePlain
Expand Down Expand Up @@ -333,27 +332,27 @@ func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command { //
}

c.AddCommand(
upCommand(&opts, backend),
upCommand(&opts, streams, backend),
downCommand(&opts, backend),
startCommand(&opts, backend),
restartCommand(&opts, backend),
stopCommand(&opts, backend),
psCommand(&opts, backend),
listCommand(backend),
logsCommand(&opts, backend),
convertCommand(&opts, backend),
psCommand(&opts, streams, backend),
listCommand(streams, backend),
logsCommand(&opts, streams, backend),
convertCommand(&opts, streams, backend),
killCommand(&opts, backend),
runCommand(&opts, dockerCli, backend),
runCommand(&opts, streams, backend),
removeCommand(&opts, backend),
execCommand(&opts, dockerCli, backend),
execCommand(&opts, streams, backend),
pauseCommand(&opts, backend),
unpauseCommand(&opts, backend),
topCommand(&opts, backend),
eventsCommand(&opts, backend),
portCommand(&opts, backend),
imagesCommand(&opts, backend),
topCommand(&opts, streams, backend),
eventsCommand(&opts, streams, backend),
portCommand(&opts, streams, backend),
imagesCommand(&opts, streams, backend),
versionCommand(),
buildCommand(&opts, backend),
buildCommand(&opts, streams, backend),
pushCommand(&opts, backend),
pullCommand(&opts, backend),
createCommand(&opts, backend),
Expand Down
40 changes: 20 additions & 20 deletions cmd/compose/convert.go
Expand Up @@ -50,7 +50,7 @@ type convertOptions struct {
noConsistency bool
}

func convertCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func convertCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
opts := convertOptions{
ProjectOptions: p,
}
Expand All @@ -73,22 +73,22 @@ func convertCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
if opts.services {
return runServices(opts)
return runServices(streams, opts)
}
if opts.volumes {
return runVolumes(opts)
return runVolumes(streams, opts)
}
if opts.hash != "" {
return runHash(opts)
return runHash(streams, opts)
}
if opts.profiles {
return runProfiles(opts, args)
return runProfiles(streams, opts, args)
}
if opts.images {
return runConfigImages(opts, args)
return runConfigImages(streams, opts, args)
}

return runConvert(ctx, backend, opts, args)
return runConvert(ctx, streams, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
}
Expand All @@ -110,7 +110,7 @@ func convertCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return cmd
}

func runConvert(ctx context.Context, backend api.Service, opts convertOptions, services []string) error {
func runConvert(ctx context.Context, streams api.Streams, backend api.Service, opts convertOptions, services []string) error {
var content []byte
project, err := opts.ToProject(services,
cli.WithInterpolation(!opts.noInterpolate),
Expand Down Expand Up @@ -139,7 +139,7 @@ func runConvert(ctx context.Context, backend api.Service, opts convertOptions, s
return nil
}

var out io.Writer = os.Stdout
var out io.Writer = streams.Out()
if opts.Output != "" && len(content) > 0 {
file, err := os.Create(opts.Output)
if err != nil {
Expand All @@ -151,29 +151,29 @@ func runConvert(ctx context.Context, backend api.Service, opts convertOptions, s
return err
}

func runServices(opts convertOptions) error {
func runServices(streams api.Streams, opts convertOptions) error {
project, err := opts.ToProject(nil)
if err != nil {
return err
}
return project.WithServices(project.ServiceNames(), func(s types.ServiceConfig) error {
fmt.Println(s.Name)
fmt.Fprintln(streams.Out(), s.Name)
return nil
})
}

func runVolumes(opts convertOptions) error {
func runVolumes(streams api.Streams, opts convertOptions) error {
project, err := opts.ToProject(nil)
if err != nil {
return err
}
for n := range project.Volumes {
fmt.Println(n)
fmt.Fprintln(streams.Out(), n)
}
return nil
}

func runHash(opts convertOptions) error {
func runHash(streams api.Streams, opts convertOptions) error {
var services []string
if opts.hash != "*" {
services = append(services, strings.Split(opts.hash, ",")...)
Expand All @@ -187,12 +187,12 @@ func runHash(opts convertOptions) error {
if err != nil {
return err
}
fmt.Printf("%s %s\n", s.Name, hash)
fmt.Fprintf(streams.Out(), "%s %s\n", s.Name, hash)
}
return nil
}

func runProfiles(opts convertOptions, services []string) error {
func runProfiles(streams api.Streams, opts convertOptions, services []string) error {
set := map[string]struct{}{}
project, err := opts.ToProject(services)
if err != nil {
Expand All @@ -209,21 +209,21 @@ func runProfiles(opts convertOptions, services []string) error {
}
sort.Strings(profiles)
for _, p := range profiles {
fmt.Println(p)
fmt.Fprintln(streams.Out(), p)
}
return nil
}

func runConfigImages(opts convertOptions, services []string) error {
func runConfigImages(streams api.Streams, opts convertOptions, services []string) error {
project, err := opts.ToProject(services)
if err != nil {
return err
}
for _, s := range project.Services {
if s.Image != "" {
fmt.Println(s.Image)
fmt.Fprintln(streams.Out(), s.Image)
} else {
fmt.Printf("%s%s%s\n", project.Name, api.Separator, s.Name)
fmt.Fprintf(streams.Out(), "%s%s%s\n", project.Name, api.Separator, s.Name)
}
}
return nil
Expand Down
10 changes: 5 additions & 5 deletions cmd/compose/events.go
Expand Up @@ -31,7 +31,7 @@ type eventsOpts struct {
json bool
}

func eventsCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func eventsCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
opts := eventsOpts{
composeOptions: &composeOptions{
ProjectOptions: p,
Expand All @@ -41,7 +41,7 @@ func eventsCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
Use: "events [OPTIONS] [SERVICE...]",
Short: "Receive real time events from containers.",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runEvents(ctx, backend, opts, args)
return runEvents(ctx, streams, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
}
Expand All @@ -50,7 +50,7 @@ func eventsCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return cmd
}

func runEvents(ctx context.Context, backend api.Service, opts eventsOpts, services []string) error {
func runEvents(ctx context.Context, streams api.Streams, backend api.Service, opts eventsOpts, services []string) error {
name, err := opts.toProjectName()
if err != nil {
return err
Expand All @@ -71,9 +71,9 @@ func runEvents(ctx context.Context, backend api.Service, opts eventsOpts, servic
if err != nil {
return err
}
fmt.Println(string(marshal))
fmt.Fprintln(streams.Out(), string(marshal))
} else {
fmt.Println(event)
fmt.Fprintln(streams.Out(), event)
}
return nil
},
Expand Down
5 changes: 2 additions & 3 deletions cmd/compose/exec.go
Expand Up @@ -21,7 +21,6 @@ import (

"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/compose"
"github.com/spf13/cobra"
Expand All @@ -43,7 +42,7 @@ type execOpts struct {
interactive bool
}

func execCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func execCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
opts := execOpts{
composeOptions: &composeOptions{
ProjectOptions: p,
Expand All @@ -69,7 +68,7 @@ func execCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
runCmd.Flags().IntVar(&opts.index, "index", 1, "index of the container if there are multiple instances of a service [default: 1].")
runCmd.Flags().BoolVarP(&opts.privileged, "privileged", "", false, "Give extended privileges to the process.")
runCmd.Flags().StringVarP(&opts.user, "user", "u", "", "Run the command as this user.")
runCmd.Flags().BoolVarP(&opts.noTty, "no-TTY", "T", !dockerCli.Out().IsTerminal(), "Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY.")
runCmd.Flags().BoolVarP(&opts.noTty, "no-TTY", "T", !streams.Out().IsTerminal(), "Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY.")
runCmd.Flags().StringVarP(&opts.workingDir, "workdir", "w", "", "Path to workdir directory for this command.")

runCmd.Flags().BoolVarP(&opts.interactive, "interactive", "i", true, "Keep STDIN open even if not attached.")
Expand Down
11 changes: 5 additions & 6 deletions cmd/compose/images.go
Expand Up @@ -20,7 +20,6 @@ import (
"context"
"fmt"
"io"
"os"
"sort"
"strings"

Expand All @@ -39,15 +38,15 @@ type imageOptions struct {
Format string
}

func imagesCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func imagesCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
opts := imageOptions{
ProjectOptions: p,
}
imgCmd := &cobra.Command{
Use: "images [OPTIONS] [SERVICE...]",
Short: "List images used by the created containers",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runImages(ctx, backend, opts, args)
return runImages(ctx, streams, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
}
Expand All @@ -56,7 +55,7 @@ func imagesCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return imgCmd
}

func runImages(ctx context.Context, backend api.Service, opts imageOptions, services []string) error {
func runImages(ctx context.Context, streams api.Streams, backend api.Service, opts imageOptions, services []string) error {
projectName, err := opts.toProjectName()
if err != nil {
return err
Expand All @@ -81,7 +80,7 @@ func runImages(ctx context.Context, backend api.Service, opts imageOptions, serv
}
}
for _, img := range ids {
fmt.Println(img)
fmt.Fprintln(streams.Out(), img)
}
return nil
}
Expand All @@ -90,7 +89,7 @@ func runImages(ctx context.Context, backend api.Service, opts imageOptions, serv
return images[i].ContainerName < images[j].ContainerName
})

return formatter.Print(images, opts.Format, os.Stdout,
return formatter.Print(images, opts.Format, streams.Out(),
func(w io.Writer) {
for _, img := range images {
id := stringid.TruncateID(img.ID)
Expand Down
11 changes: 5 additions & 6 deletions cmd/compose/list.go
Expand Up @@ -20,7 +20,6 @@ import (
"context"
"fmt"
"io"
"os"
"strings"

"github.com/docker/compose/v2/cmd/formatter"
Expand All @@ -38,13 +37,13 @@ type lsOptions struct {
Filter opts.FilterOpt
}

func listCommand(backend api.Service) *cobra.Command {
func listCommand(streams api.Streams, backend api.Service) *cobra.Command {
lsOpts := lsOptions{Filter: opts.NewFilterOpt()}
lsCmd := &cobra.Command{
Use: "ls [OPTIONS]",
Short: "List running compose projects",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runList(ctx, backend, lsOpts)
return runList(ctx, streams, backend, lsOpts)
}),
Args: cobra.NoArgs,
ValidArgsFunction: noCompletion(),
Expand All @@ -61,7 +60,7 @@ var acceptedListFilters = map[string]bool{
"name": true,
}

func runList(ctx context.Context, backend api.Service, lsOpts lsOptions) error {
func runList(ctx context.Context, streams api.Streams, backend api.Service, lsOpts lsOptions) error {
filters := lsOpts.Filter.Value()
err := filters.Validate(acceptedListFilters)
if err != nil {
Expand All @@ -74,7 +73,7 @@ func runList(ctx context.Context, backend api.Service, lsOpts lsOptions) error {
}
if lsOpts.Quiet {
for _, s := range stackList {
fmt.Println(s.Name)
fmt.Fprintln(streams.Out(), s.Name)
}
return nil
}
Expand All @@ -91,7 +90,7 @@ func runList(ctx context.Context, backend api.Service, lsOpts lsOptions) error {
}

view := viewFromStackList(stackList)
return formatter.Print(view, lsOpts.Format, os.Stdout, func(w io.Writer) {
return formatter.Print(view, lsOpts.Format, streams.Out(), func(w io.Writer) {
for _, stack := range view {
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\n", stack.Name, stack.Status, stack.ConfigFiles)
}
Expand Down

0 comments on commit 24f8327

Please sign in to comment.