Skip to content

Commit

Permalink
Ensure inherited flags are captured in generate-docs
Browse files Browse the repository at this point in the history
Ensure that the inherited flags of each command being cloned for
remapping is captured in the command itself prior to the clone.
This enables the correct generation of the
'### Options inherited from parent commands'
section in the markdown file.

Signed-off-by: Vui Lam <vui.lam@broadcom.com>
  • Loading branch information
vuil committed May 1, 2024
1 parent 80c8993 commit d181bcb
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 12 deletions.
30 changes: 23 additions & 7 deletions plugin/generate_docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,33 @@ func mapCommand(tanzuCmd, subCommand *cobra.Command, mapEntry *CommandMapEntry)
}
}

func cloneCommand(sourceCommand *cobra.Command) *cobra.Command {
// TODO(vuil): before cloning the command, we need the inherited flags
// (persistent flags from command's ancestors) to be captured in the
// command because once the clone is remapped and has a different
// ancestry, some of the inherited flags may not be dynamically
// discoverable anymore. Somewhat dubiously, until there is a means to
// better dictate what a cobra Command's inherited flags are, we rely
// on the side-effect of InheritedFlags() to populate the discovered
// inherited flags in Command.iFlags
_ = sourceCommand.InheritedFlags()

clone := *sourceCommand
return &clone
}

func cloneChildCommands(parentCloneCmd *cobra.Command) {
childCommands := parentCloneCmd.Commands()
for _, child := range childCommands {
newChild := *child
cloneChildCommands(&newChild)
newChild := cloneCommand(child)

cloneChildCommands(newChild)
childParent := child.Parent()
// child's parent pointer is wrong (still point to childParent, the
// source that parentCloneCmd is cloned from), so remove said child
parentCloneCmd.RemoveCommand(child)
// and add the properly updated clone of child instead
parentCloneCmd.AddCommand(&newChild)
parentCloneCmd.AddCommand(newChild)
// however, the removal has the side-effect of wiping the child's
// parent link, so remove then re-add back as child of the clone source
childParent.RemoveCommand(child)
Expand All @@ -89,15 +105,15 @@ func cloneChildCommands(parentCloneCmd *cobra.Command) {
// generated for the clone (tanzu_xxx_help.md), something that is
// extraneous but not incorrect.
if child.Use == "help [command]" {
parentCloneCmd.SetHelpCommand(&newChild)
parentCloneCmd.SetHelpCommand(newChild)
}
}
}

func deepCopy(cmd *cobra.Command) *cobra.Command {
clone := *cmd
cloneChildCommands(&clone)
return &clone
clone := cloneCommand(cmd)
cloneChildCommands(clone)
return clone
}

// rebuildTanzuCommandTree reconstructs the tanzu CLI's placement of the
Expand Down
41 changes: 36 additions & 5 deletions plugin/generate_docs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ func genDocsTestPlugin(t *testing.T, mapEntries []CommandMapEntry, hiddenCommand

var value string
var bvalue string
var noColor bool
fooCmd.Flags().StringVarP(&value, "value", "v", "", "value to pass")
bazCmd.Flags().StringVarP(&bvalue, "bvalue", "b", "", "bvalue to pass")

Expand All @@ -155,6 +156,9 @@ func genDocsTestPlugin(t *testing.T, mapEntries []CommandMapEntry, hiddenCommand
cmd.Hidden = true
}

// for testing the effect of inherited flags
p.Cmd.PersistentFlags().BoolVar(&noColor, "n", false, "deactivate color, bold")

return p
}

Expand Down Expand Up @@ -294,13 +298,20 @@ func TestGenerateDocsWithPlugin(t *testing.T) {
},
},
"tanzu_foo.md": fileContent{
contains: []string{"foo command", "[tanzu](tanzu.md)"},
omits: []string{"tanzu plug foo"},
contains: []string{
"foo command",
"[tanzu](tanzu.md)",
// also check that inherited flags are captured
"### Options inherited from parent commands",
"deactivate color",
},
omits: []string{"tanzu plug foo"},
},
},
},
},
{
// includes check that global flags are fully propagated
test: "command and plugin level mapping",
commandMap: []CommandMapEntry{
{
Expand All @@ -320,15 +331,35 @@ func TestGenerateDocsWithPlugin(t *testing.T) {
contains: []string{"tanzu", "[tanzu pi](tanzu_pi.md)", "[tanzu foo](tanzu_foo.md)"},
},
"tanzu_pi.md": fileContent{
contains: []string{"[tanzu pi bar](tanzu_pi_bar.md)"},
contains: []string{
"[tanzu pi bar](tanzu_pi_bar.md)",
"deactivate color",
},
omits: []string{
"tanzu pi deeper",
"tanzu pi foo",
// this is the command where the nocolor persistent flag is
// defined, so flag is show in the regular options
// section, not under "Options inherited..."
"### Options inherited from parent commands",
},
},
"tanzu_pi_bar.md": fileContent{
contains: []string{
"[tanzu pi](tanzu_pi.md)",
"### Options inherited from parent commands",
"deactivate color",
},
},
"tanzu_foo.md": fileContent{
contains: []string{"foo command", "[tanzu](tanzu.md)"},
omits: []string{"tanzu pi foo"},
contains: []string{
"foo command",
"[tanzu](tanzu.md)",
"### Options inherited from parent commands",
"deactivate color"},
omits: []string{
"tanzu pi foo",
},
},
},
},
Expand Down

0 comments on commit d181bcb

Please sign in to comment.