diff --git a/aci/compose.go b/aci/compose.go index 8beba0ba2..f004ddbd7 100644 --- a/aci/compose.go +++ b/aci/compose.go @@ -44,7 +44,7 @@ func newComposeService(ctx store.AciContext) aciComposeService { } } -func (cs *aciComposeService) Build(ctx context.Context, project *types.Project) error { +func (cs *aciComposeService) Build(ctx context.Context, project *types.Project, options compose.BuildOptions) error { return errdefs.ErrNotImplemented } diff --git a/api/client/compose.go b/api/client/compose.go index 75e7be163..f68378b8c 100644 --- a/api/client/compose.go +++ b/api/client/compose.go @@ -28,7 +28,7 @@ import ( type composeService struct { } -func (c *composeService) Build(ctx context.Context, project *types.Project) error { +func (c *composeService) Build(ctx context.Context, project *types.Project, options compose.BuildOptions) error { return errdefs.ErrNotImplemented } diff --git a/api/compose/api.go b/api/compose/api.go index dfd919333..d1b6ddf29 100644 --- a/api/compose/api.go +++ b/api/compose/api.go @@ -28,7 +28,7 @@ import ( // Service manages a compose project type Service interface { // Build executes the equivalent to a `compose build` - Build(ctx context.Context, project *types.Project) error + Build(ctx context.Context, project *types.Project, options BuildOptions) error // Push executes the equivalent ot a `compose push` Push(ctx context.Context, project *types.Project) error // Pull executes the equivalent of a `compose pull` @@ -65,6 +65,14 @@ type Service interface { UnPause(ctx context.Context, project *types.Project) error } +// BuildOptions group options of the Build API +type BuildOptions struct { + // Pull always attempt to pull a newer version of the image + Pull bool + // Progress set type of progress output ("auto", "plain", "tty") + Progress string +} + // CreateOptions group options of the Create API type CreateOptions struct { // Services defines the services user interacts with diff --git a/cli/cmd/compose/build.go b/cli/cmd/compose/build.go index 622b753fa..b81c17100 100644 --- a/cli/cmd/compose/build.go +++ b/cli/cmd/compose/build.go @@ -23,13 +23,16 @@ import ( "github.com/spf13/cobra" "github.com/docker/compose-cli/api/client" + "github.com/docker/compose-cli/api/compose" "github.com/docker/compose-cli/api/progress" ) type buildOptions struct { *projectOptions composeOptions - quiet bool + quiet bool + pull bool + progress string } func buildCommand(p *projectOptions) *cobra.Command { @@ -51,6 +54,8 @@ func buildCommand(p *projectOptions) *cobra.Command { }, } cmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false, "Don't print anything to STDOUT") + cmd.Flags().BoolVar(&opts.pull, "pull", false, "Always attempt to pull a newer version of the image.") + cmd.Flags().StringVar(&opts.progress, "progress", "auto", `Set type of progress output ("auto", "plain", "tty")`) return cmd } @@ -66,7 +71,10 @@ func runBuild(ctx context.Context, opts buildOptions, services []string) error { } _, err = progress.Run(ctx, func(ctx context.Context) (string, error) { - return "", c.ComposeService().Build(ctx, project) + return "", c.ComposeService().Build(ctx, project, compose.BuildOptions{ + Pull: opts.pull, + Progress: opts.progress, + }) }) return err } diff --git a/ecs/local/compose.go b/ecs/local/compose.go index 6ecce3e71..f8a8da8e5 100644 --- a/ecs/local/compose.go +++ b/ecs/local/compose.go @@ -32,8 +32,8 @@ import ( "github.com/docker/compose-cli/api/errdefs" ) -func (e ecsLocalSimulation) Build(ctx context.Context, project *types.Project) error { - return e.compose.Build(ctx, project) +func (e ecsLocalSimulation) Build(ctx context.Context, project *types.Project, options compose.BuildOptions) error { + return e.compose.Build(ctx, project, options) } func (e ecsLocalSimulation) Push(ctx context.Context, project *types.Project) error { diff --git a/ecs/up.go b/ecs/up.go index 697cabe04..b899bd0df 100644 --- a/ecs/up.go +++ b/ecs/up.go @@ -31,7 +31,7 @@ import ( "github.com/compose-spec/compose-go/types" ) -func (b *ecsAPIService) Build(ctx context.Context, project *types.Project) error { +func (b *ecsAPIService) Build(ctx context.Context, project *types.Project, options compose.BuildOptions) error { return errdefs.ErrNotImplemented } diff --git a/kube/compose.go b/kube/compose.go index 230914a6a..9ca2911fb 100644 --- a/kube/compose.go +++ b/kube/compose.go @@ -124,7 +124,7 @@ func (s *composeService) List(ctx context.Context, opts compose.ListOptions) ([] } // Build executes the equivalent to a `compose build` -func (s *composeService) Build(ctx context.Context, project *types.Project) error { +func (s *composeService) Build(ctx context.Context, project *types.Project, options compose.BuildOptions) error { return errdefs.ErrNotImplemented } diff --git a/local/compose/build.go b/local/compose/build.go index 80efdbe7c..80e8ae991 100644 --- a/local/compose/build.go +++ b/local/compose/build.go @@ -23,6 +23,8 @@ import ( "path" "strings" + "github.com/docker/compose-cli/api/compose" + "github.com/compose-spec/compose-go/types" "github.com/docker/buildx/build" "github.com/docker/buildx/driver" @@ -32,18 +34,20 @@ import ( bclient "github.com/moby/buildkit/client" ) -func (s *composeService) Build(ctx context.Context, project *types.Project) error { +func (s *composeService) Build(ctx context.Context, project *types.Project, options compose.BuildOptions) error { opts := map[string]build.Options{} imagesToBuild := []string{} for _, service := range project.Services { if service.Build != nil { imageName := getImageName(service, project.Name) imagesToBuild = append(imagesToBuild, imageName) - opts[imageName] = s.toBuildOptions(service, project.WorkingDir, imageName) + buildOptions := s.toBuildOptions(service, project.WorkingDir, imageName) + buildOptions.Pull = options.Pull + opts[imageName] = buildOptions } } - err := s.build(ctx, project, opts) + err := s.build(ctx, project, opts, options.Progress) if err == nil { displayScanSuggestMsg(ctx, imagesToBuild) } @@ -93,7 +97,7 @@ func (s *composeService) ensureImagesExists(ctx context.Context, project *types. } - err := s.build(ctx, project, opts) + err := s.build(ctx, project, opts, "auto") if err == nil { displayScanSuggestMsg(ctx, imagesToBuild) } @@ -111,7 +115,7 @@ func (s *composeService) localImagePresent(ctx context.Context, imageName string return true, nil } -func (s *composeService) build(ctx context.Context, project *types.Project, opts map[string]build.Options) error { +func (s *composeService) build(ctx context.Context, project *types.Project, opts map[string]build.Options, mode string) error { if len(opts) == 0 { return nil } @@ -132,7 +136,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opts // build and will lock progressCtx, cancel := context.WithCancel(context.Background()) defer cancel() - w := progress.NewPrinter(progressCtx, os.Stdout, "auto") + w := progress.NewPrinter(progressCtx, os.Stdout, mode) // We rely on buildx "docker" builder integrated in docker engine, so don't need a DockerAPI here _, err = build.Build(ctx, driverInfo, opts, nil, nil, w)