cobra icon indicating copy to clipboard operation
cobra copied to clipboard

Detecting and handling commands with uses / names that conflict with existing commands

Open andyfeller opened this issue 5 months ago • 2 comments

Long time supporter, first time caller! 👋 Wanted to solicit maintainers' insights into how users avoid conflicting commands. I appreciate any guidance offered! ❤

Problem

As of v1.8.1, Command.AddCommand(cmds ...*Command) does not handle situations where a command added might conflict with the Use / Name of a previously added command, creating situations where commands can be overridden.

https://github.com/spf13/cobra/blob/e94f6d0dd9a5e5738dca6bce03c4b1207ffbc0ec/command.go#L1305-L1332

At first glance, it seems Command.Traverse(args []string) could be used to detect whether a command by name was previously added, however this searches too deeply.

https://github.com/spf13/cobra/blob/e94f6d0dd9a5e5738dca6bce03c4b1207ffbc0ec/command.go#L790-L831

This issue is aimed to understand how spf13/cobra expects multiple commands with overlap to behave, seeing if there are additional capabilities worth considering.

Background

The GitHub CLI has a static set of core commands we support while facilitating users being able to install and use extensions built by the community. These extensions are not specially namespaced, so it is possible for someone to create an extension as the same name of the core commandset to override them during execution.

https://github.com/cli/cli/blob/192f57ef429b4e89937c87dcbd330520730d4a3a/pkg/cmd/root/root.go#L172-L177

In this situation, a workaround would be iterating over the top-level commands looking for conflicting names:

	// Extensions
	em := f.ExtensionManager
	for _, e := range em.List() {
		var childCmd *cobra.Command
		for _, cc := range cmd.Commands() {
			if cc.Name() == e.Name() {
				childCmd = cc
				break
			}
		}
		if childCmd != nil {
			return nil, fmt.Errorf("cannot add extension %s as command by that name exists", e.Name())
		}
		extensionCmd := NewCmdExtension(io, em, e)
		cmd.AddCommand(extensionCmd)
	}

andyfeller avatar Aug 29 '24 20:08 andyfeller