Skip to content

Commit fc8c56b

Browse files
ndeloofglours
authored andcommitted
select services implicitly declared by a service:xx build dependency
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
1 parent 9c998a9 commit fc8c56b

4 files changed

Lines changed: 41 additions & 31 deletions

File tree

cmd/compose/build.go

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
"github.com/docker/cli/cli/command"
2828
cliopts "github.com/docker/cli/opts"
2929
ui "github.com/docker/compose/v2/pkg/progress"
30-
"github.com/docker/compose/v2/pkg/utils"
3130
buildkit "github.com/moby/buildkit/util/progress/progressui"
3231
"github.com/spf13/cobra"
3332

@@ -141,13 +140,11 @@ func buildCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
141140
}
142141

143142
func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, opts buildOptions, services []string) error {
144-
project, _, err := opts.ToProject(ctx, dockerCli, services, cli.WithResolvedPaths(true), cli.WithoutEnvironmentResolution)
143+
project, _, err := opts.ToProject(ctx, dockerCli, nil, cli.WithResolvedPaths(true), cli.WithoutEnvironmentResolution)
145144
if err != nil {
146145
return err
147146
}
148147

149-
services = addBuildDependencies(services, project)
150-
151148
if err := applyPlatforms(project, false); err != nil {
152149
return err
153150
}
@@ -159,21 +156,3 @@ func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, o
159156

160157
return backend.Build(ctx, project, apiBuildOptions)
161158
}
162-
163-
func addBuildDependencies(services []string, project *types.Project) []string {
164-
servicesWithDependencies := utils.NewSet(services...)
165-
for _, service := range services {
166-
build := project.Services[service].Build
167-
if build != nil {
168-
for _, target := range build.AdditionalContexts {
169-
if s, found := strings.CutPrefix(target, types.ServicePrefix); found {
170-
servicesWithDependencies.Add(s)
171-
}
172-
}
173-
}
174-
}
175-
if len(servicesWithDependencies) > len(services) {
176-
return addBuildDependencies(servicesWithDependencies.Elements(), project)
177-
}
178-
return servicesWithDependencies.Elements()
179-
}

pkg/compose/build.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,16 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
8585
policy = types.IncludeDependencies
8686
}
8787

88-
err := project.ForEachService(options.Services, func(serviceName string, service *types.ServiceConfig) error {
88+
if len(options.Services) > 0 {
89+
// As user requested some services to be built, also include those used as additional_contexts
90+
options.Services = addBuildDependencies(options.Services, project)
91+
}
92+
project, err := project.WithSelectedServices(options.Services)
93+
if err != nil {
94+
return nil, err
95+
}
96+
97+
err = project.ForEachService(options.Services, func(serviceName string, service *types.ServiceConfig) error {
8998
if service.Build == nil {
9099
return nil
91100
}
@@ -613,3 +622,21 @@ func parsePlatforms(service types.ServiceConfig) ([]specs.Platform, error) {
613622

614623
return ret, nil
615624
}
625+
626+
func addBuildDependencies(services []string, project *types.Project) []string {
627+
servicesWithDependencies := utils.NewSet(services...)
628+
for _, service := range services {
629+
b := project.Services[service].Build
630+
if b != nil {
631+
for _, target := range b.AdditionalContexts {
632+
if s, found := strings.CutPrefix(target, types.ServicePrefix); found {
633+
servicesWithDependencies.Add(s)
634+
}
635+
}
636+
}
637+
}
638+
if len(servicesWithDependencies) > len(services) {
639+
return addBuildDependencies(servicesWithDependencies.Elements(), project)
640+
}
641+
return servicesWithDependencies.Elements()
642+
}

pkg/e2e/build_test.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,14 @@ func TestLocalComposeBuild(t *testing.T) {
117117
})
118118

119119
t.Run(env+" rebuild when up --build", func(t *testing.T) {
120-
res := c.RunDockerComposeCmd(t, "--workdir", "fixtures/build-test", "up", "-d", "--build")
120+
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "up", "-d", "--build")
121121

122122
res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"})
123123
res.Assert(t, icmd.Expected{Out: "COPY static2 /usr/share/nginx/html"})
124124
})
125125

126126
t.Run(env+" build --push ignored for unnamed images", func(t *testing.T) {
127-
res := c.RunDockerComposeCmd(t, "--workdir", "fixtures/build-test", "build", "--push", "nginx")
127+
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "build", "--push", "nginx")
128128
assert.Assert(t, !strings.Contains(res.Stdout(), "failed to push"), res.Stdout())
129129
})
130130

@@ -232,7 +232,7 @@ func TestBuildTags(t *testing.T) {
232232
}
233233

234234
func TestBuildImageDependencies(t *testing.T) {
235-
doTest := func(t *testing.T, cli *CLI) {
235+
doTest := func(t *testing.T, cli *CLI, args ...string) {
236236
resetState := func() {
237237
cli.RunDockerComposeCmd(t, "down", "--rmi=all", "-t=0")
238238
res := cli.RunDockerOrExitError(t, "image", "rm", "build-dependencies-service")
@@ -250,7 +250,7 @@ func TestBuildImageDependencies(t *testing.T) {
250250
Err: "No such image: build-dependencies-service",
251251
})
252252

253-
res = cli.RunDockerComposeCmd(t, "build")
253+
res = cli.RunDockerComposeCmd(t, args...)
254254
t.Log(res.Combined())
255255

256256
res = cli.RunDockerCmd(t,
@@ -273,31 +273,35 @@ func TestBuildImageDependencies(t *testing.T) {
273273
"DOCKER_BUILDKIT=0",
274274
"COMPOSE_FILE=./fixtures/build-dependencies/classic.yaml",
275275
))
276-
doTest(t, cli)
276+
doTest(t, cli, "build")
277+
doTest(t, cli, "build", "--with-dependencies", "service")
277278
})
278279

279280
t.Run("BuildKit by dependency order", func(t *testing.T) {
280281
cli := NewCLI(t, WithEnv(
281282
"DOCKER_BUILDKIT=1",
282283
"COMPOSE_FILE=./fixtures/build-dependencies/classic.yaml",
283284
))
284-
doTest(t, cli)
285+
doTest(t, cli, "build")
286+
doTest(t, cli, "build", "--with-dependencies", "service")
285287
})
286288

287289
t.Run("BuildKit by additional contexts", func(t *testing.T) {
288290
cli := NewCLI(t, WithEnv(
289291
"DOCKER_BUILDKIT=1",
290292
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
291293
))
292-
doTest(t, cli)
294+
doTest(t, cli, "build")
295+
doTest(t, cli, "build", "service")
293296
})
294297

295298
t.Run("Bake by additional contexts", func(t *testing.T) {
296299
cli := NewCLI(t, WithEnv(
297300
"DOCKER_BUILDKIT=1", "COMPOSE_BAKE=1",
298301
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
299302
))
300-
doTest(t, cli)
303+
doTest(t, cli, "build")
304+
doTest(t, cli, "build", "service")
301305
})
302306
}
303307

0 commit comments

Comments
 (0)