mirror of
https://github.com/spf13/cobra
synced 2024-11-24 22:57:12 +00:00
Issue #195: Move doc generation into separate pkg
* Move man_docs and md_docs into new doc pkg * Replace *bytes.Buffer with io.Writer * Replace c == cmd.helpCommand with c.IsHelpCommand() * Remove redundant len(children) == 0 check in HasSeeAlso * Duplicate test setup for doc generation
This commit is contained in:
parent
b167d9beaa
commit
90aa777933
9 changed files with 203 additions and 81 deletions
145
doc/cmd_test.go
Normal file
145
doc/cmd_test.go
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
package doc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var flagb1, flagb2, flagb3, flagbr, flagbp bool
|
||||||
|
var flags1, flags2a, flags2b, flags3, outs string
|
||||||
|
var flagi1, flagi2, flagi3, flagir int
|
||||||
|
|
||||||
|
const strtwoParentHelp = "help message for parent flag strtwo"
|
||||||
|
const strtwoChildHelp = "help message for child flag strtwo"
|
||||||
|
|
||||||
|
var cmdEcho = &cobra.Command{
|
||||||
|
Use: "echo [string to echo]",
|
||||||
|
Aliases: []string{"say"},
|
||||||
|
Short: "Echo anything to the screen",
|
||||||
|
Long: `an utterly useless command for testing.`,
|
||||||
|
Example: "Just run cobra-test echo",
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdEchoSub = &cobra.Command{
|
||||||
|
Use: "echosub [string to print]",
|
||||||
|
Short: "second sub command for echo",
|
||||||
|
Long: `an absolutely utterly useless command for testing gendocs!.`,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {},
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdDeprecated = &cobra.Command{
|
||||||
|
Use: "deprecated [can't do anything here]",
|
||||||
|
Short: "A command which is deprecated",
|
||||||
|
Long: `an absolutely utterly useless command for testing deprecation!.`,
|
||||||
|
Deprecated: "Please use echo instead",
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdTimes = &cobra.Command{
|
||||||
|
Use: "times [# times] [string to echo]",
|
||||||
|
SuggestFor: []string{"counts"},
|
||||||
|
Short: "Echo anything to the screen more times",
|
||||||
|
Long: `a slightly useless command for testing.`,
|
||||||
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {},
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdPrint = &cobra.Command{
|
||||||
|
Use: "print [string to print]",
|
||||||
|
Short: "Print anything to the screen",
|
||||||
|
Long: `an absolutely utterly useless command for testing.`,
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdRootNoRun = &cobra.Command{
|
||||||
|
Use: "cobra-test",
|
||||||
|
Short: "The root can run its own function",
|
||||||
|
Long: "The root description for help",
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdRootSameName = &cobra.Command{
|
||||||
|
Use: "print",
|
||||||
|
Short: "Root with the same name as a subcommand",
|
||||||
|
Long: "The root description for help",
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdRootWithRun = &cobra.Command{
|
||||||
|
Use: "cobra-test",
|
||||||
|
Short: "The root can run its own function",
|
||||||
|
Long: "The root description for help",
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdSubNoRun = &cobra.Command{
|
||||||
|
Use: "subnorun",
|
||||||
|
Short: "A subcommand without a Run function",
|
||||||
|
Long: "A long output about a subcommand without a Run function",
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdVersion1 = &cobra.Command{
|
||||||
|
Use: "version",
|
||||||
|
Short: "Print the version number",
|
||||||
|
Long: `First version of the version command`,
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdVersion2 = &cobra.Command{
|
||||||
|
Use: "version",
|
||||||
|
Short: "Print the version number",
|
||||||
|
Long: `Second version of the version command`,
|
||||||
|
}
|
||||||
|
|
||||||
|
func flagInit() {
|
||||||
|
cmdEcho.ResetFlags()
|
||||||
|
cmdPrint.ResetFlags()
|
||||||
|
cmdTimes.ResetFlags()
|
||||||
|
cmdRootNoRun.ResetFlags()
|
||||||
|
cmdRootSameName.ResetFlags()
|
||||||
|
cmdRootWithRun.ResetFlags()
|
||||||
|
cmdSubNoRun.ResetFlags()
|
||||||
|
cmdRootNoRun.PersistentFlags().StringVarP(&flags2a, "strtwo", "t", "two", strtwoParentHelp)
|
||||||
|
cmdEcho.Flags().IntVarP(&flagi1, "intone", "i", 123, "help message for flag intone")
|
||||||
|
cmdTimes.Flags().IntVarP(&flagi2, "inttwo", "j", 234, "help message for flag inttwo")
|
||||||
|
cmdPrint.Flags().IntVarP(&flagi3, "intthree", "i", 345, "help message for flag intthree")
|
||||||
|
cmdEcho.PersistentFlags().StringVarP(&flags1, "strone", "s", "one", "help message for flag strone")
|
||||||
|
cmdEcho.PersistentFlags().BoolVarP(&flagbp, "persistentbool", "p", false, "help message for flag persistentbool")
|
||||||
|
cmdTimes.PersistentFlags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp)
|
||||||
|
cmdPrint.PersistentFlags().StringVarP(&flags3, "strthree", "s", "three", "help message for flag strthree")
|
||||||
|
cmdEcho.Flags().BoolVarP(&flagb1, "boolone", "b", true, "help message for flag boolone")
|
||||||
|
cmdTimes.Flags().BoolVarP(&flagb2, "booltwo", "c", false, "help message for flag booltwo")
|
||||||
|
cmdPrint.Flags().BoolVarP(&flagb3, "boolthree", "b", true, "help message for flag boolthree")
|
||||||
|
cmdVersion1.ResetFlags()
|
||||||
|
cmdVersion2.ResetFlags()
|
||||||
|
}
|
||||||
|
|
||||||
|
func initializeWithRootCmd() *cobra.Command {
|
||||||
|
cmdRootWithRun.ResetCommands()
|
||||||
|
flagInit()
|
||||||
|
cmdRootWithRun.Flags().BoolVarP(&flagbr, "boolroot", "b", false, "help message for flag boolroot")
|
||||||
|
cmdRootWithRun.Flags().IntVarP(&flagir, "introot", "i", 321, "help message for flag introot")
|
||||||
|
return cmdRootWithRun
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkStringContains(t *testing.T, found, expected string) {
|
||||||
|
if !strings.Contains(found, expected) {
|
||||||
|
logErr(t, found, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkStringOmits(t *testing.T, found, expected string) {
|
||||||
|
if strings.Contains(found, expected) {
|
||||||
|
logErr(t, found, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func logErr(t *testing.T, found, expected string) {
|
||||||
|
out := new(bytes.Buffer)
|
||||||
|
|
||||||
|
_, _, line, ok := runtime.Caller(2)
|
||||||
|
if ok {
|
||||||
|
fmt.Fprintf(out, "Line: %d ", line)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, "Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
|
||||||
|
t.Errorf(out.String())
|
||||||
|
}
|
|
@ -11,36 +11,33 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package cobra
|
package doc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
mangen "github.com/cpuguy83/go-md2man/md2man"
|
mangen "github.com/cpuguy83/go-md2man/md2man"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenManTree will call cmd.GenManTree(header, dir)
|
|
||||||
func GenManTree(cmd *Command, header *GenManHeader, dir string) {
|
|
||||||
cmd.GenManTree(header, dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenManTree will generate a man page for this command and all decendants
|
// GenManTree will generate a man page for this command and all decendants
|
||||||
// in the directory given. The header may be nil. This function may not work
|
// in the directory given. The header may be nil. This function may not work
|
||||||
// correctly if your command names have - in them. If you have `cmd` with two
|
// correctly if your command names have - in them. If you have `cmd` with two
|
||||||
// subcmds, `sub` and `sub-third`. And `sub` has a subcommand called `third`
|
// subcmds, `sub` and `sub-third`. And `sub` has a subcommand called `third`
|
||||||
// it is undefined which help output will be in the file `cmd-sub-third.1`.
|
// it is undefined which help output will be in the file `cmd-sub-third.1`.
|
||||||
func (cmd *Command) GenManTree(header *GenManHeader, dir string) {
|
func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) {
|
||||||
if header == nil {
|
if header == nil {
|
||||||
header = &GenManHeader{}
|
header = &GenManHeader{}
|
||||||
}
|
}
|
||||||
for _, c := range cmd.Commands() {
|
for _, c := range cmd.Commands() {
|
||||||
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
GenManTree(c, header, dir)
|
GenManTree(c, header, dir)
|
||||||
|
@ -49,7 +46,7 @@ func (cmd *Command) GenManTree(header *GenManHeader, dir string) {
|
||||||
|
|
||||||
needToResetTitle := header.Title == ""
|
needToResetTitle := header.Title == ""
|
||||||
|
|
||||||
cmd.GenMan(header, out)
|
GenMan(cmd, header, out)
|
||||||
|
|
||||||
if needToResetTitle {
|
if needToResetTitle {
|
||||||
header.Title = ""
|
header.Title = ""
|
||||||
|
@ -83,18 +80,13 @@ type GenManHeader struct {
|
||||||
Manual string
|
Manual string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenMan will call cmd.GenMan(header, out)
|
|
||||||
func GenMan(cmd *Command, header *GenManHeader, out *bytes.Buffer) {
|
|
||||||
cmd.GenMan(header, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenMan will generate a man page for the given command in the out buffer.
|
// GenMan will generate a man page for the given command in the out buffer.
|
||||||
// The header argument may be nil, however obviously out may not.
|
// The header argument may be nil, however obviously out may not.
|
||||||
func (cmd *Command) GenMan(header *GenManHeader, out *bytes.Buffer) {
|
func GenMan(cmd *cobra.Command, header *GenManHeader, out io.Writer) {
|
||||||
if header == nil {
|
if header == nil {
|
||||||
header = &GenManHeader{}
|
header = &GenManHeader{}
|
||||||
}
|
}
|
||||||
buf := genMarkdown(cmd, header)
|
buf := genMan(cmd, header)
|
||||||
final := mangen.Render(buf)
|
final := mangen.Render(buf)
|
||||||
out.Write(final)
|
out.Write(final)
|
||||||
}
|
}
|
||||||
|
@ -116,7 +108,7 @@ func fillHeader(header *GenManHeader, name string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func manPreamble(out *bytes.Buffer, header *GenManHeader, name, short, long string) {
|
func manPreamble(out io.Writer, header *GenManHeader, name, short, long string) {
|
||||||
dashName := strings.Replace(name, " ", "-", -1)
|
dashName := strings.Replace(name, " ", "-", -1)
|
||||||
fmt.Fprintf(out, `%% %s(%s)%s
|
fmt.Fprintf(out, `%% %s(%s)%s
|
||||||
%% %s
|
%% %s
|
||||||
|
@ -130,7 +122,7 @@ func manPreamble(out *bytes.Buffer, header *GenManHeader, name, short, long stri
|
||||||
fmt.Fprintf(out, "%s\n\n", long)
|
fmt.Fprintf(out, "%s\n\n", long)
|
||||||
}
|
}
|
||||||
|
|
||||||
func manPrintFlags(out *bytes.Buffer, flags *pflag.FlagSet) {
|
func manPrintFlags(out io.Writer, flags *pflag.FlagSet) {
|
||||||
flags.VisitAll(func(flag *pflag.Flag) {
|
flags.VisitAll(func(flag *pflag.Flag) {
|
||||||
if len(flag.Deprecated) > 0 || flag.Hidden {
|
if len(flag.Deprecated) > 0 || flag.Hidden {
|
||||||
return
|
return
|
||||||
|
@ -158,7 +150,7 @@ func manPrintFlags(out *bytes.Buffer, flags *pflag.FlagSet) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func manPrintOptions(out *bytes.Buffer, command *Command) {
|
func manPrintOptions(out io.Writer, command *cobra.Command) {
|
||||||
flags := command.NonInheritedFlags()
|
flags := command.NonInheritedFlags()
|
||||||
if flags.HasFlags() {
|
if flags.HasFlags() {
|
||||||
fmt.Fprintf(out, "# OPTIONS\n")
|
fmt.Fprintf(out, "# OPTIONS\n")
|
||||||
|
@ -173,7 +165,7 @@ func manPrintOptions(out *bytes.Buffer, command *Command) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func genMarkdown(cmd *Command, header *GenManHeader) []byte {
|
func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
|
||||||
// something like `rootcmd subcmd1 subcmd2`
|
// something like `rootcmd subcmd1 subcmd2`
|
||||||
commandName := cmd.CommandPath()
|
commandName := cmd.CommandPath()
|
||||||
// something like `rootcmd-subcmd1-subcmd2`
|
// something like `rootcmd-subcmd1-subcmd2`
|
||||||
|
@ -195,13 +187,13 @@ func genMarkdown(cmd *Command, header *GenManHeader) []byte {
|
||||||
fmt.Fprintf(buf, "# EXAMPLE\n")
|
fmt.Fprintf(buf, "# EXAMPLE\n")
|
||||||
fmt.Fprintf(buf, "```\n%s\n```\n", cmd.Example)
|
fmt.Fprintf(buf, "```\n%s\n```\n", cmd.Example)
|
||||||
}
|
}
|
||||||
if cmd.hasSeeAlso() {
|
if hasSeeAlso(cmd) {
|
||||||
fmt.Fprintf(buf, "# SEE ALSO\n")
|
fmt.Fprintf(buf, "# SEE ALSO\n")
|
||||||
if cmd.HasParent() {
|
if cmd.HasParent() {
|
||||||
parentPath := cmd.Parent().CommandPath()
|
parentPath := cmd.Parent().CommandPath()
|
||||||
dashParentPath := strings.Replace(parentPath, " ", "-", -1)
|
dashParentPath := strings.Replace(parentPath, " ", "-", -1)
|
||||||
fmt.Fprintf(buf, "**%s(%s)**", dashParentPath, header.Section)
|
fmt.Fprintf(buf, "**%s(%s)**", dashParentPath, header.Section)
|
||||||
cmd.VisitParents(func(c *Command) {
|
cmd.VisitParents(func(c *cobra.Command) {
|
||||||
if c.DisableAutoGenTag {
|
if c.DisableAutoGenTag {
|
||||||
cmd.DisableAutoGenTag = c.DisableAutoGenTag
|
cmd.DisableAutoGenTag = c.DisableAutoGenTag
|
||||||
}
|
}
|
||||||
|
@ -210,7 +202,7 @@ func genMarkdown(cmd *Command, header *GenManHeader) []byte {
|
||||||
children := cmd.Commands()
|
children := cmd.Commands()
|
||||||
sort.Sort(byName(children))
|
sort.Sort(byName(children))
|
||||||
for i, c := range children {
|
for i, c := range children {
|
||||||
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if cmd.HasParent() || i > 0 {
|
if cmd.HasParent() || i > 0 {
|
|
@ -1,4 +1,4 @@
|
||||||
package cobra
|
package doc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -29,7 +29,7 @@ func TestGenManDoc(t *testing.T) {
|
||||||
Section: "2",
|
Section: "2",
|
||||||
}
|
}
|
||||||
// We generate on a subcommand so we have both subcommands and parents
|
// We generate on a subcommand so we have both subcommands and parents
|
||||||
cmdEcho.GenMan(header, out)
|
GenMan(cmdEcho, header, out)
|
||||||
found := out.String()
|
found := out.String()
|
||||||
|
|
||||||
// Make sure parent has - in CommandPath() in SEE ALSO:
|
// Make sure parent has - in CommandPath() in SEE ALSO:
|
||||||
|
@ -72,7 +72,6 @@ func TestGenManDoc(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenManNoGenTag(t *testing.T) {
|
func TestGenManNoGenTag(t *testing.T) {
|
||||||
|
|
||||||
c := initializeWithRootCmd()
|
c := initializeWithRootCmd()
|
||||||
// Need two commands to run the command alphabetical sort
|
// Need two commands to run the command alphabetical sort
|
||||||
cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated)
|
cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated)
|
||||||
|
@ -86,7 +85,7 @@ func TestGenManNoGenTag(t *testing.T) {
|
||||||
Section: "2",
|
Section: "2",
|
||||||
}
|
}
|
||||||
// We generate on a subcommand so we have both subcommands and parents
|
// We generate on a subcommand so we have both subcommands and parents
|
||||||
cmdEcho.GenMan(header, out)
|
GenMan(cmdEcho, header, out)
|
||||||
found := out.String()
|
found := out.String()
|
||||||
|
|
||||||
unexpected := translate("#HISTORY")
|
unexpected := translate("#HISTORY")
|
|
@ -1,10 +1,11 @@
|
||||||
package cobra_test
|
package doc_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/cobra/doc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleCommand_GenManTree() {
|
func ExampleCommand_GenManTree() {
|
||||||
|
@ -12,11 +13,11 @@ func ExampleCommand_GenManTree() {
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Short: "my test program",
|
Short: "my test program",
|
||||||
}
|
}
|
||||||
header := &cobra.GenManHeader{
|
header := &doc.GenManHeader{
|
||||||
Title: "MINE",
|
Title: "MINE",
|
||||||
Section: "3",
|
Section: "3",
|
||||||
}
|
}
|
||||||
cmd.GenManTree(header, "/tmp")
|
doc.GenManTree(cmd, header, "/tmp")
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleCommand_GenMan() {
|
func ExampleCommand_GenMan() {
|
||||||
|
@ -24,11 +25,11 @@ func ExampleCommand_GenMan() {
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Short: "my test program",
|
Short: "my test program",
|
||||||
}
|
}
|
||||||
header := &cobra.GenManHeader{
|
header := &doc.GenManHeader{
|
||||||
Title: "MINE",
|
Title: "MINE",
|
||||||
Section: "3",
|
Section: "3",
|
||||||
}
|
}
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
cmd.GenMan(header, out)
|
doc.GenMan(cmd, header, out)
|
||||||
fmt.Print(out.String())
|
fmt.Print(out.String())
|
||||||
}
|
}
|
|
@ -11,18 +11,21 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package cobra
|
package doc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
func printOptions(out *bytes.Buffer, cmd *Command, name string) {
|
func printOptions(out io.Writer, cmd *cobra.Command, name string) {
|
||||||
flags := cmd.NonInheritedFlags()
|
flags := cmd.NonInheritedFlags()
|
||||||
flags.SetOutput(out)
|
flags.SetOutput(out)
|
||||||
if flags.HasFlags() {
|
if flags.HasFlags() {
|
||||||
|
@ -40,25 +43,11 @@ func printOptions(out *bytes.Buffer, cmd *Command, name string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type byName []*Command
|
func GenMarkdown(cmd *cobra.Command, out io.Writer) {
|
||||||
|
GenMarkdownCustom(cmd, out, func(s string) string { return s })
|
||||||
func (s byName) Len() int { return len(s) }
|
|
||||||
func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
||||||
func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
|
|
||||||
|
|
||||||
func GenMarkdown(cmd *Command, out *bytes.Buffer) {
|
|
||||||
cmd.GenMarkdown(out)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *Command) GenMarkdown(out *bytes.Buffer) {
|
func GenMarkdownCustom(cmd *cobra.Command, out io.Writer, linkHandler func(string) string) {
|
||||||
cmd.GenMarkdownCustom(out, func(s string) string { return s })
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) {
|
|
||||||
cmd.GenMarkdownCustom(out, linkHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cmd *Command) GenMarkdownCustom(out *bytes.Buffer, linkHandler func(string) string) {
|
|
||||||
name := cmd.CommandPath()
|
name := cmd.CommandPath()
|
||||||
|
|
||||||
short := cmd.Short
|
short := cmd.Short
|
||||||
|
@ -82,7 +71,7 @@ func (cmd *Command) GenMarkdownCustom(out *bytes.Buffer, linkHandler func(string
|
||||||
}
|
}
|
||||||
|
|
||||||
printOptions(out, cmd, name)
|
printOptions(out, cmd, name)
|
||||||
if cmd.hasSeeAlso() {
|
if hasSeeAlso(cmd) {
|
||||||
fmt.Fprintf(out, "### SEE ALSO\n")
|
fmt.Fprintf(out, "### SEE ALSO\n")
|
||||||
if cmd.HasParent() {
|
if cmd.HasParent() {
|
||||||
parent := cmd.Parent()
|
parent := cmd.Parent()
|
||||||
|
@ -90,7 +79,7 @@ func (cmd *Command) GenMarkdownCustom(out *bytes.Buffer, linkHandler func(string
|
||||||
link := pname + ".md"
|
link := pname + ".md"
|
||||||
link = strings.Replace(link, " ", "_", -1)
|
link = strings.Replace(link, " ", "_", -1)
|
||||||
fmt.Fprintf(out, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short)
|
fmt.Fprintf(out, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short)
|
||||||
cmd.VisitParents(func(c *Command) {
|
cmd.VisitParents(func(c *cobra.Command) {
|
||||||
if c.DisableAutoGenTag {
|
if c.DisableAutoGenTag {
|
||||||
cmd.DisableAutoGenTag = c.DisableAutoGenTag
|
cmd.DisableAutoGenTag = c.DisableAutoGenTag
|
||||||
}
|
}
|
||||||
|
@ -101,7 +90,7 @@ func (cmd *Command) GenMarkdownCustom(out *bytes.Buffer, linkHandler func(string
|
||||||
sort.Sort(byName(children))
|
sort.Sort(byName(children))
|
||||||
|
|
||||||
for _, child := range children {
|
for _, child := range children {
|
||||||
if !child.IsAvailableCommand() || child == cmd.helpCommand {
|
if !child.IsAvailableCommand() || child.IsHelpCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cname := name + " " + child.Name()
|
cname := name + " " + child.Name()
|
||||||
|
@ -116,30 +105,22 @@ func (cmd *Command) GenMarkdownCustom(out *bytes.Buffer, linkHandler func(string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenMarkdownTree(cmd *Command, dir string) {
|
func GenMarkdownTree(cmd *cobra.Command, dir string) {
|
||||||
cmd.GenMarkdownTree(dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cmd *Command) GenMarkdownTree(dir string) {
|
|
||||||
identity := func(s string) string { return s }
|
identity := func(s string) string { return s }
|
||||||
emptyStr := func(s string) string { return "" }
|
emptyStr := func(s string) string { return "" }
|
||||||
cmd.GenMarkdownTreeCustom(dir, emptyStr, identity)
|
GenMarkdownTreeCustom(cmd, dir, emptyStr, identity)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenMarkdownTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string) string) {
|
func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender func(string) string, linkHandler func(string) string) {
|
||||||
cmd.GenMarkdownTreeCustom(dir, filePrepender, linkHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cmd *Command) GenMarkdownTreeCustom(dir string, filePrepender func(string) string, linkHandler func(string) string) {
|
|
||||||
for _, c := range cmd.Commands() {
|
for _, c := range cmd.Commands() {
|
||||||
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
c.GenMarkdownTreeCustom(dir, filePrepender, linkHandler)
|
GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler)
|
||||||
}
|
}
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
|
|
||||||
cmd.GenMarkdownCustom(out, linkHandler)
|
GenMarkdownCustom(cmd, out, linkHandler)
|
||||||
|
|
||||||
filename := cmd.CommandPath()
|
filename := cmd.CommandPath()
|
||||||
filename = dir + strings.Replace(filename, " ", "_", -1) + ".md"
|
filename = dir + strings.Replace(filename, " ", "_", -1) + ".md"
|
|
@ -12,12 +12,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
kubectl := cmd.NewFactory(nil).NewKubectlCommand(os.Stdin, ioutil.Discard, ioutil.Discard)
|
kubectl := cmd.NewFactory(nil).NewKubectlCommand(os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||||
cobra.GenMarkdownTree(kubectl, "./")
|
doc.GenMarkdownTree(kubectl, "./")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ You may wish to have more control over the output, or only generate for a single
|
||||||
|
|
||||||
```go
|
```go
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
cobra.GenMarkdown(cmd, out)
|
doc.GenMarkdown(cmd, out)
|
||||||
```
|
```
|
||||||
|
|
||||||
This will write the markdown doc for ONLY "cmd" into the out, buffer.
|
This will write the markdown doc for ONLY "cmd" into the out, buffer.
|
||||||
|
@ -78,4 +78,4 @@ linkHandler := func(name string) string {
|
||||||
return "/commands/" + strings.ToLower(base) + "/"
|
return "/commands/" + strings.ToLower(base) + "/"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cobra
|
package doc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
|
@ -11,24 +11,28 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package cobra
|
package doc
|
||||||
|
|
||||||
|
import "github.com/spf13/cobra"
|
||||||
|
|
||||||
// Test to see if we have a reason to print See Also information in docs
|
// Test to see if we have a reason to print See Also information in docs
|
||||||
// Basically this is a test for a parent commend or a subcommand which is
|
// Basically this is a test for a parent commend or a subcommand which is
|
||||||
// both not deprecated and not the autogenerated help command.
|
// both not deprecated and not the autogenerated help command.
|
||||||
func (cmd *Command) hasSeeAlso() bool {
|
func hasSeeAlso(cmd *cobra.Command) bool {
|
||||||
if cmd.HasParent() {
|
if cmd.HasParent() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
children := cmd.Commands()
|
for _, c := range cmd.Commands() {
|
||||||
if len(children) == 0 {
|
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, c := range children {
|
|
||||||
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type byName []*cobra.Command
|
||||||
|
|
||||||
|
func (s byName) Len() int { return len(s) }
|
||||||
|
func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
|
Loading…
Reference in a new issue