1 package clidoc
2
3 import (
4 "bytes"
5 "errors"
6 "fmt"
7 "html"
8 "io"
9 "io/ioutil"
10 "os"
11 "path"
12 "path/filepath"
13 "sort"
14 "strings"
15
16 "github.com/spf13/cobra"
17 "github.com/spf13/cobra/doc"
18 "github.com/tidwall/gjson"
19 "github.com/tidwall/sjson"
20 )
21
22 const sideBarLabel = "Command Line Interface (CLI)"
23
24
25 func Generate(cmd *cobra.Command, args []string) error {
26 if len(args) != 1 {
27 return errors.New("command expects one argument which is the project's root folder")
28 }
29
30 navItems := make([]string, 0)
31 if err := generate(cmd, args[0], &navItems); err != nil {
32 return err
33 }
34 sort.Strings(navItems)
35
36 spath := filepath.Join(args[0], "docs", "sidebar.json")
37 sidebar, err := ioutil.ReadFile(spath)
38 if err != nil {
39 return err
40 }
41
42 if !gjson.ValidBytes(sidebar) {
43 return errors.New("sidebar file is not valid JSON")
44 }
45
46 var index int
47 gjson.GetBytes(sidebar, `Reference`).ForEach(func(key, value gjson.Result) bool {
48 if strings.Contains(value.Raw, sideBarLabel) {
49 return false
50 }
51 index++
52 return true
53 })
54
55 sidebar, err = sjson.SetBytes(sidebar, fmt.Sprintf(`Reference.%d.%s`, index, sideBarLabel), navItems)
56 if err != nil {
57 return err
58 }
59
60
61 if err := ioutil.WriteFile(spath, []byte(gjson.GetBytes(sidebar, "@pretty").Raw), 0644); err != nil {
62 return err
63 }
64
65 return nil
66 }
67
68 func trimExt(s string) string {
69 return strings.ReplaceAll(strings.TrimSuffix(s, filepath.Ext(s)), "_", "-")
70 }
71
72 func generate(cmd *cobra.Command, dir string, navItems *[]string) error {
73 cmd.DisableAutoGenTag = true
74 for _, c := range cmd.Commands() {
75 if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
76 continue
77 }
78 if err := generate(c, dir, navItems); err != nil {
79 return err
80 }
81 }
82
83 basename := strings.Replace(cmd.CommandPath(), " ", "-", -1)
84 if err := os.MkdirAll(filepath.Join(dir, "docs", "docs", "cli"), 0755); err != nil {
85 return err
86 }
87
88 filename := filepath.Join(dir, "docs", "docs", "cli", basename) + ".md"
89 f, err := os.Create(filename)
90 if err != nil {
91 return err
92 }
93 defer f.Close()
94
95 if _, err := io.WriteString(f, fmt.Sprintf(`---
96 id: %s
97 title: %s
98 description: %s %s
99 ---
100
101 <!--
102 This file is auto-generated.
103
104 To improve this file please make your change against the appropriate "./cmd/*.go" file.
105 -->
106 `,
107 basename,
108 cmd.CommandPath(),
109 cmd.CommandPath(),
110 cmd.Short,
111 )); err != nil {
112 return err
113 }
114
115 *navItems = append(*navItems, path.Join("cli", basename))
116
117 var b bytes.Buffer
118 if err := doc.GenMarkdownCustom(cmd, &b, trimExt); err != nil {
119 return err
120 }
121
122 _, err = f.WriteString(html.EscapeString(b.String()))
123 return err
124 }
125
View as plain text