Skip to content

Commit

Permalink
build: set default builder name if not specified
Browse files Browse the repository at this point in the history
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
  • Loading branch information
crazy-max committed Jun 15, 2022
1 parent c59773f commit e0293f1
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
22 changes: 22 additions & 0 deletions cmd/docker/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package main

import (
"fmt"
"io"
"os"
"strconv"
"strings"

pluginmanager "github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli/command"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

const (
Expand Down Expand Up @@ -127,3 +130,22 @@ func forwardBuilder(alias string, args, osargs []string) ([]string, []string, bo
}
return args, osargs, false
}

// hasBuilderName checks if a builder name is defined in args or env vars
func hasBuilderName(args []string, envs []string) bool {
var builder string
flagset := pflag.NewFlagSet("buildx", pflag.ContinueOnError)
flagset.Usage = func() {}
flagset.SetOutput(io.Discard)
flagset.StringVar(&builder, "builder", "", "")
_ = flagset.Parse(args)
if builder != "" {
return true
}
for _, e := range envs {
if strings.HasPrefix(e, "BUILDX_BUILDER=") {
return true
}
}
return false
}
40 changes: 40 additions & 0 deletions cmd/docker/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,43 @@ func TestBuilderBrokenEnforced(t *testing.T) {
2: output.Suffix("ERROR: BuildKit is enabled but the buildx component is missing or broken."),
})
}

func TestHasBuilderName(t *testing.T) {
cases := []struct {
name string
args []string
envs []string
expected bool
}{
{
name: "no args",
args: []string{"docker", "build", "."},
envs: []string{"FOO=bar"},
expected: false,
},
{
name: "env var",
args: []string{"docker", "build", "."},
envs: []string{"BUILDX_BUILDER=foo"},
expected: true,
},
{
name: "flag",
args: []string{"docker", "build", "--builder", "foo", "."},
envs: []string{"FOO=bar"},
expected: true,
},
{
name: "both",
args: []string{"docker", "build", "--builder", "foo", "."},
envs: []string{"BUILDX_BUILDER=foo"},
expected: true,
},
}
for _, tt := range cases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, hasBuilderName(tt.args, tt.envs))
})
}
}
22 changes: 18 additions & 4 deletions cmd/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,23 @@ func setValidateArgs(dockerCli command.Cli, cmd *cobra.Command) {
})
}

func tryPluginRun(dockerCli command.Cli, cmd *cobra.Command, subcommand string) error {
func tryPluginRun(dockerCli command.Cli, cmd *cobra.Command, orargs []string, subcommand string) error {
plugincmd, err := pluginmanager.PluginRunCommand(dockerCli, subcommand, cmd)
if err != nil {
return err
}

// if build subcommand has changed to a builder alias (buildx),
// user would expect "docker build" to always create a local docker
// image (default builder). this is for better backward compatibility in
// case where user could switch to a docker container builder with
// "docker buildx --use foo" which does not --load by default. also makes
// sure that an arbitrary builder name is not being set in the command
// line or in the environment before setting the default one.
if orargs[0] == "build" && orargs[0] != subcommand && !hasBuilderName(plugincmd.Args, plugincmd.Env) {
plugincmd.Env = append([]string{"BUILDX_BUILDER=default"}, plugincmd.Env...)
}

go func() {
// override SIGTERM handler so we let the plugin shut down first
<-appcontext.Context().Done()
Expand Down Expand Up @@ -223,15 +234,18 @@ func runDocker(dockerCli *command.DockerCli) error {
return err
}

// makes a copy of the original args that can be modified by processAliases
orargs := args

args, os.Args, err = processAliases(dockerCli, cmd, args, os.Args)
if err != nil {
return err
}

if len(args) > 0 {
command, _, err := cmd.Find(args)
if err != nil || command.Annotations[pluginmanager.CommandAnnotationPlugin] == "true" {
err := tryPluginRun(dockerCli, cmd, args[0])
pcmd, _, err := cmd.Find(args)
if err != nil || pcmd.Annotations[pluginmanager.CommandAnnotationPlugin] == "true" {
err := tryPluginRun(dockerCli, cmd, orargs, args[0])
if !pluginmanager.IsNotFound(err) {
return err
}
Expand Down

0 comments on commit e0293f1

Please sign in to comment.