@@ -163,8 +163,11 @@ func newDockerCommand(dockerCli *command.DockerCli) *cli.TopLevelCommand {
163163 cmd .SetOut (dockerCli .Out ())
164164 commands .AddCommands (cmd , dockerCli )
165165
166- cli .DisableFlagsInUseLine (cmd )
167- setValidateArgs (dockerCli , cmd )
166+ visitAll (cmd ,
167+ setValidateArgs (dockerCli ),
168+ // prevent adding "[flags]" to the end of the usage line.
169+ func (c * cobra.Command ) { c .DisableFlagsInUseLine = true },
170+ )
168171
169172 // flags must be the top-level command flags, not cmd.Flags()
170173 return cli .NewTopLevelCommand (cmd , dockerCli , opts , cmd .Flags ())
@@ -265,14 +268,29 @@ func setHelpFunc(dockerCli command.Cli, cmd *cobra.Command) {
265268 })
266269}
267270
268- func setValidateArgs (dockerCli command.Cli , cmd * cobra.Command ) {
269- // The Args is handled by ValidateArgs in cobra, which does not allows a pre-hook.
270- // As a result, here we replace the existing Args validation func to a wrapper,
271- // where the wrapper will check to see if the feature is supported or not.
272- // The Args validation error will only be returned if the feature is supported.
273- cli .VisitAll (cmd , func (ccmd * cobra.Command ) {
271+ // visitAll traverses all commands from the root.
272+ func visitAll (root * cobra.Command , fns ... func (* cobra.Command )) {
273+ for _ , cmd := range root .Commands () {
274+ visitAll (cmd , fns ... )
275+ }
276+ for _ , fn := range fns {
277+ fn (root )
278+ }
279+ }
280+
281+ // The Args is handled by ValidateArgs in cobra, which does not allows a pre-hook.
282+ // As a result, here we replace the existing Args validation func to a wrapper,
283+ // where the wrapper will check to see if the feature is supported or not.
284+ // The Args validation error will only be returned if the feature is supported.
285+ func setValidateArgs (dockerCLI versionDetails ) func (* cobra.Command ) {
286+ return func (ccmd * cobra.Command ) {
274287 // if there is no tags for a command or any of its parent,
275288 // there is no need to wrap the Args validation.
289+ //
290+ // FIXME(thaJeztah): can we memoize properties of the parent?
291+ // visitAll traverses root -> all childcommands, and hasTags
292+ // goes the reverse (cmd -> visit all parents), so we may
293+ // end traversing two directions.
276294 if ! hasTags (ccmd ) {
277295 return
278296 }
@@ -283,12 +301,12 @@ func setValidateArgs(dockerCli command.Cli, cmd *cobra.Command) {
283301
284302 cmdArgs := ccmd .Args
285303 ccmd .Args = func (cmd * cobra.Command , args []string ) error {
286- if err := isSupported (cmd , dockerCli ); err != nil {
304+ if err := isSupported (cmd , dockerCLI ); err != nil {
287305 return err
288306 }
289307 return cmdArgs (cmd , args )
290308 }
291- })
309+ }
292310}
293311
294312func tryPluginRun (ctx context.Context , dockerCli command.Cli , cmd * cobra.Command , subcommand string , envs []string ) error {
0 commit comments