always add but hide experimental cmds and flags
| ... | ... |
@@ -17,6 +17,7 @@ func NewCheckpointCommand(dockerCli *command.DockerCli) *cobra.Command {
|
| 17 | 17 |
Run: func(cmd *cobra.Command, args []string) {
|
| 18 | 18 |
fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) |
| 19 | 19 |
}, |
| 20 |
+ Tags: map[string]string{"experimental": ""},
|
|
| 20 | 21 |
} |
| 21 | 22 |
cmd.AddCommand( |
| 22 | 23 |
newCreateCommand(dockerCli), |
| ... | ... |
@@ -32,27 +32,21 @@ type Streams interface {
|
| 32 | 32 |
// DockerCli represents the docker command line client. |
| 33 | 33 |
// Instances of the client can be returned from NewDockerCli. |
| 34 | 34 |
type DockerCli struct {
|
| 35 |
- configFile *configfile.ConfigFile |
|
| 36 |
- in *InStream |
|
| 37 |
- out *OutStream |
|
| 38 |
- err io.Writer |
|
| 39 |
- keyFile string |
|
| 40 |
- client client.APIClient |
|
| 41 |
- hasExperimental *bool |
|
| 35 |
+ configFile *configfile.ConfigFile |
|
| 36 |
+ in *InStream |
|
| 37 |
+ out *OutStream |
|
| 38 |
+ err io.Writer |
|
| 39 |
+ keyFile string |
|
| 40 |
+ client client.APIClient |
|
| 42 | 41 |
} |
| 43 | 42 |
|
| 44 | 43 |
// HasExperimental returns true if experimental features are accessible |
| 45 | 44 |
func (cli *DockerCli) HasExperimental() bool {
|
| 46 |
- if cli.hasExperimental == nil {
|
|
| 47 |
- if cli.client == nil {
|
|
| 48 |
- cli.Initialize(cliflags.NewClientOptions()) |
|
| 49 |
- } |
|
| 50 |
- enabled := false |
|
| 51 |
- cli.hasExperimental = &enabled |
|
| 52 |
- enabled, _ = cli.client.Ping(context.Background()) |
|
| 45 |
+ if cli.client == nil {
|
|
| 46 |
+ return false |
|
| 53 | 47 |
} |
| 54 |
- |
|
| 55 |
- return *cli.hasExperimental |
|
| 48 |
+ enabled, _ := cli.client.Ping(context.Background()) |
|
| 49 |
+ return enabled |
|
| 56 | 50 |
} |
| 57 | 51 |
|
| 58 | 52 |
// Client returns the APIClient |
| ... | ... |
@@ -70,17 +70,12 @@ func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) {
|
| 70 | 70 |
hide(image.NewSaveCommand(dockerCli)), |
| 71 | 71 |
hide(image.NewTagCommand(dockerCli)), |
| 72 | 72 |
hide(system.NewInspectCommand(dockerCli)), |
| 73 |
+ stack.NewStackCommand(dockerCli), |
|
| 74 |
+ stack.NewTopLevelDeployCommand(dockerCli), |
|
| 75 |
+ checkpoint.NewCheckpointCommand(dockerCli), |
|
| 76 |
+ plugin.NewPluginCommand(dockerCli), |
|
| 73 | 77 |
) |
| 74 | 78 |
|
| 75 |
- if dockerCli.HasExperimental() {
|
|
| 76 |
- cmd.AddCommand( |
|
| 77 |
- stack.NewStackCommand(dockerCli), |
|
| 78 |
- stack.NewTopLevelDeployCommand(dockerCli), |
|
| 79 |
- checkpoint.NewCheckpointCommand(dockerCli), |
|
| 80 |
- plugin.NewPluginCommand(dockerCli), |
|
| 81 |
- ) |
|
| 82 |
- } |
|
| 83 |
- |
|
| 84 | 79 |
} |
| 85 | 80 |
|
| 86 | 81 |
func hide(cmd *cobra.Command) *cobra.Command {
|
| ... | ... |
@@ -45,11 +45,10 @@ func NewStartCommand(dockerCli *command.DockerCli) *cobra.Command {
|
| 45 | 45 |
flags.BoolVarP(&opts.openStdin, "interactive", "i", false, "Attach container's STDIN") |
| 46 | 46 |
flags.StringVar(&opts.detachKeys, "detach-keys", "", "Override the key sequence for detaching a container") |
| 47 | 47 |
|
| 48 |
- if dockerCli.HasExperimental() {
|
|
| 49 |
- flags.StringVar(&opts.checkpoint, "checkpoint", "", "Restore from this checkpoint") |
|
| 50 |
- flags.StringVar(&opts.checkpointDir, "checkpoint-dir", "", "Use a custom checkpoint storage directory") |
|
| 51 |
- } |
|
| 52 |
- |
|
| 48 |
+ flags.StringVar(&opts.checkpoint, "checkpoint", "", "Restore from this checkpoint") |
|
| 49 |
+ flags.SetAnnotation("checkpoint", "experimental", nil)
|
|
| 50 |
+ flags.StringVar(&opts.checkpointDir, "checkpoint-dir", "", "Use a custom checkpoint storage directory") |
|
| 51 |
+ flags.SetAnnotation("checkpoint-dir", "experimental", nil)
|
|
| 53 | 52 |
return cmd |
| 54 | 53 |
} |
| 55 | 54 |
|
| ... | ... |
@@ -111,9 +111,8 @@ func NewBuildCommand(dockerCli *command.DockerCli) *cobra.Command {
|
| 111 | 111 |
|
| 112 | 112 |
command.AddTrustedFlags(flags, true) |
| 113 | 113 |
|
| 114 |
- if dockerCli.HasExperimental() {
|
|
| 115 |
- flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer") |
|
| 116 |
- } |
|
| 114 |
+ flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer") |
|
| 115 |
+ flags.SetAnnotation("squash", "experimental", nil)
|
|
| 117 | 116 |
|
| 118 | 117 |
return cmd |
| 119 | 118 |
} |
| ... | ... |
@@ -17,6 +17,7 @@ func NewPluginCommand(dockerCli *command.DockerCli) *cobra.Command {
|
| 17 | 17 |
Run: func(cmd *cobra.Command, args []string) {
|
| 18 | 18 |
fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) |
| 19 | 19 |
}, |
| 20 |
+ Tags: map[string]string{"experimental": ""},
|
|
| 20 | 21 |
} |
| 21 | 22 |
|
| 22 | 23 |
cmd.AddCommand( |
| ... | ... |
@@ -17,6 +17,7 @@ func NewStackCommand(dockerCli *command.DockerCli) *cobra.Command {
|
| 17 | 17 |
Run: func(cmd *cobra.Command, args []string) {
|
| 18 | 18 |
fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) |
| 19 | 19 |
}, |
| 20 |
+ Tags: map[string]string{"experimental": ""},
|
|
| 20 | 21 |
} |
| 21 | 22 |
cmd.AddCommand( |
| 22 | 23 |
newConfigCommand(dockerCli), |
| ... | ... |
@@ -33,7 +33,8 @@ func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
|
| 33 | 33 |
showVersion() |
| 34 | 34 |
return nil |
| 35 | 35 |
} |
| 36 |
- fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) |
|
| 36 |
+ cmd.SetOutput(dockerCli.Err()) |
|
| 37 |
+ cmd.HelpFunc()(cmd, args) |
|
| 37 | 38 |
return nil |
| 38 | 39 |
}, |
| 39 | 40 |
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
| ... | ... |
@@ -45,6 +46,22 @@ func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
|
| 45 | 45 |
} |
| 46 | 46 |
cli.SetupRootCommand(cmd) |
| 47 | 47 |
|
| 48 |
+ cmd.SetHelpFunc(func(ccmd *cobra.Command, args []string) {
|
|
| 49 |
+ var err error |
|
| 50 |
+ if dockerCli.Client() == nil {
|
|
| 51 |
+ // flags must be the top-level command flags, not cmd.Flags() |
|
| 52 |
+ opts.Common.SetDefaultOptions(flags) |
|
| 53 |
+ dockerPreRun(opts) |
|
| 54 |
+ err = dockerCli.Initialize(opts) |
|
| 55 |
+ } |
|
| 56 |
+ if err != nil || !dockerCli.HasExperimental() {
|
|
| 57 |
+ hideExperimentalFeatures(ccmd) |
|
| 58 |
+ } |
|
| 59 |
+ if err := ccmd.Help(); err != nil {
|
|
| 60 |
+ ccmd.Println(err) |
|
| 61 |
+ } |
|
| 62 |
+ }) |
|
| 63 |
+ |
|
| 48 | 64 |
flags = cmd.Flags() |
| 49 | 65 |
flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit") |
| 50 | 66 |
flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files") |
| ... | ... |
@@ -105,3 +122,19 @@ func dockerPreRun(opts *cliflags.ClientOptions) {
|
| 105 | 105 |
utils.EnableDebug() |
| 106 | 106 |
} |
| 107 | 107 |
} |
| 108 |
+ |
|
| 109 |
+func hideExperimentalFeatures(cmd *cobra.Command) {
|
|
| 110 |
+ // hide flags |
|
| 111 |
+ cmd.Flags().VisitAll(func(f *pflag.Flag) {
|
|
| 112 |
+ if _, ok := f.Annotations["experimental"]; ok {
|
|
| 113 |
+ f.Hidden = true |
|
| 114 |
+ } |
|
| 115 |
+ }) |
|
| 116 |
+ |
|
| 117 |
+ for _, subcmd := range cmd.Commands() {
|
|
| 118 |
+ // hide subcommands |
|
| 119 |
+ if _, ok := subcmd.Tags["experimental"]; ok {
|
|
| 120 |
+ subcmd.Hidden = true |
|
| 121 |
+ } |
|
| 122 |
+ } |
|
| 123 |
+} |
| ... | ... |
@@ -123,7 +123,7 @@ github.com/matttproud/golang_protobuf_extensions fc2b8d3a73c4867e51861bbdd5ae3c1 |
| 123 | 123 |
github.com/pkg/errors 01fa4104b9c248c8945d14d9f128454d5b28d595 |
| 124 | 124 |
|
| 125 | 125 |
# cli |
| 126 |
-github.com/spf13/cobra v1.4.1 https://github.com/dnephin/cobra.git |
|
| 126 |
+github.com/spf13/cobra v1.5 https://github.com/dnephin/cobra.git |
|
| 127 | 127 |
github.com/spf13/pflag dabebe21bf790f782ea4c7bbd2efc430de182afd |
| 128 | 128 |
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 |
| 129 | 129 |
github.com/flynn-archive/go-shlex 3f9db97f856818214da2e1057f8ad84803971cff |
| ... | ... |
@@ -59,6 +59,9 @@ type Command struct {
|
| 59 | 59 |
Deprecated string |
| 60 | 60 |
// Is this command hidden and should NOT show up in the list of available commands? |
| 61 | 61 |
Hidden bool |
| 62 |
+ // Tags are key/value pairs that can be used by applications to identify or |
|
| 63 |
+ // group commands |
|
| 64 |
+ Tags map[string]string |
|
| 62 | 65 |
// Full set of flags |
| 63 | 66 |
flags *flag.FlagSet |
| 64 | 67 |
// Set of flags childrens of this command will inherit |
| ... | ... |
@@ -111,10 +114,10 @@ type Command struct {
|
| 111 | 111 |
|
| 112 | 112 |
flagErrorBuf *bytes.Buffer |
| 113 | 113 |
|
| 114 |
- args []string // actual args parsed from flags |
|
| 115 |
- output *io.Writer // nil means stderr; use Out() method instead |
|
| 116 |
- usageFunc func(*Command) error // Usage can be defined by application |
|
| 117 |
- usageTemplate string // Can be defined by Application |
|
| 114 |
+ args []string // actual args parsed from flags |
|
| 115 |
+ output *io.Writer // nil means stderr; use Out() method instead |
|
| 116 |
+ usageFunc func(*Command) error // Usage can be defined by application |
|
| 117 |
+ usageTemplate string // Can be defined by Application |
|
| 118 | 118 |
flagErrorFunc func(*Command, error) error |
| 119 | 119 |
helpTemplate string // Can be defined by Application |
| 120 | 120 |
helpFunc func(*Command, []string) // Help can be defined by application |
| ... | ... |
@@ -417,7 +420,7 @@ func argsMinusFirstX(args []string, x string) []string {
|
| 417 | 417 |
|
| 418 | 418 |
func isFlagArg(arg string) bool {
|
| 419 | 419 |
return ((len(arg) >= 3 && arg[1] == '-') || |
| 420 |
- (len(arg) >= 2 && arg[0] == '-' && arg[1] != '-')) |
|
| 420 |
+ (len(arg) >= 2 && arg[0] == '-' && arg[1] != '-')) |
|
| 421 | 421 |
} |
| 422 | 422 |
|
| 423 | 423 |
// 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
|
| 820 | 820 |
// Commands returns a sorted slice of child commands. |
| 821 | 821 |
func (c *Command) Commands() []*Command {
|
| 822 | 822 |
// do not sort commands if it already sorted or sorting was disabled |
| 823 |
- if EnableCommandSorting && !c.commandsAreSorted{
|
|
| 823 |
+ if EnableCommandSorting && !c.commandsAreSorted {
|
|
| 824 | 824 |
sort.Sort(commandSorterByName(c.commands)) |
| 825 | 825 |
c.commandsAreSorted = true |
| 826 | 826 |
} |