Skip to content

fix: add HasHiddenParent() to skip hidden command subtrees in Walk()#2376

Open
dearchap wants to merge 3 commits into
urfave:mainfrom
dearchap:fix/2372-has-hidden-parent
Open

fix: add HasHiddenParent() to skip hidden command subtrees in Walk()#2376
dearchap wants to merge 3 commits into
urfave:mainfrom
dearchap:fix/2372-has-hidden-parent

Conversation

@dearchap

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • feature

What this PR does / why we need it:

When using Walk() to traverse the command tree, users who want to skip hidden commands currently check cmd.Hidden. However, the subcommands of a hidden command are not themselves hidden and still appear in the walk output. There is no way to check whether a command belongs to a hidden subtree without manually walking parent pointers, which are unexported.

This PR adds HasHiddenParent() bool to Command, which returns true if any ancestor has Hidden: true. Users can combine it with cmd.Hidden in their Walk callback to skip entire hidden subtrees:

cmd.Walk(func(c *cli.Command) error {
    if c.Hidden || c.HasHiddenParent() {
        return nil
    }
    // process visible commands only
})

Which issue(s) this PR fixes:

Fixes #2372

Testing

  • go test ./... passes
  • go vet ./... passes
  • make v3diff shows only the new HasHiddenParent method
  • make v3approve run to update API surface docs

Release Notes

Add Command.HasHiddenParent() method to help users skip subcommands of hidden commands during Walk().

Users can now check cmd.HasHiddenParent() in a Walk callback to
skip subcommands of hidden commands, solving the issue where
children of hidden commands were still visited.

Closes urfave#2372
@dearchap dearchap requested a review from a team as a code owner June 29, 2026 20:43
@abitrolly

Copy link
Copy Markdown
Contributor

Is it possible to add this to Walk examples?

@dearchap

dearchap commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

@abitrolly Added

Comment thread testdata/godoc-v3.x.txt
}
// process visible commands only
return nil
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If c.Hidden is set, then the function returns nil, the walk terminates, and c.HasHiddenParent is never reached, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dearchap so what's the point in having c.HasHiddenParent condition here? It could be that immediate parent is not hidden, but the grandfather is. Maybe c.AnyHiddenParent method would be better? If the logic is if any([c.Hidden for c in [c] + c.Parents]).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the implementation of HasHiddenParent. If any command in the chain has Hidden set it will return true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dearchap I feel like the better API would be to add a generic way to check some property in current and all parent commands. Otherwise there has to be a plenty of method for each property.

And also, how to check that only the parent command has hidden status? If I want to hide intermediate command, but make all its children visible? This HasHiddenParent method seems too specific as for me.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abitrolly do you have a design in mind ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cmd.Hidden is not recursive

2 participants