From 26f34df3e64554c3a6900671e5c417549e7c90c8 Mon Sep 17 00:00:00 2001 From: Anton Ovchinnikov Date: Sun, 22 Jun 2025 19:26:25 +0200 Subject: [PATCH] fix: Improve output for build operations --- .github/workflows/go-tests.yml | 5 ++++- go.mod | 2 +- internal/cli/build.go | 41 +++++++++------------------------- 3 files changed, 15 insertions(+), 33 deletions(-) diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index cc08f3e7..b1fd9e50 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -31,7 +31,10 @@ jobs: go-version: "1.23.2" - name: Install dependencies - run: go mod tidy + run: | + go mod tidy + git diff --exit-code || + (echo "go.mod or go.sum has changed. Please run 'go mod tidy' and commit the changes." && exit 1) - name: Run tests run: make test diff --git a/go.mod b/go.mod index e9bbf15f..cec5f015 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( github.com/jmoiron/sqlx v1.4.0 github.com/lmittmann/tint v1.0.5 github.com/miekg/dns v1.1.65 + github.com/moby/term v0.5.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 github.com/siderolabs/discovery-api v0.1.4 @@ -215,7 +216,6 @@ require ( github.com/moby/sys/signal v0.7.1 // indirect github.com/moby/sys/user v0.3.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect - github.com/moby/term v0.5.0 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect diff --git a/internal/cli/build.go b/internal/cli/build.go index d1782e9c..1448cbed 100644 --- a/internal/cli/build.go +++ b/internal/cli/build.go @@ -5,7 +5,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io" "os" composetypes "github.com/compose-spec/compose-go/v2/types" @@ -15,7 +14,9 @@ import ( "github.com/docker/docker/api/types/image" dockerclient "github.com/docker/docker/client" "github.com/docker/docker/pkg/archive" + "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/registry" + "github.com/moby/term" ) type BuildOptions struct { @@ -102,19 +103,10 @@ func buildSingleService(ctx context.Context, dockerCli *dockerclient.Client, ser } defer buildResponse.Body.Close() - // Print the build output - decoder := json.NewDecoder(buildResponse.Body) - for { - var message map[string]interface{} - if err := decoder.Decode(&message); err == io.EOF { - break - } else if err != nil { - return "", fmt.Errorf("failed to decode build output for service %s: %w", service.Name, err) - } - - if stream, ok := message["stream"]; ok { - fmt.Print(stream) - } + // Display the build response + fd, isTerminal := term.GetFdInfo(os.Stdout) + if err := jsonmessage.DisplayJSONMessagesStream(buildResponse.Body, os.Stdout, fd, isTerminal, nil); err != nil { + return "", fmt.Errorf("failed to display build response for service %s: %w", service.Name, err) } return imageName, nil @@ -161,24 +153,11 @@ func pushSingleServiceImage(ctx context.Context, dockerCli *dockerclient.Client, } defer pushResponse.Close() - fmt.Printf("Pushing image %s for service %s\n", imageName, serviceName) + fmt.Printf("Pushing image %s for service %s...\n", imageName, serviceName) - // Handle output and errors - decoder := json.NewDecoder(pushResponse) - for { - var message map[string]interface{} - if err := decoder.Decode(&message); err == io.EOF { - break - } else if err != nil { - return fmt.Errorf("failed to decode push output for image %s: %w", imageName, err) - } - if stream, ok := message["stream"]; ok { - fmt.Print(stream) - } else if errorMessage, ok := message["error"]; ok { - return fmt.Errorf("error pushing image %s: %s", imageName, errorMessage) - } else if status, ok := message["status"]; ok { - fmt.Printf(" %s\n", status) - } + fd, isTerminal := term.GetFdInfo(os.Stdout) + if err := jsonmessage.DisplayJSONMessagesStream(pushResponse, os.Stdout, fd, isTerminal, nil); err != nil { + return fmt.Errorf("failed to display push response for image %s: %w", imageName, err) } fmt.Printf("Image %s pushed successfully.\n", imageName)