github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/doc/doc.go (about)

     1  package doc
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  	"sort"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/spf13/cobra"
    14  )
    15  
    16  // GenMarkdownTreeCustom is the the same as GenMarkdownTree, but
    17  // with custom filePrepender and linkHandler.
    18  func GenMarkdownTreeCustom(c *cobra.Command, dir string, name string, path string, filePrepender func(string) string,
    19  	linkHandler func(*cobra.Command, string) string) (err error) {
    20  	for _, child := range c.Commands() {
    21  		if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() {
    22  			continue
    23  		}
    24  		if err = GenMarkdownTreeCustom(child, dir, name, path, filePrepender, linkHandler); err != nil {
    25  			return err
    26  		}
    27  	}
    28  
    29  	basename := strings.Replace(c.CommandPath(), " ", "_", -1) + ".md"
    30  	filename := filepath.Join(dir, basename)
    31  	if strings.Contains(filename, name+".md") {
    32  		filename = filepath.Join(path, "README.md")
    33  	}
    34  
    35  	var f *os.File
    36  	f, err = os.Create(filepath.Clean(filename))
    37  	if err != nil {
    38  		return err
    39  	}
    40  	defer func() {
    41  		err1 := f.Close()
    42  		if err == nil {
    43  			err = err1
    44  		}
    45  	}()
    46  	if _, err = io.WriteString(f, filePrepender(filename)); err != nil {
    47  		return err
    48  	}
    49  	if err = GenMarkdownCustom(c, f, linkHandler); err != nil {
    50  		return err
    51  	}
    52  	return err
    53  }
    54  
    55  // GenMarkdownCustom creates custom markdown output.
    56  func GenMarkdownCustom(c *cobra.Command, w io.Writer, linkHandler func(*cobra.Command, string) string) error {
    57  	c.InitDefaultHelpCmd()
    58  	c.InitDefaultHelpFlag()
    59  
    60  	buf := new(bytes.Buffer)
    61  	name := c.CommandPath()
    62  
    63  	short := c.Short
    64  	long := c.Long
    65  	if long == "" {
    66  		long = short
    67  	}
    68  
    69  	buf.WriteString("## " + name + "\n\n")
    70  	buf.WriteString(short + "\n\n")
    71  	buf.WriteString("### Synopsis\n\n")
    72  	buf.WriteString(long + "\n\n")
    73  
    74  	if c.Runnable() {
    75  		buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", c.UseLine()))
    76  	}
    77  
    78  	if len(c.Example) > 0 {
    79  		buf.WriteString("### Examples\n\n")
    80  		buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", c.Example))
    81  	}
    82  
    83  	if err := printOptions(buf, c); err != nil {
    84  		return err
    85  	}
    86  	if hasSeeAlso(c) {
    87  		buf.WriteString("### SEE ALSO\n\n")
    88  		if c.HasParent() {
    89  			parent := c.Parent()
    90  			pName := parent.CommandPath()
    91  			link := pName + ".md"
    92  			link = strings.Replace(link, " ", "_", -1)
    93  			buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", pName, linkHandler(c, link), parent.Short))
    94  		}
    95  
    96  		children := c.Commands()
    97  		sort.Sort(byName(children))
    98  
    99  		for _, child := range children {
   100  			if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() {
   101  				continue
   102  			}
   103  			cname := name + " " + child.Name()
   104  			link := cname + ".md"
   105  			link = strings.Replace(link, " ", "_", -1)
   106  			buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", cname, linkHandler(c, link), child.Short))
   107  		}
   108  		buf.WriteString("\n")
   109  	}
   110  	if !c.DisableAutoGenTag {
   111  		buf.WriteString("###### Auto generated by docgen on " + time.Now().Format("2-Jan-2006") + "\n")
   112  	}
   113  	_, err := buf.WriteTo(w)
   114  	return err
   115  }
   116  
   117  func printOptions(buf *bytes.Buffer, c *cobra.Command) error {
   118  	flags := c.NonInheritedFlags()
   119  	flags.SetOutput(buf)
   120  	if flags.HasAvailableFlags() {
   121  		buf.WriteString("### Options\n\n```\n")
   122  		flags.PrintDefaults()
   123  		buf.WriteString("```\n\n")
   124  	}
   125  
   126  	parentFlags := c.InheritedFlags()
   127  	parentFlags.SetOutput(buf)
   128  	if parentFlags.HasAvailableFlags() {
   129  		buf.WriteString("### Options inherited from parent commands\n\n```\n")
   130  		parentFlags.PrintDefaults()
   131  		buf.WriteString("```\n\n")
   132  	}
   133  	return nil
   134  }
   135  
   136  // Test to see if we have a reason to print See Also information in docs
   137  // Basically this is a test for a parent commend or a subcommand which is
   138  // both not deprecated and not the autogenerated help command.
   139  func hasSeeAlso(c *cobra.Command) bool {
   140  	if c.HasParent() {
   141  		return true
   142  	}
   143  	for _, c := range c.Commands() {
   144  		if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
   145  			continue
   146  		}
   147  		return true
   148  	}
   149  	return false
   150  }
   151  
   152  type byName []*cobra.Command
   153  
   154  func (s byName) Len() int           { return len(s) }
   155  func (s byName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
   156  func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }