linkerd2/cli/cmd/doc.go

96 lines
2.0 KiB
Go

package cmd
import (
"bytes"
"fmt"
"io"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
"sigs.k8s.io/yaml"
)
type cmdOption struct {
Name string
Shorthand string `yaml:",omitempty"`
DefaultValue string `yaml:"default_value,omitempty"`
Usage string `yaml:",omitempty"`
}
type cmdDoc struct {
Name string
Synopsis string `yaml:",omitempty"`
Description string `yaml:",omitempty"`
Options []cmdOption `yaml:",omitempty"`
InheritedOptions []cmdOption `yaml:"inherited_options,omitempty"`
Example string `yaml:",omitempty"`
SeeAlso []string `yaml:"see_also,omitempty"`
}
func newCmdDoc() *cobra.Command {
cmd := &cobra.Command{
Use: "doc",
Hidden: true,
Short: "Generate YAML documentation for the Linkerd CLI",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cmdList, err := generateDocs(RootCmd)
if err != nil {
return err
}
out, err := yaml.Marshal(cmdList)
if err != nil {
return err
}
fmt.Println(string(out))
return nil
},
}
return cmd
}
// generateDocs takes a command and recursively walks the tree of commands,
// adding each as an item to cmdList.
func generateDocs(cmd *cobra.Command) ([]cmdDoc, error) {
var cmdList []cmdDoc
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
continue
}
subList, err := generateDocs(c)
if err != nil {
return nil, err
}
cmdList = append(cmdList, subList...)
}
var buf bytes.Buffer
if err := doc.GenYaml(cmd, io.Writer(&buf)); err != nil {
return nil, err
}
var doc cmdDoc
if err := yaml.Unmarshal(buf.Bytes(), &doc); err != nil {
return nil, err
}
// Cobra names start with linkerd, strip that off for the docs.
doc.Name = strings.TrimPrefix(doc.Name, "linkerd ")
// Don't include the root command.
if doc.Name != "linkerd" {
cmdList = append(cmdList, doc)
}
return cmdList, nil
}