Browse Source

include implicit build dependencies in build command

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 8 months ago
parent
commit
0badcf3c8d
2 changed files with 78 additions and 0 deletions
  1. 21 0
      cmd/compose/build.go
  2. 57 0
      cmd/compose/build_test.go

+ 21 - 0
cmd/compose/build.go

@@ -27,6 +27,7 @@ import (
 	"github.com/docker/cli/cli/command"
 	cliopts "github.com/docker/cli/opts"
 	ui "github.com/docker/compose/v2/pkg/progress"
+	"github.com/docker/compose/v2/pkg/utils"
 	buildkit "github.com/moby/buildkit/util/progress/progressui"
 	"github.com/spf13/cobra"
 
@@ -145,6 +146,8 @@ func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, o
 		return err
 	}
 
+	services = addBuildDependencies(services, project)
+
 	if err := applyPlatforms(project, false); err != nil {
 		return err
 	}
@@ -156,3 +159,21 @@ func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, o
 
 	return backend.Build(ctx, project, apiBuildOptions)
 }
+
+func addBuildDependencies(services []string, project *types.Project) []string {
+	servicesWithDependencies := utils.NewSet(services...)
+	for _, service := range services {
+		build := project.Services[service].Build
+		if build != nil {
+			for _, target := range build.AdditionalContexts {
+				if s, found := strings.CutPrefix(target, types.ServicePrefix); found {
+					servicesWithDependencies.Add(s)
+				}
+			}
+		}
+	}
+	if len(servicesWithDependencies) > len(services) {
+		return addBuildDependencies(servicesWithDependencies.Elements(), project)
+	}
+	return servicesWithDependencies.Elements()
+}

+ 57 - 0
cmd/compose/build_test.go

@@ -0,0 +1,57 @@
+/*
+   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 (
+	"slices"
+	"testing"
+
+	"github.com/compose-spec/compose-go/v2/types"
+	"gotest.tools/v3/assert"
+)
+
+func Test_addBuildDependencies(t *testing.T) {
+	project := &types.Project{Services: types.Services{
+		"test": types.ServiceConfig{
+			Build: &types.BuildConfig{
+				AdditionalContexts: map[string]string{
+					"foo": "service:foo",
+					"bar": "service:bar",
+				},
+			},
+		},
+		"foo": types.ServiceConfig{
+			Build: &types.BuildConfig{
+				AdditionalContexts: map[string]string{
+					"zot": "service:zot",
+				},
+			},
+		},
+		"bar": types.ServiceConfig{
+			Build: &types.BuildConfig{},
+		},
+		"zot": types.ServiceConfig{
+			Build: &types.BuildConfig{},
+		},
+	}}
+
+	services := addBuildDependencies([]string{"test"}, project)
+	expected := []string{"test", "foo", "bar", "zot"}
+	slices.Sort(services)
+	slices.Sort(expected)
+	assert.DeepEqual(t, services, expected)
+}