show build progress during watch rebuild

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2025-07-17 10:47:01 +02:00 committed by Guillaume Lours
parent d62e21025c
commit fd954f266c
9 changed files with 35 additions and 10 deletions

View File

@ -121,7 +121,7 @@ func buildCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
} }
flags := cmd.Flags() flags := cmd.Flags()
flags.BoolVar(&opts.push, "push", false, "Push service images") flags.BoolVar(&opts.push, "push", false, "Push service images")
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Don't print anything to STDOUT") flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress the build output")
flags.BoolVar(&opts.pull, "pull", false, "Always attempt to pull a newer version of the image") flags.BoolVar(&opts.pull, "pull", false, "Always attempt to pull a newer version of the image")
flags.StringArrayVar(&opts.args, "build-arg", []string{}, "Set build-time variables for services") flags.StringArrayVar(&opts.args, "build-arg", []string{}, "Set build-time variables for services")
flags.StringVar(&opts.ssh, "ssh", "", "Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent)") flags.StringVar(&opts.ssh, "ssh", "", "Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent)")

View File

@ -165,6 +165,7 @@ func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *c
flags.BoolVar(&create.recreateDeps, "always-recreate-deps", false, "Recreate dependent containers. Incompatible with --no-recreate.") flags.BoolVar(&create.recreateDeps, "always-recreate-deps", false, "Recreate dependent containers. Incompatible with --no-recreate.")
flags.BoolVarP(&create.noInherit, "renew-anon-volumes", "V", false, "Recreate anonymous volumes instead of retrieving data from the previous containers") flags.BoolVarP(&create.noInherit, "renew-anon-volumes", "V", false, "Recreate anonymous volumes instead of retrieving data from the previous containers")
flags.BoolVar(&create.quietPull, "quiet-pull", false, "Pull without printing progress information") flags.BoolVar(&create.quietPull, "quiet-pull", false, "Pull without printing progress information")
flags.BoolVar(&build.quiet, "quiet-build", false, "Suppress the build output")
flags.StringArrayVar(&up.attach, "attach", []string{}, "Restrict attaching to the specified services. Incompatible with --attach-dependencies.") flags.StringArrayVar(&up.attach, "attach", []string{}, "Restrict attaching to the specified services. Incompatible with --attach-dependencies.")
flags.StringArrayVar(&up.noAttach, "no-attach", []string{}, "Do not attach (stream logs) to the specified services") flags.StringArrayVar(&up.noAttach, "no-attach", []string{}, "Do not attach (stream logs) to the specified services")
flags.BoolVar(&up.attachDependencies, "attach-dependencies", false, "Automatically attach to log output of dependent services") flags.BoolVar(&up.attachDependencies, "attach-dependencies", false, "Automatically attach to log output of dependent services")

View File

@ -25,7 +25,7 @@ run `docker compose build` to rebuild it.
| `--provenance` | `string` | | Add a provenance attestation | | `--provenance` | `string` | | Add a provenance attestation |
| `--pull` | `bool` | | Always attempt to pull a newer version of the image | | `--pull` | `bool` | | Always attempt to pull a newer version of the image |
| `--push` | `bool` | | Push service images | | `--push` | `bool` | | Push service images |
| `-q`, `--quiet` | `bool` | | Don't print anything to STDOUT | | `-q`, `--quiet` | `bool` | | Suppress the build output |
| `--sbom` | `string` | | Add a SBOM attestation | | `--sbom` | `string` | | Add a SBOM attestation |
| `--ssh` | `string` | | Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent) | | `--ssh` | `string` | | Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent) |
| `--with-dependencies` | `bool` | | Also build dependencies (transitively) | | `--with-dependencies` | `bool` | | Also build dependencies (transitively) |

View File

@ -44,6 +44,7 @@ If the process is interrupted using `SIGINT` (ctrl + C) or `SIGTERM`, the contai
| `--no-recreate` | `bool` | | If containers already exist, don't recreate them. Incompatible with --force-recreate. | | `--no-recreate` | `bool` | | If containers already exist, don't recreate them. Incompatible with --force-recreate. |
| `--no-start` | `bool` | | Don't start the services after creating them | | `--no-start` | `bool` | | Don't start the services after creating them |
| `--pull` | `string` | `policy` | Pull image before running ("always"\|"missing"\|"never") | | `--pull` | `string` | `policy` | Pull image before running ("always"\|"missing"\|"never") |
| `--quiet-build` | `bool` | | Suppress the build output |
| `--quiet-pull` | `bool` | | Pull without printing progress information | | `--quiet-pull` | `bool` | | Pull without printing progress information |
| `--remove-orphans` | `bool` | | Remove containers for services not defined in the Compose file | | `--remove-orphans` | `bool` | | Remove containers for services not defined in the Compose file |
| `-V`, `--renew-anon-volumes` | `bool` | | Recreate anonymous volumes instead of retrieving data from the previous containers | | `-V`, `--renew-anon-volumes` | `bool` | | Recreate anonymous volumes instead of retrieving data from the previous containers |

