mirror of
https://github.com/spf13/cobra
synced 2024-11-24 22:57:12 +00:00
Merge pull request #218 from mvdan/error-checking
Error checking for doc generation
This commit is contained in:
commit
a3a9f345ca
6 changed files with 112 additions and 75 deletions
|
@ -11,7 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var flagb1, flagb2, flagb3, flagbr, flagbp bool
|
var flagb1, flagb2, flagb3, flagbr, flagbp bool
|
||||||
var flags1, flags2a, flags2b, flags3, outs string
|
var flags1, flags2a, flags2b, flags3 string
|
||||||
var flagi1, flagi2, flagi3, flagir int
|
var flagi1, flagi2, flagi3, flagir int
|
||||||
|
|
||||||
const strtwoParentHelp = "help message for parent flag strtwo"
|
const strtwoParentHelp = "help message for parent flag strtwo"
|
||||||
|
|
|
@ -32,7 +32,7 @@ import (
|
||||||
// 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 GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) {
|
func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) error {
|
||||||
if header == nil {
|
if header == nil {
|
||||||
header = &GenManHeader{}
|
header = &GenManHeader{}
|
||||||
}
|
}
|
||||||
|
@ -40,31 +40,28 @@ func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) {
|
||||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
GenManTree(c, header, dir)
|
if err := GenManTree(c, header, dir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out := new(bytes.Buffer)
|
|
||||||
|
|
||||||
needToResetTitle := header.Title == ""
|
needToResetTitle := header.Title == ""
|
||||||
|
|
||||||
GenMan(cmd, header, out)
|
filename := cmd.CommandPath()
|
||||||
|
filename = dir + strings.Replace(filename, " ", "-", -1) + ".1"
|
||||||
|
f, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
if err := GenMan(cmd, header, f); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if needToResetTitle {
|
if needToResetTitle {
|
||||||
header.Title = ""
|
header.Title = ""
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
filename := cmd.CommandPath()
|
|
||||||
filename = dir + strings.Replace(filename, " ", "-", -1) + ".1"
|
|
||||||
outFile, err := os.Create(filename)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer outFile.Close()
|
|
||||||
_, err = outFile.Write(out.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenManHeader is a lot like the .TH header at the start of man pages. These
|
// GenManHeader is a lot like the .TH header at the start of man pages. These
|
||||||
|
@ -80,15 +77,16 @@ type GenManHeader struct {
|
||||||
Manual string
|
Manual string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenMan will generate a man page for the given command in the out buffer.
|
// GenMan will generate a man page for the given command and write it to
|
||||||
// The header argument may be nil, however obviously out may not.
|
// w. The header argument may be nil, however obviously w may not.
|
||||||
func GenMan(cmd *cobra.Command, header *GenManHeader, out io.Writer) {
|
func GenMan(cmd *cobra.Command, header *GenManHeader, w io.Writer) error {
|
||||||
if header == nil {
|
if header == nil {
|
||||||
header = &GenManHeader{}
|
header = &GenManHeader{}
|
||||||
}
|
}
|
||||||
buf := genMan(cmd, header)
|
b := genMan(cmd, header)
|
||||||
final := mangen.Render(buf)
|
final := mangen.Render(b)
|
||||||
out.Write(final)
|
_, err := w.Write(final)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func fillHeader(header *GenManHeader, name string) {
|
func fillHeader(header *GenManHeader, name string) {
|
||||||
|
|
|
@ -29,7 +29,9 @@ 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
|
||||||
GenMan(cmdEcho, header, out)
|
if err := GenMan(cmdEcho, header, out); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
found := out.String()
|
found := out.String()
|
||||||
|
|
||||||
// Make sure parent has - in CommandPath() in SEE ALSO:
|
// Make sure parent has - in CommandPath() in SEE ALSO:
|
||||||
|
@ -85,7 +87,9 @@ 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
|
||||||
GenMan(cmdEcho, header, out)
|
if err := GenMan(cmdEcho, header, out); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
found := out.String()
|
found := out.String()
|
||||||
|
|
||||||
unexpected := translate("#HISTORY")
|
unexpected := translate("#HISTORY")
|
||||||
|
|
117
doc/md_docs.go
117
doc/md_docs.go
|
@ -14,7 +14,6 @@
|
||||||
package doc
|
package doc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -25,29 +24,38 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
func printOptions(out io.Writer, cmd *cobra.Command, name string) {
|
func printOptions(w io.Writer, cmd *cobra.Command, name string) error {
|
||||||
flags := cmd.NonInheritedFlags()
|
flags := cmd.NonInheritedFlags()
|
||||||
flags.SetOutput(out)
|
flags.SetOutput(w)
|
||||||
if flags.HasFlags() {
|
if flags.HasFlags() {
|
||||||
fmt.Fprintf(out, "### Options\n\n```\n")
|
if _, err := fmt.Fprintf(w, "### Options\n\n```\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
flags.PrintDefaults()
|
flags.PrintDefaults()
|
||||||
fmt.Fprintf(out, "```\n\n")
|
if _, err := fmt.Fprintf(w, "```\n\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parentFlags := cmd.InheritedFlags()
|
parentFlags := cmd.InheritedFlags()
|
||||||
parentFlags.SetOutput(out)
|
parentFlags.SetOutput(w)
|
||||||
if parentFlags.HasFlags() {
|
if parentFlags.HasFlags() {
|
||||||
fmt.Fprintf(out, "### Options inherited from parent commands\n\n```\n")
|
if _, err := fmt.Fprintf(w, "### Options inherited from parent commands\n\n```\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
parentFlags.PrintDefaults()
|
parentFlags.PrintDefaults()
|
||||||
fmt.Fprintf(out, "```\n\n")
|
if _, err := fmt.Fprintf(w, "```\n\n"); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func GenMarkdown(cmd *cobra.Command, out io.Writer) {
|
func GenMarkdown(cmd *cobra.Command, w io.Writer) error {
|
||||||
GenMarkdownCustom(cmd, out, func(s string) string { return s })
|
return GenMarkdownCustom(cmd, w, func(s string) string { return s })
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenMarkdownCustom(cmd *cobra.Command, out io.Writer, linkHandler func(string) string) {
|
func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error {
|
||||||
name := cmd.CommandPath()
|
name := cmd.CommandPath()
|
||||||
|
|
||||||
short := cmd.Short
|
short := cmd.Short
|
||||||
|
@ -56,29 +64,49 @@ func GenMarkdownCustom(cmd *cobra.Command, out io.Writer, linkHandler func(strin
|
||||||
long = short
|
long = short
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(out, "## %s\n\n", name)
|
if _, err := fmt.Fprintf(w, "## %s\n\n", name); err != nil {
|
||||||
fmt.Fprintf(out, "%s\n\n", short)
|
return err
|
||||||
fmt.Fprintf(out, "### Synopsis\n\n")
|
}
|
||||||
fmt.Fprintf(out, "\n%s\n\n", long)
|
if _, err := fmt.Fprintf(w, "%s\n\n", short); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := fmt.Fprintf(w, "### Synopsis\n\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := fmt.Fprintf(w, "\n%s\n\n", long); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if cmd.Runnable() {
|
if cmd.Runnable() {
|
||||||
fmt.Fprintf(out, "```\n%s\n```\n\n", cmd.UseLine())
|
if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.UseLine()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cmd.Example) > 0 {
|
if len(cmd.Example) > 0 {
|
||||||
fmt.Fprintf(out, "### Examples\n\n")
|
if _, err := fmt.Fprintf(w, "### Examples\n\n"); err != nil {
|
||||||
fmt.Fprintf(out, "```\n%s\n```\n\n", cmd.Example)
|
return err
|
||||||
|
}
|
||||||
|
if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.Example); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printOptions(out, cmd, name)
|
if err := printOptions(w, cmd, name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if hasSeeAlso(cmd) {
|
if hasSeeAlso(cmd) {
|
||||||
fmt.Fprintf(out, "### SEE ALSO\n")
|
if _, err := fmt.Fprintf(w, "### SEE ALSO\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if cmd.HasParent() {
|
if cmd.HasParent() {
|
||||||
parent := cmd.Parent()
|
parent := cmd.Parent()
|
||||||
pname := parent.CommandPath()
|
pname := parent.CommandPath()
|
||||||
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)
|
if _, err := fmt.Fprintf(w, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
cmd.VisitParents(func(c *cobra.Command) {
|
cmd.VisitParents(func(c *cobra.Command) {
|
||||||
if c.DisableAutoGenTag {
|
if c.DisableAutoGenTag {
|
||||||
cmd.DisableAutoGenTag = c.DisableAutoGenTag
|
cmd.DisableAutoGenTag = c.DisableAutoGenTag
|
||||||
|
@ -96,48 +124,51 @@ func GenMarkdownCustom(cmd *cobra.Command, out io.Writer, linkHandler func(strin
|
||||||
cname := name + " " + child.Name()
|
cname := name + " " + child.Name()
|
||||||
link := cname + ".md"
|
link := cname + ".md"
|
||||||
link = strings.Replace(link, " ", "_", -1)
|
link = strings.Replace(link, " ", "_", -1)
|
||||||
fmt.Fprintf(out, "* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short)
|
if _, err := fmt.Fprintf(w, "* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err := fmt.Fprintf(w, "\n"); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "\n")
|
|
||||||
}
|
}
|
||||||
if !cmd.DisableAutoGenTag {
|
if !cmd.DisableAutoGenTag {
|
||||||
fmt.Fprintf(out, "###### Auto generated by spf13/cobra on %s\n", time.Now().Format("2-Jan-2006"))
|
if _, err := fmt.Fprintf(w, "###### Auto generated by spf13/cobra on %s\n", time.Now().Format("2-Jan-2006")); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func GenMarkdownTree(cmd *cobra.Command, dir string) {
|
func GenMarkdownTree(cmd *cobra.Command, dir string) error {
|
||||||
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 "" }
|
||||||
GenMarkdownTreeCustom(cmd, dir, emptyStr, identity)
|
return GenMarkdownTreeCustom(cmd, dir, emptyStr, identity)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender func(string) string, linkHandler func(string) string) {
|
func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error {
|
||||||
for _, c := range cmd.Commands() {
|
for _, c := range cmd.Commands() {
|
||||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler)
|
if err := GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out := new(bytes.Buffer)
|
|
||||||
|
|
||||||
GenMarkdownCustom(cmd, out, linkHandler)
|
|
||||||
|
|
||||||
filename := cmd.CommandPath()
|
filename := cmd.CommandPath()
|
||||||
filename = dir + strings.Replace(filename, " ", "_", -1) + ".md"
|
filename = dir + strings.Replace(filename, " ", "_", -1) + ".md"
|
||||||
outFile, err := os.Create(filename)
|
f, err := os.Create(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
return err
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
defer outFile.Close()
|
defer f.Close()
|
||||||
_, err = outFile.WriteString(filePrepender(filename))
|
|
||||||
if err != nil {
|
if _, err := io.WriteString(f, filePrepender(filename)); err != nil {
|
||||||
fmt.Println(err)
|
return err
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
_, err = outFile.Write(out.Bytes())
|
if err := GenMarkdownCustom(cmd, f, linkHandler); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,13 +39,13 @@ This will write the markdown doc for ONLY "cmd" into the out, buffer.
|
||||||
Both `GenMarkdown` and `GenMarkdownTree` have alternate versions with callbacks to get some control of the output:
|
Both `GenMarkdown` and `GenMarkdownTree` have alternate versions with callbacks to get some control of the output:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func GenMarkdownTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string) string) {
|
func GenMarkdownTreeCustom(cmd *Command, dir string, filePrepender, linkHandler func(string) string) error {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) {
|
func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) error {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -21,7 +21,9 @@ func TestGenMdDoc(t *testing.T) {
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
|
|
||||||
// We generate on s subcommand so we have both subcommands and parents
|
// We generate on s subcommand so we have both subcommands and parents
|
||||||
GenMarkdown(cmdEcho, out)
|
if err := GenMarkdown(cmdEcho, out); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
found := out.String()
|
found := out.String()
|
||||||
|
|
||||||
// Our description
|
// Our description
|
||||||
|
@ -75,7 +77,9 @@ func TestGenMdNoTag(t *testing.T) {
|
||||||
cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp)
|
cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp)
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
|
|
||||||
GenMarkdown(c, out)
|
if err := GenMarkdown(c, out); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
found := out.String()
|
found := out.String()
|
||||||
|
|
||||||
unexpected := "Auto generated"
|
unexpected := "Auto generated"
|
||||||
|
|
Loading…
Reference in a new issue