Jelajahi Sumber

Merge pull request #28010 from vieux/fix_experimental_client

always add but hide experimental cmds and flags
Victor Vieux 8 tahun lalu
induk
melakukan
f6edbdf883

+ 1 - 0
cli/command/checkpoint/cmd.go

@@ -17,6 +17,7 @@ func NewCheckpointCommand(dockerCli *command.DockerCli) *cobra.Command {
 		Run: func(cmd *cobra.Command, args []string) {
 		Run: func(cmd *cobra.Command, args []string) {
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
 		},
 		},
+		Tags: map[string]string{"experimental": ""},
 	}
 	}
 	cmd.AddCommand(
 	cmd.AddCommand(
 		newCreateCommand(dockerCli),
 		newCreateCommand(dockerCli),

+ 10 - 16
cli/command/cli.go

@@ -32,27 +32,21 @@ type Streams interface {
 // DockerCli represents the docker command line client.
 // DockerCli represents the docker command line client.
 // Instances of the client can be returned from NewDockerCli.
 // Instances of the client can be returned from NewDockerCli.
 type DockerCli struct {
 type DockerCli struct {
-	configFile      *configfile.ConfigFile
-	in              *InStream
-	out             *OutStream
-	err             io.Writer
-	keyFile         string
-	client          client.APIClient
-	hasExperimental *bool
+	configFile *configfile.ConfigFile
+	in         *InStream
+	out        *OutStream
+	err        io.Writer
+	keyFile    string
+	client     client.APIClient
 }
 }
 
 
 // HasExperimental returns true if experimental features are accessible
 // HasExperimental returns true if experimental features are accessible
 func (cli *DockerCli) HasExperimental() bool {
 func (cli *DockerCli) HasExperimental() bool {
-	if cli.hasExperimental == nil {
-		if cli.client == nil {
-			cli.Initialize(cliflags.NewClientOptions())
-		}
-		enabled := false
-		cli.hasExperimental = &enabled
-		enabled, _ = cli.client.Ping(context.Background())
+	if cli.client == nil {
+		return false
 	}
 	}
-
-	return *cli.hasExperimental
+	enabled, _ := cli.client.Ping(context.Background())
+	return enabled
 }
 }
 
 
 // Client returns the APIClient
 // Client returns the APIClient

+ 4 - 9
cli/command/commands/commands.go

@@ -70,17 +70,12 @@ func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) {
 		hide(image.NewSaveCommand(dockerCli)),
 		hide(image.NewSaveCommand(dockerCli)),
 		hide(image.NewTagCommand(dockerCli)),
 		hide(image.NewTagCommand(dockerCli)),
 		hide(system.NewInspectCommand(dockerCli)),
 		hide(system.NewInspectCommand(dockerCli)),
+		stack.NewStackCommand(dockerCli),
+		stack.NewTopLevelDeployCommand(dockerCli),
+		checkpoint.NewCheckpointCommand(dockerCli),
+		plugin.NewPluginCommand(dockerCli),
 	)
 	)
 
 
-	if dockerCli.HasExperimental() {
-		cmd.AddCommand(
-			stack.NewStackCommand(dockerCli),
-			stack.NewTopLevelDeployCommand(dockerCli),
-			checkpoint.NewCheckpointCommand(dockerCli),
-			plugin.NewPluginCommand(dockerCli),
-		)
-	}
-
 }
 }
 
 
 func hide(cmd *cobra.Command) *cobra.Command {
 func hide(cmd *cobra.Command) *cobra.Command {

+ 4 - 5
cli/command/container/start.go

@@ -45,11 +45,10 @@ func NewStartCommand(dockerCli *command.DockerCli) *cobra.Command {
 	flags.BoolVarP(&opts.openStdin, "interactive", "i", false, "Attach container's STDIN")
 	flags.BoolVarP(&opts.openStdin, "interactive", "i", false, "Attach container's STDIN")
 	flags.StringVar(&opts.detachKeys, "detach-keys", "", "Override the key sequence for detaching a container")
 	flags.StringVar(&opts.detachKeys, "detach-keys", "", "Override the key sequence for detaching a container")
 
 
-	if dockerCli.HasExperimental() {
-		flags.StringVar(&opts.checkpoint, "checkpoint", "", "Restore from this checkpoint")
-		flags.StringVar(&opts.checkpointDir, "checkpoint-dir", "", "Use a custom checkpoint storage directory")
-	}
-
+	flags.StringVar(&opts.checkpoint, "checkpoint", "", "Restore from this checkpoint")
+	flags.SetAnnotation("checkpoint", "experimental", nil)
+	flags.StringVar(&opts.checkpointDir, "checkpoint-dir", "", "Use a custom checkpoint storage directory")
+	flags.SetAnnotation("checkpoint-dir", "experimental", nil)
 	return cmd
 	return cmd
 }
 }
 
 

+ 2 - 3
cli/command/image/build.go

@@ -111,9 +111,8 @@ func NewBuildCommand(dockerCli *command.DockerCli) *cobra.Command {
 
 
 	command.AddTrustedFlags(flags, true)
 	command.AddTrustedFlags(flags, true)
 
 
-	if dockerCli.HasExperimental() {
-		flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer")
-	}
+	flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer")
+	flags.SetAnnotation("squash", "experimental", nil)
 
 
 	return cmd
 	return cmd
 }
 }

