Repository: spf13/cobra
File: custom_completions.go (Go)

Code before:
				doCompleteFlags(flag)
			})
		}

		directive := ShellCompDirectiveNoFileComp
		if len(completions) == 1 && strings.HasSuffix(completions[0], "=") {
			// If there is a single completion, the shell usually adds a space
			// after the completion.  We don't want that if the flag ends with an =
			directive = ShellCompDirectiveNoSpace
		}
		return finalCmd, completions, directive, nil
	}

	// We only remove the flags from the arguments if DisableFlagParsing is not set.
	// This is important for commands which have requested to do their own flag completion.
	if !finalCmd.DisableFlagParsing {
		finalArgs = finalCmd.Flags().Args()
	}

	var completions []string
	directive := ShellCompDirectiveDefault
	if flag == nil {
		foundLocalNonPersistentFlag := false
		// If TraverseChildren is true we dont check for local flags
		// because we can use a local flag on a parent command
		if !finalCmd.TraverseChildren {
			// Check if there are any local, non-persistent flags on the command-line
			localNonPersistentFlags := finalCmd.LocalNonPersistentFlags()
			finalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
				if localNonPersistentFlags.Lookup(flag.Name) != nil && flag.Changed {
					foundLocalNonPersistentFlag = true
				}
			})
		}

		// Complete subcommand names, including the help command
		if len(finalArgs) == 0 && !foundLocalNonPersistentFlag {
			// We only complete sub-commands if:
			// - there are no arguments on the command-line and
			// - there are no local, non-peristent flag on the command-line or TraverseChildren is true
			for _, subCmd := range finalCmd.Commands() {
				if subCmd.IsAvailableCommand() || subCmd == finalCmd.helpCommand {
					if strings.HasPrefix(subCmd.Name(), toComplete) {
						completions = append(completions, fmt.Sprintf("%s\t%s", subCmd.Name(), subCmd.Short))
					}
					directive = ShellCompDirectiveNoFileComp
				}
			}
		}

		// Complete required flags even without the '-' prefix

Review comment (suggestion):
From what I understand, for `TraverseChildren` to work (outside of completion), it *must* be set on the Root command.  This is because `TraverseChildren` is only considered here:
https://github.com/spf13/cobra/blob/19e41cf081df9bf9dde5cffa0090e718c3fdc8af/command.go#L922
and that line is *only* run on the root command.
I have confirmed by testing that setting `TraverseChildren` only on a sub-command will still cause an "unknow flag" error for local flags.

Therefore, we should only consider `TraverseChildren` for the root command, so it should probably be:
`if !finalCmd.Root().TraverseChildren {`


Code after:
			// We cannot use finalCmd.Flags() because we may not have called ParsedFlags() for commands
			// that have set DisableFlagParsing; it is ParseFlags() that merges the inherited and
			// non-inherited flags.
			finalCmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
				doCompleteFlags(flag)
			})
			finalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
				doCompleteFlags(flag)
			})
		}

		directive := ShellCompDirectiveNoFileComp
		if len(completions) == 1 && strings.HasSuffix(completions[0], "=") {
			// If there is a single completion, the shell usually adds a space
			// after the completion.  We don't want that if the flag ends with an =
			directive = ShellCompDirectiveNoSpace
		}
		return finalCmd, completions, directive, nil
	}

	// We only remove the flags from the arguments if DisableFlagParsing is not set.
	// This is important for commands which have requested to do their own flag completion.
	if !finalCmd.DisableFlagParsing {
		finalArgs = finalCmd.Flags().Args()
	}

	var completions []string
	directive := ShellCompDirectiveDefault
	if flag == nil {
		foundLocalNonPersistentFlag := false
		// If TraverseChildren is true on the root command we don't check for
		// local flags because we can use a local flag on a parent command
		if !finalCmd.Root().TraverseChildren {
			// Check if there are any local, non-persistent flags on the command-line
			localNonPersistentFlags := finalCmd.LocalNonPersistentFlags()
			finalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
				if localNonPersistentFlags.Lookup(flag.Name) != nil && flag.Changed {
					foundLocalNonPersistentFlag = true
				}
			})
		}

		// Complete subcommand names, including the help command
		if len(finalArgs) == 0 && !foundLocalNonPersistentFlag {
			// We only complete sub-commands if:
			// - there are no arguments on the command-line and
			// - there are no local, non-peristent flag on the command-line or TraverseChildren is true
			for _, subCmd := range finalCmd.Commands() {
				if subCmd.IsAvailableCommand() || subCmd == finalCmd.helpCommand {
					if strings.HasPrefix(subCmd.Name(), toComplete) {
						completions = append(completions, fmt.Sprintf("%s\t%s", subCmd.Name(), subCmd.Short))