View File

@ -158,7 +158,7 @@ options:
shorthand: q shorthand: q
value_type: bool value_type: bool
default_value: "false" default_value: "false"
description: Don't print anything to STDOUT description: Suppress the build output
deprecated: false deprecated: false
hidden: false hidden: false
experimental: false experimental: false

View File

@ -211,6 +211,16 @@ options:
experimentalcli: false experimentalcli: false
kubernetes: false kubernetes: false
swarm: false swarm: false
- option: quiet-build
value_type: bool
default_value: "false"
description: Suppress the build output
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: quiet-pull - option: quiet-pull
value_type: bool value_type: bool
default_value: "false" default_value: "false"

View File

@ -19,6 +19,7 @@ package api
import ( import (
"context" "context"
"fmt" "fmt"
"io"
"slices" "slices"
"strings" "strings"
"time" "time"
@ -176,6 +177,8 @@ type BuildOptions struct {
Provenance string Provenance string
// SBOM generate a SBOM attestation // SBOM generate a SBOM attestation
SBOM string SBOM string
// Out is the stream to write build progress
Out io.Writer
} }
// Apply mutates project according to build options // Apply mutates project according to build options

View File

@ -130,11 +130,15 @@ type buildStatus struct {
func (s *composeService) doBuildBake(ctx context.Context, project *types.Project, serviceToBeBuild types.Services, options api.BuildOptions) (map[string]string, error) { //nolint:gocyclo func (s *composeService) doBuildBake(ctx context.Context, project *types.Project, serviceToBeBuild types.Services, options api.BuildOptions) (map[string]string, error) { //nolint:gocyclo
eg := errgroup.Group{} eg := errgroup.Group{}
ch := make(chan *client.SolveStatus) ch := make(chan *client.SolveStatus)
out := s.dockerCli.Out()
displayMode := progressui.DisplayMode(options.Progress) displayMode := progressui.DisplayMode(options.Progress)
if !out.IsTerminal() { out := options.Out
if out == nil {
cout := s.dockerCli.Out()
if !cout.IsTerminal() {
displayMode = progressui.PlainMode displayMode = progressui.PlainMode
} }
out = cout
}
display, err := progressui.NewDisplay(out, displayMode) display, err := progressui.NewDisplay(out, displayMode)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -29,14 +29,17 @@ import (
gsync "sync" gsync "sync"
"time" "time"
"github.com/compose-spec/compose-go/v2/types"
"github.com/compose-spec/compose-go/v2/utils"
ccli "github.com/docker/cli/cli/command/container"
pathutil "github.com/docker/compose/v2/internal/paths" pathutil "github.com/docker/compose/v2/internal/paths"
"github.com/docker/compose/v2/internal/sync" "github.com/docker/compose/v2/internal/sync"
"github.com/docker/compose/v2/internal/tracing" "github.com/docker/compose/v2/internal/tracing"
"github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/progress"
cutils "github.com/docker/compose/v2/pkg/utils"
"github.com/docker/compose/v2/pkg/watch" "github.com/docker/compose/v2/pkg/watch"
"github.com/compose-spec/compose-go/v2/types"
"github.com/compose-spec/compose-go/v2/utils"
ccli "github.com/docker/cli/cli/command/container"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
@ -61,7 +64,6 @@ func NewWatcher(project *types.Project, options api.UpOptions, w WatchFunc, cons
if service.Develop != nil && service.Develop.Watch != nil { if service.Develop != nil && service.Develop.Watch != nil {
build := options.Create.Build build := options.Create.Build
build.Quiet = true
return &Watcher{ return &Watcher{
project: project, project: project,
options: api.WatchOptions{ options: api.WatchOptions{
@ -598,6 +600,10 @@ func (s *composeService) rebuild(ctx context.Context, project *types.Project, se
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Rebuilding service(s) %q after changes were detected...", services)) options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Rebuilding service(s) %q after changes were detected...", services))
// restrict the build to ONLY this service, not any of its dependencies // restrict the build to ONLY this service, not any of its dependencies
options.Build.Services = services options.Build.Services = services
options.Build.Progress = progress.ModePlain
options.Build.Out = cutils.GetWriter(func(line string) {
options.LogTo.Log(api.WatchLogger, line)
})
var ( var (
imageNameToIdMap map[string]string imageNameToIdMap map[string]string