github.com/jduhamel/gcli@v0.2.4-0.20151019142748-0d5307cd7e21/godoc.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"os"
     7  	"sort"
     8  	"text/template"
     9  
    10  	"github.com/mitchellh/cli"
    11  )
    12  
    13  // CommandDoc stores command documentation strings.
    14  type CommandDoc struct {
    15  	Name     string
    16  	Synopsis string
    17  	Help     string
    18  }
    19  
    20  func runGodoc(commands map[string]cli.CommandFactory) int {
    21  	f, err := os.Create("doc.go")
    22  	if err != nil {
    23  		return 1
    24  	}
    25  	defer f.Close()
    26  
    27  	commandDocs := newCommandDocs(commands)
    28  
    29  	var buf bytes.Buffer
    30  	if err := tmpl(&buf, docTmpl, commandDocs); err != nil {
    31  		return 1
    32  	}
    33  
    34  	err = tmpl(f, godocTmpl, struct {
    35  		Content string
    36  	}{
    37  		Content: buf.String(),
    38  	})
    39  	if err != nil {
    40  		return 1
    41  	}
    42  	return 0
    43  }
    44  
    45  func newCommandDocs(commands map[string]cli.CommandFactory) []CommandDoc {
    46  	keys := make([]string, 0, len(commands))
    47  
    48  	// Extract key (command name) for sort.
    49  	for key, _ := range commands {
    50  		keys = append(keys, key)
    51  	}
    52  	sort.Strings(keys)
    53  
    54  	commandDocs := make([]CommandDoc, 0, len(commands))
    55  	for _, key := range keys {
    56  		if key == "version" {
    57  			continue
    58  		}
    59  		cmdFunc, ok := commands[key]
    60  		if !ok {
    61  			// Should not reach here..
    62  			panic("command not found: " + key)
    63  		}
    64  
    65  		cmd, _ := cmdFunc()
    66  		commandDocs = append(commandDocs, CommandDoc{
    67  			Name:     key,
    68  			Synopsis: cmd.Synopsis(),
    69  			Help:     cmd.Help(),
    70  		})
    71  	}
    72  
    73  	return commandDocs
    74  }
    75  
    76  // tmpl evaluates template content with data
    77  // and write them to writer, return error if any
    78  func tmpl(wr io.Writer, content string, data interface{}) error {
    79  
    80  	tmpl, err := template.New("doc").Parse(content)
    81  	if err != nil {
    82  		return err
    83  	}
    84  
    85  	if err := tmpl.Execute(wr, data); err != nil {
    86  		return err
    87  	}
    88  
    89  	return nil
    90  }
    91  
    92  var docTmpl = `Command gcli generates a skeleton (codes and its directory structure) you need to start building CLI tool by Golang.
    93  https://github.com/tcnksm/gcli
    94  
    95  Usage:
    96  
    97      gcli [-version] [-help]  <command> [<options>]
    98  
    99  Available commands:
   100  {{ range .}}
   101      {{ .Name | printf "%-11s"}} {{ .Synopsis }}{{end}}
   102  
   103  Use "gcli <command> -help" for more information about command.
   104  
   105  {{ range . }}
   106  
   107  {{ .Synopsis }}
   108  
   109  {{ .Help }}
   110  
   111  {{ end }}
   112  `
   113  
   114  var godocTmpl = `// DO NOT EDIT THIS FILE.
   115  // THIS FILE IS GENERATED BY GO GENERATE.
   116  
   117  /*
   118  {{ .Content }}
   119  */
   120  package main
   121  `