+ 1 - 0
cli/command/plugin/cmd.go

@@ -17,6 +17,7 @@ func NewPluginCommand(dockerCli *command.DockerCli) *cobra.Command {
 		Run: func(cmd *cobra.Command, args []string) {
 		Run: func(cmd *cobra.Command, args []string) {
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
 		},
 		},
+		Tags: map[string]string{"experimental": ""},
 	}
 	}
 
 
 	cmd.AddCommand(
 	cmd.AddCommand(

+ 1 - 0
cli/command/stack/cmd.go

@@ -17,6 +17,7 @@ func NewStackCommand(dockerCli *command.DockerCli) *cobra.Command {
 		Run: func(cmd *cobra.Command, args []string) {
 		Run: func(cmd *cobra.Command, args []string) {
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
 		},
 		},
+		Tags: map[string]string{"experimental": ""},
 	}
 	}
 	cmd.AddCommand(
 	cmd.AddCommand(
 		newConfigCommand(dockerCli),
 		newConfigCommand(dockerCli),

+ 1 - 0
cli/command/stack/deploy.go

@@ -36,6 +36,7 @@ func newDeployCommand(dockerCli *command.DockerCli) *cobra.Command {
 			opts.namespace = strings.TrimSuffix(args[0], ".dab")
 			opts.namespace = strings.TrimSuffix(args[0], ".dab")
 			return runDeploy(dockerCli, opts)
 			return runDeploy(dockerCli, opts)
 		},
 		},
+		Tags: map[string]string{"experimental": ""},
 	}
 	}
 
 
 	flags := cmd.Flags()
 	flags := cmd.Flags()

+ 34 - 1
cmd/docker/docker.go

@@ -33,7 +33,8 @@ func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
 				showVersion()
 				showVersion()
 				return nil
 				return nil
 			}
 			}
-			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
+			cmd.SetOutput(dockerCli.Err())
+			cmd.HelpFunc()(cmd, args)
 			return nil
 			return nil
 		},
 		},
 		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
 		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
@@ -45,6 +46,22 @@ func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
 	}
 	}
 	cli.SetupRootCommand(cmd)
 	cli.SetupRootCommand(cmd)
 
 
+	cmd.SetHelpFunc(func(ccmd *cobra.Command, args []string) {
+		var err error
+		if dockerCli.Client() == nil {
+			// flags must be the top-level command flags, not cmd.Flags()
+			opts.Common.SetDefaultOptions(flags)
+			dockerPreRun(opts)
+			err = dockerCli.Initialize(opts)
+		}
+		if err != nil || !dockerCli.HasExperimental() {
+			hideExperimentalFeatures(ccmd)
+		}
+		if err := ccmd.Help(); err != nil {
+			ccmd.Println(err)
+		}
+	})
+
 	flags = cmd.Flags()
 	flags = cmd.Flags()
 	flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")
 	flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")
 	flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files")
 	flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files")
@@ -105,3 +122,19 @@ func dockerPreRun(opts *cliflags.ClientOptions) {
 		utils.EnableDebug()
 		utils.EnableDebug()
 	}
 	}
 }
 }
