Browse Source

identify services to build and don't display 'building' if none

Signed-off-by: Guillaume Lours <[email protected]>
Guillaume Lours 1 year ago
parent
commit
f557220140
1 changed files with 44 additions and 15 deletions
  1. 44 15
      pkg/compose/build.go

+ 44 - 15
pkg/compose/build.go

@@ -22,6 +22,7 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
+	"sync"
 
 	"github.com/compose-spec/compose-go/types"
 	"github.com/containerd/containerd/platforms"
@@ -33,6 +34,10 @@ import (
 	xprogress "github.com/docker/buildx/util/progress"
 	"github.com/docker/cli/cli/command"
 	cliopts "github.com/docker/cli/opts"
+	"github.com/docker/compose/v2/internal/tracing"
+	"github.com/docker/compose/v2/pkg/api"
+	"github.com/docker/compose/v2/pkg/progress"
+	"github.com/docker/compose/v2/pkg/utils"
 	"github.com/docker/docker/builder/remotecontext/urlutil"
 	"github.com/docker/go-units"
 	bclient "github.com/moby/buildkit/client"
@@ -44,11 +49,6 @@ import (
 	specs "github.com/opencontainers/image-spec/specs-go/v1"
 	"github.com/sirupsen/logrus"
 
-	"github.com/docker/compose/v2/internal/tracing"
-	"github.com/docker/compose/v2/pkg/api"
-	"github.com/docker/compose/v2/pkg/progress"
-	"github.com/docker/compose/v2/pkg/utils"
-
 	// required to get default driver registered
 	_ "github.com/docker/buildx/driver/docker"
 )
@@ -64,6 +64,11 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
 	}, s.stdinfo(), "Building")
 }
 
+type serviceToBuild struct {
+	idx     int
+	service types.ServiceConfig
+}
+
 //nolint:gocyclo
 func (s *composeService) build(ctx context.Context, project *types.Project, options api.BuildOptions, localImages map[string]string) (map[string]string, error) {
 	buildkitEnabled, err := s.dockerCli.BuildKitEnabled()
@@ -71,6 +76,36 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
 		return nil, err
 	}
 
+	imageIDs := map[string]string{}
+	serviceToBeBuild := map[string]serviceToBuild{}
+	mapServiceMutx := sync.Mutex{}
+	err = InDependencyOrder(ctx, project, func(ctx context.Context, name string) error {
+		if len(options.Services) > 0 && !utils.Contains(options.Services, name) {
+			return nil
+		}
+		service, idx := getServiceIndex(project, name)
+
+		if service.Build == nil {
+			return nil
+		}
+
+		image := api.GetImageNameOrDefault(service, project.Name)
+		_, localImagePresent := localImages[image]
+		if localImagePresent && service.PullPolicy != types.PullPolicyBuild {
+			return nil
+		}
+		mapServiceMutx.Lock()
+		serviceToBeBuild[name] = serviceToBuild{idx: idx, service: service}
+		mapServiceMutx.Unlock()
+		return nil
+	}, func(traversal *graphTraversal) {
+		traversal.maxConcurrency = s.maxConcurrency
+	})
+
+	if err != nil || len(serviceToBeBuild) == 0 {
+		return imageIDs, err
+	}
+
 	// Initialize buildkit nodes
 	var (
 		b     *builder.Builder
@@ -114,17 +149,12 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
 		if len(options.Services) > 0 && !utils.Contains(options.Services, name) {
 			return nil
 		}
-		service, idx := getServiceIndex(project, name)
-
-		if service.Build == nil {
-			return nil
-		}
-
-		image := api.GetImageNameOrDefault(service, project.Name)
-		_, localImagePresent := localImages[image]
-		if localImagePresent && service.PullPolicy != types.PullPolicyBuild {
+		serviceToBuild, ok := serviceToBeBuild[name]
+		if !ok {
 			return nil
 		}
+		service := serviceToBuild.service
+		idx := serviceToBuild.idx
 
 		if !buildkitEnabled {
 			id, err := s.doBuildClassic(ctx, project, service, options)
@@ -170,7 +200,6 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
 		return nil, err
 	}
 
-	imageIDs := map[string]string{}
 	for i, imageDigest := range builtDigests {
 		if imageDigest != "" {
 			imageRef := api.GetImageNameOrDefault(project.Services[i], project.Name)