From e970264f007f77384c03a4d5913a1948e83001fd Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Mon, 14 Sep 2015 12:33:59 +0100 Subject: [PATCH] Use man content for `help ' and ' --help' Call 'go generate ./commands' to create string entries from .ronns which the cobra command can then use (added to the build scripts) --- .gitignore | 1 + commands/commands.go | 26 +++++++++++++++++ docs/man/mangen.go | 67 ++++++++++++++++++++++++++++++++++++++++++++ script/build.go | 5 ++++ 4 files changed, 99 insertions(+) create mode 100644 docs/man/mangen.go diff --git a/.gitignore b/.gitignore index 051cecf2..255c385e 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ repos docker/*.key src +commands/mancontent_gen.go diff --git a/commands/commands.go b/commands/commands.go index 2a4a3c4d..76bff546 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -16,6 +16,9 @@ import ( "github.com/github/git-lfs/vendor/_nuts/github.com/spf13/cobra" ) +// Populate man pages +//go:generate go run ../docs/man/mangen.go + var ( Debugging = false ErrorBuffer = &bytes.Buffer{} @@ -29,6 +32,7 @@ var ( cmd.Usage() }, } + ManPages = make(map[string]string, 20) ) // Error prints a formatted message to Stderr. It also gets printed to the @@ -218,6 +222,28 @@ func determineIncludeExcludePaths(includeArg, excludeArg string) (include, exclu return includePaths, excludePaths } +// help is used for 'git-lfs help ' +func help(cmd *cobra.Command, args []string) { + if txt, ok := ManPages[cmd.Use]; ok { + fmt.Fprintf(os.Stderr, txt) + } else { + fmt.Fprintf(os.Stderr, "Sorry, no help text found\n") + } +} + +// usage is used for 'git-lfs --help' or wen invoked manually +func usage(cmd *cobra.Command) error { + if txt, ok := ManPages[cmd.Use]; ok { + fmt.Fprintf(os.Stderr, txt) + } else { + fmt.Fprintf(os.Stderr, "Sorry, no usage text found\n") + } + return nil +} + func init() { log.SetOutput(ErrorWriter) + // Set up help/usage funcs based on manpage text + RootCmd.SetHelpFunc(help) + RootCmd.SetUsageFunc(usage) } diff --git a/docs/man/mangen.go b/docs/man/mangen.go new file mode 100644 index 00000000..b27451b1 --- /dev/null +++ b/docs/man/mangen.go @@ -0,0 +1,67 @@ +package main + +import ( + "bufio" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "regexp" + "strings" +) + +// Reads all .ronn files & and converts them to string literals +// triggered by "go generate" comment +// Literals are inserted into a map using an init function, this means +// that there are no compilation errors if 'go generate' hasn't been run, just +// blank man files. +func main() { + fmt.Fprintf(os.Stderr, "Converting man pages into code...\n") + mandir := "../docs/man" + fs, err := ioutil.ReadDir(mandir) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to open man dir: %v\n", err) + os.Exit(2) + } + out, err := os.Create("../commands/mancontent_gen.go") + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create go file: %v\n", err) + os.Exit(2) + } + out.WriteString("package commands\n\nfunc init() {\n") + out.WriteString("// THIS FILE IS GENERATED, DO NOT EDIT\n") + out.WriteString("// Use 'go generate ./commands' to update\n") + r := regexp.MustCompile(`git-lfs(?:-([A-Za-z\-]+))?.\d.ronn`) + count := 0 + for _, f := range fs { + if match := r.FindStringSubmatch(f.Name()); match != nil { + fmt.Fprintf(os.Stderr, "%v\n", f.Name()) + cmd := match[1] + if len(cmd) == 0 { + // This is git-lfs.1.ronn + cmd = "git-lfs" + } + out.WriteString("ManPages[\"" + cmd + "\"] = `") + contentf, err := os.Open(filepath.Join(mandir, f.Name())) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to open %v: %v\n", f.Name(), err) + os.Exit(2) + } + // Process the ronn to make it nicer as help text + scanner := bufio.NewScanner(contentf) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + // Remove backticks since it won't format & that's delimiting the string + line = strings.Replace(line, "`", "", -1) + // Maybe more e.g. ## ? + out.WriteString(line + "\n") + } + out.WriteString("`\n") + contentf.Close() + count++ + } + } + out.WriteString("}\n") + fmt.Fprintf(os.Stderr, "Successfully processed %d man pages.\n", count) + +} diff --git a/script/build.go b/script/build.go index 51d62fba..a7cdcac6 100644 --- a/script/build.go +++ b/script/build.go @@ -38,6 +38,11 @@ func mainBuild() { fmt.Printf("Using %s\n", runtime.Version()) + genOut, err := exec.Command("go", "generate", "./commands").CombinedOutput() + if err != nil { + fmt.Fprintf(os.Stderr, "go generate failed:\n%v", genOut) + os.Exit(1) + } cmd, _ := exec.Command("git", "rev-parse", "--short", "HEAD").Output() if len(cmd) > 0 {