commands: check if flag is set instead of using flagutil.Tristate

Fixes --pull and --no-cache without argument

Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
Tibor Vass 2020-04-30 12:25:30 -07:00
parent 205165bec5
commit c4d07f67e3
3 changed files with 41 additions and 47 deletions

View File

@ -106,13 +106,15 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
Use: "bake [OPTIONS] [TARGET...]",
Aliases: []string{"f"},
Short: "Build from a file",
RunE: func(cmd *cobra.Command, args []string) error {
return runBake(dockerCli, args, options)
},
}
flags := cmd.Flags()
cmd.RunE = func(cmd *cobra.Command, args []string) error {
handleUnsetFlags(flags, &options)
return runBake(dockerCli, args, options)
}
flags.StringArrayVarP(&options.files, "file", "f", []string{}, "Build definition file")
flags.BoolVar(&options.printOnly, "print", false, "Print the options without building")
flags.StringArrayVar(&options.overrides, "set", nil, "Override target value (eg: targetpattern.key=value)")

View File

@ -7,7 +7,6 @@ import (
"strings"
"github.com/docker/buildx/build"
"github.com/docker/buildx/util/flagutil"
"github.com/docker/buildx/util/platformutil"
"github.com/docker/buildx/util/progress"
"github.com/docker/cli/cli"
@ -71,6 +70,18 @@ type commonOptions struct {
exportLoad bool
}
func (o *commonOptions) Unset(s string) error {
switch s {
case "pull":
o.noCache = nil
case "no-cache":
o.pull = nil
default:
return errors.Errorf("cannot unset flag %q", s)
}
return nil
}
func runBuild(dockerCli command.Cli, in buildOptions) error {
if in.squash {
return errors.Errorf("squash currently not implemented")
@ -209,6 +220,21 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]bu
return err
}
type unsetter interface {
Unset(flagName string) error
}
func handleUnsetFlags(flags *pflag.FlagSet, options unsetter) error {
for _, name := range []string{"pull", "no-cache"} {
if !flags.Lookup(name).Changed {
if err := options.Unset(name); err != nil {
return err
}
}
}
return nil
}
func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
var options buildOptions
@ -217,15 +243,17 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
Aliases: []string{"b"},
Short: "Start a build",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
options.contextPath = args[0]
options.builder = rootOpts.builder
return runBuild(dockerCli, options)
},
}
flags := cmd.Flags()
cmd.RunE = func(cmd *cobra.Command, args []string) error {
options.contextPath = args[0]
options.builder = rootOpts.builder
handleUnsetFlags(flags, &options)
return runBuild(dockerCli, options)
}
flags.BoolVar(&options.exportPush, "push", false, "Shorthand for --output=type=registry")
flags.BoolVar(&options.exportLoad, "load", false, "Shorthand for --output=type=docker")
@ -305,9 +333,9 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
}
func commonBuildFlags(options *commonOptions, flags *pflag.FlagSet) {
flags.Var(flagutil.Tristate(options.noCache), "no-cache", "Do not use cache when building the image")
options.noCache = flags.Bool("no-cache", false, "Do not use cache when building the image")
flags.StringVar(&options.progress, "progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
flags.Var(flagutil.Tristate(options.pull), "pull", "Always attempt to pull a newer version of the image")
options.pull = flags.Bool("pull", false, "Always attempt to pull a newer version of the image")
}
func listToMap(values []string, defaultEnv bool) map[string]string {

View File

@ -1,36 +0,0 @@
package flagutil
import "strconv"
type tristate struct {
opt *bool
}
// Tristate is a tri-state boolean flag type.
// It can be set, but not unset.
func Tristate(opt *bool) tristate {
return tristate{opt}
}
func (t tristate) Type() string {
return "tristate"
}
func (t tristate) String() string {
if t.opt == nil {
return "(unset)"
}
if *t.opt {
return "true"
}
return "false"
}
func (t tristate) Set(s string) error {
b, err := strconv.ParseBool(s)
if err != nil {
return err
}
t.opt = &b
return nil
}