+
+func hideExperimentalFeatures(cmd *cobra.Command) {
+	// hide flags
+	cmd.Flags().VisitAll(func(f *pflag.Flag) {
+		if _, ok := f.Annotations["experimental"]; ok {
+			f.Hidden = true
+		}
+	})
+
+	for _, subcmd := range cmd.Commands() {
+		// hide subcommands
+		if _, ok := subcmd.Tags["experimental"]; ok {
+			subcmd.Hidden = true
+		}
+	}
+}

+ 1 - 1
vendor.conf

@@ -123,7 +123,7 @@ github.com/matttproud/golang_protobuf_extensions fc2b8d3a73c4867e51861bbdd5ae3c1
 github.com/pkg/errors 01fa4104b9c248c8945d14d9f128454d5b28d595
 github.com/pkg/errors 01fa4104b9c248c8945d14d9f128454d5b28d595
 
 
 # cli
 # cli
-github.com/spf13/cobra v1.4.1 https://github.com/dnephin/cobra.git
+github.com/spf13/cobra v1.5 https://github.com/dnephin/cobra.git
 github.com/spf13/pflag dabebe21bf790f782ea4c7bbd2efc430de182afd
 github.com/spf13/pflag dabebe21bf790f782ea4c7bbd2efc430de182afd
 github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
 github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
 github.com/flynn-archive/go-shlex 3f9db97f856818214da2e1057f8ad84803971cff
 github.com/flynn-archive/go-shlex 3f9db97f856818214da2e1057f8ad84803971cff

+ 9 - 6
vendor/github.com/spf13/cobra/command.go

@@ -59,6 +59,9 @@ type Command struct {
 	Deprecated string
 	Deprecated string
 	// Is this command hidden and should NOT show up in the list of available commands?
 	// Is this command hidden and should NOT show up in the list of available commands?
 	Hidden bool
 	Hidden bool
+	// Tags are key/value pairs that can be used by applications to identify or
+	// group commands
+	Tags map[string]string
 	// Full set of flags
 	// Full set of flags
 	flags *flag.FlagSet
 	flags *flag.FlagSet
 	// Set of flags childrens of this command will inherit
 	// Set of flags childrens of this command will inherit
@@ -111,10 +114,10 @@ type Command struct {
 
 
 	flagErrorBuf *bytes.Buffer
 	flagErrorBuf *bytes.Buffer
 
 
-	args          []string                 // actual args parsed from flags
-	output        *io.Writer               // nil means stderr; use Out() method instead
-	usageFunc     func(*Command) error     // Usage can be defined by application
-	usageTemplate string                   // Can be defined by Application
+	args          []string             // actual args parsed from flags
+	output        *io.Writer           // nil means stderr; use Out() method instead
+	usageFunc     func(*Command) error // Usage can be defined by application
+	usageTemplate string               // Can be defined by Application
 	flagErrorFunc func(*Command, error) error
 	flagErrorFunc func(*Command, error) error
 	helpTemplate  string                   // Can be defined by Application
 	helpTemplate  string                   // Can be defined by Application
 	helpFunc      func(*Command, []string) // Help can be defined by application
 	helpFunc      func(*Command, []string) // Help can be defined by application
@@ -417,7 +420,7 @@ func argsMinusFirstX(args []string, x string) []string {
 
 
 func isFlagArg(arg string) bool {
 func isFlagArg(arg string) bool {
 	return ((len(arg) >= 3 && arg[1] == '-') ||
 	return ((len(arg) >= 3 && arg[1] == '-') ||
-	        (len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
+		(len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
 }
 }
 
 
 // Find the target command given the args and command tree
 // Find the target command given the args and command tree
@@ -820,7 +823,7 @@ func (c commandSorterByName) Less(i, j int) bool { return c[i].Name() < c[j].Nam
 // Commands returns a sorted slice of child commands.
 // Commands returns a sorted slice of child commands.
 func (c *Command) Commands() []*Command {
 func (c *Command) Commands() []*Command {
 	// do not sort commands if it already sorted or sorting was disabled
 	// do not sort commands if it already sorted or sorting was disabled
-	if EnableCommandSorting && !c.commandsAreSorted{
+	if EnableCommandSorting && !c.commandsAreSorted {
 		sort.Sort(commandSorterByName(c.commands))
 		sort.Sort(commandSorterByName(c.commands))
 		c.commandsAreSorted = true
 		c.commandsAreSorted = true
 	}
 	}