gen_docs.go

  1package main
  2
  3import (
  4	"fmt"
  5	"os"
  6	"path"
  7	"path/filepath"
  8	"strings"
  9	"time"
 10
 11	"github.com/pkg/errors"
 12	"github.com/spf13/cobra/doc"
 13
 14	"github.com/MichaelMure/git-bug/bridge"
 15	"github.com/MichaelMure/git-bug/commands"
 16)
 17
 18const bridgeExampleFilePath = "commands/bridge_configure_doc.go"
 19
 20func main() {
 21	fmt.Println("Generating documentation ...")
 22
 23	tasks := map[string]func() error{
 24		"BridgeConfig": genBridgeConfig,
 25		"ManPage":      genManPage,
 26		"Markdown":     genMarkdown,
 27	}
 28
 29	// Due to concurrency issues in cobra, the following can't be concurrent :(
 30
 31	// var wg sync.WaitGroup
 32	for name, f := range tasks {
 33		// wg.Add(1)
 34		// go func(name string, f func() error) {
 35		// 	defer wg.Done()
 36		err := f()
 37		if err != nil {
 38			fmt.Printf("  - %s: %v\n", name, err)
 39			return
 40		}
 41		fmt.Printf("  - %s: ok\n", name)
 42		// }(name, f)
 43	}
 44
 45	// wg.Wait()
 46}
 47
 48// If a flag is not listed in flagInfos, docs will generate the default values for the flag:
 49// flagName = lowercase name
 50// defaultVal = $({uppercase name})
 51// paramConflicts = none
 52var flagInfos = map[string]BridgeFlagInfo{
 53	"BaseURL": {
 54		flagName:       "base-url",
 55		defaultVal:     "$(BASE_URL)",
 56		paramConflicts: []string{},
 57	},
 58	"CredPrefix": {
 59		flagName:   "credential",
 60		defaultVal: "$(CREDENTIALS)",
 61		paramConflicts: []string{
 62			"TokenRaw",
 63		},
 64	},
 65	"TokenRaw": {
 66		flagName:       "token",
 67		defaultVal:     "$(TOKEN)",
 68		paramConflicts: []string{},
 69	},
 70}
 71
 72type BridgeFlagInfo struct {
 73	flagName       string
 74	defaultVal     string
 75	paramConflicts []string
 76}
 77
 78func genBridgeConfig() error {
 79	var exampleText strings.Builder
 80	exampleText.WriteString("`")
 81	exampleText.WriteString(`# Interactive example
 82[1]: github
 83[2]: gitlab
 84[3]: jira
 85[4]: launchpad-preview
 86
 87target: 1
 88name [default]: default
 89
 90Detected projects:
 91[1]: github.com/a-hilaly/git-bug
 92[2]: github.com/MichaelMure/git-bug
 93
 94[0]: Another project
 95
 96Select option: 1
 97
 98[1]: user provided token
 99[2]: interactive token creation
100Select option: 1
101
102You can generate a new token by visiting https://github.com/settings/tokens.
103Choose 'Generate new token' and set the necessary access scope for your repository.
104
105The access scope depend on the type of repository.
106Public:
107	- 'public_repo': to be able to read public repositories
108Private:
109	- 'repo'       : to be able to read private repositories
110
111Enter token: 87cf5c03b64029f18ea5f9ca5679daa08ccbd700
112Successfully configured bridge: default
113
114`)
115	targets := bridge.Targets()
116	for i, b := range targets {
117		if i != 0 {
118			exampleText.WriteString("\n\n")
119		}
120		exampleText.WriteString("# For ")
121		exampleText.WriteString(strings.Title(b))
122		exampleText.WriteString("\ngit bug bridge configure \\\n")
123
124		exampleText.WriteString("    --target=")
125		exampleText.WriteString(strings.ToLower(b))
126		exampleText.WriteString(" \\\n")
127
128		params, err := bridge.ValidParams(b)
129		if err != nil {
130			return errors.Wrap(err, "bridge parameters")
131		}
132
133	OUTER:
134		for _, param := range params {
135			if flagInfo, ok := flagInfos[param]; ok {
136				if len(flagInfo.paramConflicts) != 0 {
137					for p := range params {
138						for conflict := range flagInfo.paramConflicts {
139							if p == conflict {
140								continue OUTER
141							}
142						}
143					}
144				}
145
146				exampleText.WriteString("    --")
147				exampleText.WriteString(flagInfo.flagName)
148				exampleText.WriteRune('=')
149				exampleText.WriteString(flagInfo.defaultVal)
150			} else {
151				exampleText.WriteString("    --")
152				exampleText.WriteString(strings.ToLower(param))
153				exampleText.WriteString("=$(")
154				exampleText.WriteString(strings.ToUpper(strings.ReplaceAll(param, "-", "_")))
155				exampleText.WriteRune(')')
156			}
157
158			exampleText.WriteString(" \\\n")
159		}
160	}
161	exampleText.WriteString("`")
162
163	_ = os.Remove(bridgeExampleFilePath)
164
165	f, err := os.Create(bridgeExampleFilePath)
166	if err != nil {
167		return err
168	}
169	defer f.Close()
170
171	_, err = f.WriteString(`// Code generated by doc/gen_docs.go; DO NOT EDIT.
172
173package commands
174
175var bridgeConfigureExample =`)
176	if err != nil {
177		return err
178	}
179	_, err = f.WriteString(exampleText.String())
180	if err != nil {
181		return err
182	}
183
184	return nil
185}
186
187func genManPage() error {
188	cwd, _ := os.Getwd()
189	dir := path.Join(cwd, "doc", "man")
190
191	date := time.Date(2019, 4, 1, 12, 0, 0, 0, time.UTC)
192
193	header := &doc.GenManHeader{
194		Title:   "GIT-BUG",
195		Section: "1",
196		Date:    &date,
197		Source:  "Generated from git-bug's source code",
198	}
199
200	files, err := filepath.Glob(dir + "/*.1")
201	if err != nil {
202		return err
203	}
204	for _, f := range files {
205		if err := os.Remove(f); err != nil {
206			return err
207		}
208	}
209
210	return doc.GenManTree(commands.NewRootCommand(), header, dir)
211}
212
213func genMarkdown() error {
214	cwd, _ := os.Getwd()
215	dir := path.Join(cwd, "doc", "md")
216
217	files, err := filepath.Glob(dir + "/*.md")
218	if err != nil {
219		return err
220	}
221	for _, f := range files {
222		if err := os.Remove(f); err != nil {
223			return err
224		}
225	}
226
227	return doc.GenMarkdownTree(commands.NewRootCommand(), dir)
228}