From 5952183eca550f64c42c23d193eeb0cbcb75f36e Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Mon, 30 Nov 2020 12:03:13 +0100 Subject: [PATCH] introduce `compose build` command Signed-off-by: Nicolas De Loof --- aci/compose.go | 4 +++ api/client/compose.go | 4 +++ api/compose/api.go | 2 ++ cli/cmd/compose/build.go | 67 ++++++++++++++++++++++++++++++++++++++ cli/cmd/compose/compose.go | 5 +++ ecs/local/compose.go | 4 +++ ecs/up.go | 5 +++ example/backend.go | 5 +++ local/compose.go | 12 +++++++ 9 files changed, 108 insertions(+) create mode 100644 cli/cmd/compose/build.go diff --git a/aci/compose.go b/aci/compose.go index b9a6d120..a850cd2f 100644 --- a/aci/compose.go +++ b/aci/compose.go @@ -44,6 +44,10 @@ func newComposeService(ctx store.AciContext) aciComposeService { } } +func (cs *aciComposeService) Build(ctx context.Context, project *types.Project) error { + return errdefs.ErrNotImplemented +} + func (cs *aciComposeService) Up(ctx context.Context, project *types.Project, detach bool) error { logrus.Debugf("Up on project with name %q", project.Name) diff --git a/api/client/compose.go b/api/client/compose.go index 33014ec6..419a4da2 100644 --- a/api/client/compose.go +++ b/api/client/compose.go @@ -29,6 +29,10 @@ import ( type composeService struct { } +func (c *composeService) Build(ctx context.Context, project *types.Project) error { + return errdefs.ErrNotImplemented +} + // Up executes the equivalent to a `compose up` func (c *composeService) Up(context.Context, *types.Project, bool) error { return errdefs.ErrNotImplemented diff --git a/api/compose/api.go b/api/compose/api.go index 22ddb9d1..990ea0e0 100644 --- a/api/compose/api.go +++ b/api/compose/api.go @@ -25,6 +25,8 @@ 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 // Up executes the equivalent to a `compose up` Up(ctx context.Context, project *types.Project, detach bool) error // Down executes the equivalent to a `compose down` diff --git a/cli/cmd/compose/build.go b/cli/cmd/compose/build.go new file mode 100644 index 00000000..0948db1e --- /dev/null +++ b/cli/cmd/compose/build.go @@ -0,0 +1,67 @@ +/* + Copyright 2020 Docker Compose CLI authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package compose + +import ( + "context" + + "github.com/compose-spec/compose-go/cli" + "github.com/spf13/cobra" + + "github.com/docker/compose-cli/api/client" + "github.com/docker/compose-cli/progress" +) + +type buildOptions struct { + composeOptions +} + +func buildCommand() *cobra.Command { + opts := buildOptions{} + buildCmd := &cobra.Command{ + Use: "build [SERVICE...]", + RunE: func(cmd *cobra.Command, args []string) error { + return runBuild(cmd.Context(), opts, args) + }, + } + return buildCmd +} + +func runBuild(ctx context.Context, opts buildOptions, services []string) error { + c, err := client.New(ctx) + if err != nil { + return err + } + + _, err = progress.Run(ctx, func(ctx context.Context) (string, error) { + options, err := opts.toProjectOptions() + if err != nil { + return "", err + } + project, err := cli.ProjectFromOptions(options) + if err != nil { + return "", err + } + + err = filter(project, services) + if err != nil { + return "", err + } + return "", c.ComposeService().Build(ctx, project) + }) + return err +} diff --git a/cli/cmd/compose/compose.go b/cli/cmd/compose/compose.go index 9108dc88..a65bbc57 100644 --- a/cli/cmd/compose/compose.go +++ b/cli/cmd/compose/compose.go @@ -25,6 +25,7 @@ import ( "github.com/spf13/pflag" "github.com/docker/compose-cli/api/client" + "github.com/docker/compose-cli/context/store" "github.com/docker/compose-cli/errdefs" ) @@ -89,6 +90,10 @@ func Command(contextType string) *cobra.Command { convertCommand(), ) + if contextType == store.LocalContextType { + command.AddCommand(buildCommand()) + } + return command } diff --git a/ecs/local/compose.go b/ecs/local/compose.go index eb16303d..ef0ab16d 100644 --- a/ecs/local/compose.go +++ b/ecs/local/compose.go @@ -41,6 +41,10 @@ import ( "golang.org/x/mod/semver" ) +func (e ecsLocalSimulation) Build(ctx context.Context, project *types.Project) error { + return errdefs.ErrNotImplemented +} + func (e ecsLocalSimulation) Up(ctx context.Context, project *types.Project, detach bool) error { cmd := exec.Command("docker-compose", "version", "--short") b := bytes.Buffer{} diff --git a/ecs/up.go b/ecs/up.go index 373407e2..31db45ed 100644 --- a/ecs/up.go +++ b/ecs/up.go @@ -24,8 +24,13 @@ import ( "syscall" "github.com/compose-spec/compose-go/types" + "github.com/docker/compose-cli/errdefs" ) +func (b *ecsAPIService) Build(ctx context.Context, project *types.Project) error { + return errdefs.ErrNotImplemented +} + func (b *ecsAPIService) Up(ctx context.Context, project *types.Project, detach bool) error { err := b.aws.CheckRequirements(ctx, b.Region) if err != nil { diff --git a/example/backend.go b/example/backend.go index a02ed9d0..48c69e4d 100644 --- a/example/backend.go +++ b/example/backend.go @@ -138,6 +138,11 @@ func (cs *containerService) Delete(ctx context.Context, id string, request conta type composeService struct{} +func (cs *composeService) Build(ctx context.Context, project *types.Project) error { + fmt.Printf("Build command on project %q", project.Name) + return nil +} + func (cs *composeService) Up(ctx context.Context, project *types.Project, detach bool) error { fmt.Printf("Up command on project %q", project.Name) return nil diff --git a/local/compose.go b/local/compose.go index c550d508..76dd84d2 100644 --- a/local/compose.go +++ b/local/compose.go @@ -29,6 +29,7 @@ import ( "strings" "github.com/compose-spec/compose-go/types" + "github.com/docker/buildx/build" moby "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" @@ -53,6 +54,17 @@ type composeService struct { apiClient *client.Client } +func (s *composeService) Build(ctx context.Context, project *types.Project) error { + opts := map[string]build.Options{} + for _, service := range project.Services { + if service.Build != nil { + opts[service.Name] = s.toBuildOptions(service, project.WorkingDir) + } + } + + return s.build(ctx, project, opts) +} + func (s *composeService) Up(ctx context.Context, project *types.Project, detach bool) error { err := s.ensureImagesExists(ctx, project) if err != nil {