@@ -17,10 +17,13 @@ package clidocstool
1717import (
1818 "errors"
1919 "io"
20+ "log"
2021 "os"
22+ "path/filepath"
2123 "strings"
2224
2325 "github.com/spf13/cobra"
26+ "github.com/spf13/cobra/doc"
2427)
2528
2629// Options defines options for cli-docs-tool
@@ -29,6 +32,8 @@ type Options struct {
2932 SourceDir string
3033 TargetDir string
3134 Plugin bool
35+
36+ ManHeader * doc.GenManHeader
3237}
3338
3439// Client represents an active cli-docs-tool object
@@ -37,6 +42,8 @@ type Client struct {
3742 source string
3843 target string
3944 plugin bool
45+
46+ manHeader * doc.GenManHeader
4047}
4148
4249// New initializes a new cli-docs-tool client
@@ -48,9 +55,10 @@ func New(opts Options) (*Client, error) {
4855 return nil , errors .New ("source dir required" )
4956 }
5057 c := & Client {
51- root : opts .Root ,
52- source : opts .SourceDir ,
53- plugin : opts .Plugin ,
58+ root : opts .Root ,
59+ source : opts .SourceDir ,
60+ plugin : opts .Plugin ,
61+ manHeader : opts .ManHeader ,
5462 }
5563 if len (opts .TargetDir ) == 0 {
5664 c .target = c .source
@@ -73,9 +81,69 @@ func (c *Client) GenAllTree() error {
7381 if err = c .GenYamlTree (c .root ); err != nil {
7482 return err
7583 }
84+ if err = c .GenManTree (c .root ); err != nil {
85+ return err
86+ }
7687 return nil
7788}
7889
90+ // loadLongDescription gets long descriptions and examples from markdown.
91+ func (c * Client ) loadLongDescription (parentCmd * cobra.Command , generator string ) error {
92+ for _ , cmd := range parentCmd .Commands () {
93+ if cmd .HasSubCommands () {
94+ if err := c .loadLongDescription (cmd , generator ); err != nil {
95+ return err
96+ }
97+ }
98+ name := cmd .CommandPath ()
99+ if i := strings .Index (name , " " ); i >= 0 {
100+ // remove root command / binary name
101+ name = name [i + 1 :]
102+ }
103+ if name == "" {
104+ continue
105+ }
106+ mdFile := strings .ReplaceAll (name , " " , "_" ) + ".md"
107+ sourcePath := filepath .Join (c .source , mdFile )
108+ content , err := os .ReadFile (sourcePath )
109+ if os .IsNotExist (err ) {
110+ log .Printf ("WARN: %s does not exist, skipping Markdown examples for %s docs\n " , mdFile , generator )
111+ continue
112+ }
113+ if err != nil {
114+ return err
115+ }
116+ applyDescriptionAndExamples (cmd , string (content ))
117+ }
118+ return nil
119+ }
120+
121+ // applyDescriptionAndExamples fills in cmd.Long and cmd.Example with the
122+ // "Description" and "Examples" H2 sections in mdString (if present).
123+ func applyDescriptionAndExamples (cmd * cobra.Command , mdString string ) {
124+ sections := getSections (mdString )
125+ var (
126+ anchors []string
127+ md string
128+ )
129+ if sections ["description" ] != "" {
130+ md , anchors = cleanupMarkDown (sections ["description" ])
131+ cmd .Long = md
132+ anchors = append (anchors , md )
133+ }
134+ if sections ["examples" ] != "" {
135+ md , anchors = cleanupMarkDown (sections ["examples" ])
136+ cmd .Example = md
137+ anchors = append (anchors , md )
138+ }
139+ if len (anchors ) > 0 {
140+ if cmd .Annotations == nil {
141+ cmd .Annotations = make (map [string ]string )
142+ }
143+ cmd .Annotations ["anchors" ] = strings .Join (anchors , "," )
144+ }
145+ }
146+
79147func fileExists (f string ) bool {
80148 info , err := os .Stat (f )
81149 if os .IsNotExist (err ) {
0 commit comments