Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit d8aa00a

Browse files
committed
wrap compose cobra command to set exitcode according to metrics status
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent 1fce162 commit d8aa00a

26 files changed

+117
-79
lines changed

cli/cmd/compose/build.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func buildCommand(p *projectOptions, backend compose.Service) *cobra.Command {
4646
cmd := &cobra.Command{
4747
Use: "build [SERVICE...]",
4848
Short: "Build or rebuild services",
49-
RunE: func(cmd *cobra.Command, args []string) error {
49+
RunE: Adapt(func(ctx context.Context, args []string) error {
5050
if opts.memory != "" {
5151
fmt.Println("WARNING --memory is ignored as not supported in buildkit.")
5252
}
@@ -57,8 +57,8 @@ func buildCommand(p *projectOptions, backend compose.Service) *cobra.Command {
5757
}
5858
os.Stdout = devnull
5959
}
60-
return runBuild(cmd.Context(), backend, opts, args)
61-
},
60+
return runBuild(ctx, backend, opts, args)
61+
}),
6262
}
6363
cmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false, "Don't print anything to STDOUT")
6464
cmd.Flags().BoolVar(&opts.pull, "pull", false, "Always attempt to pull a newer version of the image.")

cli/cmd/compose/compose.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
package compose
1818

1919
import (
20+
"context"
2021
"fmt"
2122
"os"
2223
"strings"
2324

2425
"github.com/compose-spec/compose-go/cli"
2526
"github.com/compose-spec/compose-go/types"
27+
dockercli "github.com/docker/cli/cli"
2628
"github.com/morikuni/aec"
2729
"github.com/pkg/errors"
2830
"github.com/spf13/cobra"
@@ -34,6 +36,24 @@ import (
3436
"github.com/docker/compose-cli/cli/metrics"
3537
)
3638

39+
//Command defines a compose CLI command as a func with args
40+
type Command func(context.Context, []string) error
41+
42+
//Adapt a Command func to cobra library
43+
func Adapt(fn Command) func(cmd *cobra.Command, args []string) error {
44+
return func(cmd *cobra.Command, args []string) error {
45+
err := fn(cmd.Context(), args)
46+
var composeErr metrics.ComposeError
47+
if errors.As(err, &composeErr) {
48+
err = dockercli.StatusError{
49+
StatusCode: composeErr.GetMetricsFailureCategory().ExitCode,
50+
Status: err.Error(),
51+
}
52+
}
53+
return err
54+
}
55+
}
56+
3757
// Warning is a global warning to be displayed to user on command failure
3858
var Warning string
3959

@@ -105,8 +125,8 @@ func (o *projectOptions) toProjectOptions(po ...cli.ProjectOptionsFn) (*cli.Proj
105125
cli.WithName(o.ProjectName))...)
106126
}
107127

108-
// Command returns the compose command with its child commands
109-
func Command(contextType string, backend compose.Service) *cobra.Command {
128+
// RootCommand returns the compose command with its child commands
129+
func RootCommand(contextType string, backend compose.Service) *cobra.Command {
110130
opts := projectOptions{}
111131
var ansi string
112132
var noAnsi bool
@@ -120,7 +140,10 @@ func Command(contextType string, backend compose.Service) *cobra.Command {
120140
return cmd.Help()
121141
}
122142
_ = cmd.Help()
123-
return fmt.Errorf("unknown docker command: %q", "compose "+args[0])
143+
return dockercli.StatusError{
144+
StatusCode: metrics.CommandSyntaxFailure.ExitCode,
145+
Status: fmt.Sprintf("unknown docker command: %q", "compose "+args[0]),
146+
}
124147
},
125148
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
126149
parent := cmd.Root()

cli/cmd/compose/convert.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func convertCommand(p *projectOptions, backend compose.Service) *cobra.Command {
5858
Aliases: []string{"config"},
5959
Use: "convert SERVICES",
6060
Short: "Converts the compose file to platform's canonical format",
61-
RunE: func(cmd *cobra.Command, args []string) error {
61+
RunE: Adapt(func(ctx context.Context, args []string) error {
6262
if opts.quiet {
6363
devnull, err := os.Open(os.DevNull)
6464
if err != nil {
@@ -79,8 +79,8 @@ func convertCommand(p *projectOptions, backend compose.Service) *cobra.Command {
7979
return runProfiles(opts, args)
8080
}
8181

82-
return runConvert(cmd.Context(), backend, opts, args)
83-
},
82+
return runConvert(ctx, backend, opts, args)
83+
}),
8484
}
8585
flags := cmd.Flags()
8686
flags.StringVar(&opts.Format, "format", "yaml", "Format the output. Values: [yaml | json]")

cli/cmd/compose/create.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package compose
1818

1919
import (
20+
"context"
2021
"fmt"
2122

2223
"github.com/spf13/cobra"
@@ -37,14 +38,14 @@ func createCommand(p *projectOptions, backend compose.Service) *cobra.Command {
3738
cmd := &cobra.Command{
3839
Use: "create [SERVICE...]",
3940
Short: "Creates containers for a service.",
40-
RunE: func(cmd *cobra.Command, args []string) error {
41+
RunE: Adapt(func(ctx context.Context, args []string) error {
4142
if opts.Build && opts.noBuild {
4243
return fmt.Errorf("--build and --no-build are incompatible")
4344
}
4445
if opts.forceRecreate && opts.noRecreate {
4546
return fmt.Errorf("--force-recreate and --no-recreate are incompatible")
4647
}
47-
return runCreateStart(cmd.Context(), backend, upOptions{
48+
return runCreateStart(ctx, backend, upOptions{
4849
composeOptions: &composeOptions{
4950
projectOptions: p,
5051
Build: opts.Build,
@@ -54,7 +55,7 @@ func createCommand(p *projectOptions, backend compose.Service) *cobra.Command {
5455
forceRecreate: opts.forceRecreate,
5556
noRecreate: opts.noRecreate,
5657
}, args)
57-
},
58+
}),
5859
}
5960
flags := cmd.Flags()
6061
flags.BoolVar(&opts.Build, "build", false, "Build images before starting containers.")

cli/cmd/compose/down.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,17 @@ func downCommand(p *projectOptions, contextType string, backend compose.Service)
4545
downCmd := &cobra.Command{
4646
Use: "down",
4747
Short: "Stop and remove containers, networks",
48-
RunE: func(cmd *cobra.Command, args []string) error {
48+
PreRun: func(cmd *cobra.Command, args []string) {
4949
opts.timeChanged = cmd.Flags().Changed("timeout")
50+
},
51+
RunE: Adapt(func(ctx context.Context, args []string) error {
5052
if opts.images != "" {
5153
if opts.images != "all" && opts.images != "local" {
5254
return fmt.Errorf("invalid value for --rmi: %q", opts.images)
5355
}
5456
}
55-
return runDown(cmd.Context(), backend, opts)
56-
},
57+
return runDown(ctx, backend, opts)
58+
}),
5759
}
5860
flags := downCmd.Flags()
5961
flags.BoolVar(&opts.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")

cli/cmd/compose/events.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ func eventsCommand(p *projectOptions, backend compose.Service) *cobra.Command {
4040
cmd := &cobra.Command{
4141
Use: "events [options] [--] [SERVICE...]",
4242
Short: "Receive real time events from containers.",
43-
RunE: func(cmd *cobra.Command, args []string) error {
44-
return runEvents(cmd.Context(), backend, opts, args)
45-
},
43+
RunE: Adapt(func(ctx context.Context, args []string) error {
44+
return runEvents(ctx, backend, opts, args)
45+
}),
4646
}
4747

4848
cmd.Flags().BoolVar(&opts.json, "json", false, "Output events as a stream of json objects")

cli/cmd/compose/exec.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ func execCommand(p *projectOptions, backend compose.Service) *cobra.Command {
5252
Use: "exec [options] [-e KEY=VAL...] [--] SERVICE COMMAND [ARGS...]",
5353
Short: "Execute a command in a running container.",
5454
Args: cobra.MinimumNArgs(2),
55-
RunE: func(cmd *cobra.Command, args []string) error {
55+
RunE: Adapt(func(ctx context.Context, args []string) error {
5656
if len(args) > 1 {
5757
opts.command = args[1:]
5858
}
5959
opts.service = args[0]
60-
return runExec(cmd.Context(), backend, opts)
61-
},
60+
return runExec(ctx, backend, opts)
61+
}),
6262
}
6363

6464
runCmd.Flags().BoolVarP(&opts.detach, "detach", "d", false, "Detached mode: Run command in the background.")

cli/cmd/compose/images.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ func imagesCommand(p *projectOptions, backend compose.Service) *cobra.Command {
4646
imgCmd := &cobra.Command{
4747
Use: "images [SERVICE...]",
4848
Short: "List images used by the created containers",
49-
RunE: func(cmd *cobra.Command, args []string) error {
50-
return runImages(cmd.Context(), backend, opts, args)
51-
},
49+
RunE: Adapt(func(ctx context.Context, args []string) error {
50+
return runImages(ctx, backend, opts, args)
51+
}),
5252
}
5353
imgCmd.Flags().BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs")
5454
return imgCmd

cli/cmd/compose/kill.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ func killCommand(p *projectOptions, backend compose.Service) *cobra.Command {
3636
cmd := &cobra.Command{
3737
Use: "kill [options] [SERVICE...]",
3838
Short: "Force stop service containers.",
39-
RunE: func(cmd *cobra.Command, args []string) error {
40-
return runKill(cmd.Context(), backend, opts, args)
41-
},
39+
RunE: Adapt(func(ctx context.Context, args []string) error {
40+
return runKill(ctx, backend, opts, args)
41+
}),
4242
}
4343

4444
flags := cmd.Flags()

cli/cmd/compose/list.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ func listCommand(contextType string, backend compose.Service) *cobra.Command {
4343
lsCmd := &cobra.Command{
4444
Use: "ls",
4545
Short: "List running compose projects",
46-
RunE: func(cmd *cobra.Command, args []string) error {
47-
return runList(cmd.Context(), backend, opts)
48-
},
46+
RunE: Adapt(func(ctx context.Context, args []string) error {
47+
return runList(ctx, backend, opts)
48+
}),
4949
}
5050
lsCmd.Flags().StringVar(&opts.Format, "format", "pretty", "Format the output. Values: [pretty | json].")
5151
lsCmd.Flags().BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs.")

0 commit comments

Comments
 (0)