-
Notifications
You must be signed in to change notification settings - Fork 0
/
document.go
137 lines (111 loc) · 4.35 KB
/
document.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package docgen
import (
"bytes"
"errors"
"fmt"
"os"
"path/filepath"
"time"
goCdLogger "github.com/nikhilsbhat/gocd-sdk-go/pkg/logger"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
const (
docGenName = "UrFaveCliDocGen"
docFolderPermission = 0o755
)
// shamelessly copied code from https://github.com/urfave/cli/issues/340#issuecomment-334389849 with few modification.
// thankful to https://github.com/Southclaws for this.
func getDocs(app *cli.App, logger *logrus.Logger) string {
buffer := bytes.Buffer{}
buffer.WriteString(fmt.Sprintf("# `%s`\n\n", app.Name))
buffer.WriteString(fmt.Sprintf("%s\n%s\n", app.Usage, app.Version))
if app.Description != "" {
buffer.WriteString(app.Description)
buffer.WriteString("\n\n")
}
logger.Info("generating documents for subcommands")
buffer.WriteString("## Subcommands\n\n")
for _, command := range app.Commands {
logger.Infof("generating documents for subcommand '%s'", command.Name)
buffer.WriteString(fmt.Sprintf("### `%s`\n\n", command.Name))
if command.Usage != "" {
logger.Infof("generating documents on usage subcommand '%s'", command.Name)
buffer.WriteString(command.Usage)
buffer.WriteString("\n\n")
}
if command.Description != "" {
logger.Infof("generating documents on description of subcommand '%s'", command.Name)
buffer.WriteString(command.Description)
buffer.WriteString("\n\n")
}
if len(command.Flags) > 0 {
logger.Infof("generating documents on flags used by subcommand '%s'", command.Name)
buffer.WriteString("#### Flags\n\n")
for _, flag := range command.Flags {
buffer.WriteString(fmt.Sprintf("- `%s`\n", flag.String()))
}
buffer.WriteString("\n\n")
}
}
if len(app.Flags) > 0 {
logger.Infof("generating documents on global flags of app '%s'", app.Name)
buffer.WriteString("## Global Flags\n\n")
for _, flag := range app.Flags {
buffer.WriteString(fmt.Sprintf("- `%s`\n", flag.String()))
}
buffer.WriteString("\n")
}
buffer.WriteString("Authors\n")
for _, author := range app.Authors {
buffer.WriteString(fmt.Sprintf(" - %s\n", author.String()))
}
buffer.WriteString("\n###### Auto generated by nikhilsbhat/urfavecli-docgen on " + time.Now().Format("2-Jan-2006") + "\n")
return buffer.String()
}
// GenerateDocs generates markdown documentation for the commands in app.
func GenerateDocs(app *cli.App, file string) error {
docsRootPath, err := filepath.Abs("doc")
if err != nil {
return err
}
docsPath := filepath.Join(docsRootPath, fmt.Sprintf("%s.md", file))
logger := logrus.New()
logger.SetLevel(goCdLogger.GetLoglevel("info"))
logger.WithField(docGenName, true)
logger.SetFormatter(&logrus.JSONFormatter{})
logger.Infof("generating cli documents for '%s'", docGenName)
logger.Infof("documets would be generated under '%s'", docsPath)
docString := getDocs(app, logger)
logger.Infof("documents for cli '%s' were rendered, proceeding to write the same to path '%s'", docGenName, docsPath)
_, err = os.Stat(docsRootPath)
if err != nil && errors.Is(err, os.ErrNotExist) {
logger.Infof("creating directory 'doc' to place document files")
if err = os.MkdirAll(docsRootPath, docFolderPermission); err != nil {
return fmt.Errorf("creating document directory errored with: '%w'", err)
}
} else {
logger.Infof("skipping the creation of directory 'doc' as it was already created.")
}
logger.Infof("proceeding to write the rendered document to '%s'.", docsPath)
_, err = os.Stat(docsPath)
if errors.Is(err, os.ErrNotExist) { //nolint:gocritic
logger.Info("writing rendered document to file")
if _, err = os.Create(docsPath); err != nil {
return fmt.Errorf("writing document to file '%s' errored with: '%w'", docsPath, err)
}
} else if err != nil {
return fmt.Errorf("stating document to file '%s' errored with: '%w'", docsPath, err)
} else {
logger.Infof("found an existing document with the same name. Updating it with the latest updates.")
}
docFile, err := os.OpenFile(docsPath, os.O_CREATE|os.O_WRONLY, os.ModeAppend) //nolint:nosnakecase
if err != nil {
return fmt.Errorf("reading the document file '%s' failed with: '%w'", docsPath, err)
}
if _, err := docFile.WriteString(docString); err != nil {
return fmt.Errorf("updating document file '%s' with newer information errored with: '%w'", docsPath, err)
}
logger.Infof("documents were successfully rendered to '%s'", docsPath)
return nil
}