Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,18 @@ func (cmd *Command) Path() []string {
return []string{cmd.Name}
}

// HasHiddenParent returns true if any ancestor of this command has
// Hidden set to true.
func (cmd *Command) HasHiddenParent() bool {
if cmd.parent == nil {
return false
}
if cmd.parent.Hidden {
return true
}
return cmd.parent.HasHiddenParent()
}

// Walk visits cmd and every descendant. If fn returns a non-nil error, the
// walk terminates and the error is returned to the caller.
func (cmd *Command) Walk(fn func(*Command) error) error {
Expand Down
53 changes: 53 additions & 0 deletions command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6450,3 +6450,56 @@ func TestCommand_Walk_NilFn(t *testing.T) {
cmd := &Command{Name: "foo"}
assert.Nil(t, cmd.Walk(nil))
}

func TestCommand_HasHiddenParent(t *testing.T) {
t.Run("root command", func(t *testing.T) {
cmd := &Command{Name: "root"}
assert.False(t, cmd.HasHiddenParent())
})

t.Run("direct hidden parent", func(t *testing.T) {
parent := &Command{Name: "parent", Hidden: true}
child := &Command{Name: "child"}
child.parent = parent
assert.True(t, child.HasHiddenParent())
})

t.Run("non-hidden parent", func(t *testing.T) {
parent := &Command{Name: "parent"}
child := &Command{Name: "child"}
child.parent = parent
assert.False(t, child.HasHiddenParent())
})

t.Run("grandparent is hidden", func(t *testing.T) {
grandparent := &Command{Name: "grandparent", Hidden: true}
parent := &Command{Name: "parent"}
child := &Command{Name: "child"}
parent.parent = grandparent
child.parent = parent
assert.True(t, child.HasHiddenParent())
})

t.Run("subcommands of hidden command are skipped in walk", func(t *testing.T) {
hiddenCmd := &Command{Name: "completion", Hidden: true}
subCmd := &Command{Name: "bash"}
subCmd.parent = hiddenCmd
hiddenCmd.Commands = []*Command{subCmd}

root := &Command{
Name: "root",
Commands: []*Command{hiddenCmd},
}

var visited []string
err := root.Walk(func(c *Command) error {
if c.Hidden || c.HasHiddenParent() {
return nil
}
visited = append(visited, c.Name)
return nil
})
require.NoError(t, err)
assert.Equal(t, []string{"root"}, visited)
})
}
4 changes: 4 additions & 0 deletions godoc-current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,10 @@ func (cmd *Command) FullName() string
func (cmd *Command) Generic(name string) Value
Generic looks up the value of a local GenericFlag, returns nil if not found

func (cmd *Command) HasHiddenParent() bool
HasHiddenParent returns true if any ancestor of this command has Hidden set
to true.

func (cmd *Command) HasName(name string) bool
HasName returns true if Command.Name matches given name

Expand Down
4 changes: 4 additions & 0 deletions testdata/godoc-v3.x.txt
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,10 @@ func (cmd *Command) FullName() string
func (cmd *Command) Generic(name string) Value
Generic looks up the value of a local GenericFlag, returns nil if not found

func (cmd *Command) HasHiddenParent() bool
HasHiddenParent returns true if any ancestor of this command has Hidden set
to true.

func (cmd *Command) HasName(name string) bool
HasName returns true if Command.Name matches given name

Expand Down