Skip to content

Commit

Permalink
Generate godoc by command
Browse files Browse the repository at this point in the history
  • Loading branch information
tcnksm committed Oct 10, 2015
1 parent bdf149a commit 5c7c1ed
Show file tree
Hide file tree
Showing 3 changed files with 279 additions and 14 deletions.
9 changes: 9 additions & 0 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,22 @@ func Run(args []string) int {
func RunCustom(args []string, commands map[string]cli.CommandFactory) int {

for _, arg := range args {

// If the following options are provided,
// then execute glic version command
if arg == "-v" || arg == "-version" || arg == "--version" {
newArgs := make([]string, len(args)+1)
newArgs[0] = "version"
copy(newArgs[1:], args)
args = newArgs
break
}

// Generating godoc (doc.go). This is only for gcli developper.
if arg == "-godoc" {
return runGodoc(commands)

}
}

cli := &cli.CLI{
Expand Down
161 changes: 147 additions & 14 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,162 @@
// DO NOT EDIT THIS FILE.
// THIS FILE IS GENERATED BY GO GENERATE.

/*
Command gcli generates the codes and its directory structure you need to start building CLI tool by Go. https://github.com/tcnksm/gcli
Command gcli generates a skeleon (codes and its directory structure) you need to start building CLI tool by Golang.
https://github.com/tcnksm/gcli
Usage:
gcli [-version] [-help] <command> [<options>]
Available commands:
apply Apply design template file for generating cli project
design Generate project design template
list List available cli frameworks
new Generate new cli project
validate Validate design template file
Use "gcli <command> -help" for more information about command.
You can choose your favorite CLI framework. Currently gcli supports the following packages
- flag (Standard package)
- codegangsta_cli (https://github.com/codegangsta/cli)
- mitchellh_cli (https://github.com/mitchellh/cli)
- go_cmd (go command style)
Apply design template file for generating cli project
Apply design template file for generating cli project. You can generate
design template file via 'gcli design' command. If framework name is not
specified gcli use codegangsta/cli. You can set framework name via '-F'
option. To check cli framework you can use, run 'gcli list'.
Usage:
$ gcli [-version] [-help] <command> [<args>]
gcli apply [option] FILE
Options:
-framework=name, -F Cli framework name. By default, gcli use "codegangsta/cli"
To check cli framework you can use, run 'gcli list'.
If you set invalid framework, it will be failed.
-skip-test, -T Skip generating *_test.go file. By default, gcli generates
test file If you specify this flag, gcli will not generate
test files.
Generate project design template
Generate project design template (as toml file). You can pass that file to 'gcli apply'
command and generate CLI tool based on template file. You can define what command
and what flag you need on that file.
Usage:
gcli design [option] NAME
Options:
-command=name, -c Command name which you want to add.
This is valid only when cli pacakge support commands.
This can be specified multiple times. Synopsis can be
set after ":". Namely, you can specify command by
-command=NAME:SYNOPSYS. Only NAME is required.
You can set multiple variables at same time with ","
separator.
-flag=name, -f Global flag option name which you want to add.
This can be specified multiple times. By default, flag type
is string and its description is empty. You can set them,
with ":" separator. Namaly, you can specify flag by
-flag=NAME:TYPE:DESCIRPTION. Order must be flow this and
TYPE must be string, bool or int. Only NAME is required.
You can set multiple variables at same time with ","
separator.
-framework=name, -F Cli framework name. By default, gcli use "codegangsta/cli"
To check cli framework you can use, run 'gcli list'.
If you set invalid framework, it will be failed.
-owner=name, -o Command owner (author) name. This value is also used for
import path name. By default, owner name is extracted from
~/.gitconfig variable.
Available commands are:
-output, -O Change output file name. By default, gcli use "NAME-design.toml"
list List available cli frameworks
new Generate new cli project
version Print the gcli version
For example, if you want to build `todo` application which has add (Add new task), list (List all tasks) and delete (Delete a task) command with mitchellh/cli framework,
List available cli frameworks
Show all avairable cli frameworks.
Usage:
gcli list
Generate new cli project
Generate new cli skeleton project. At least, you must provide executable
name. You can select cli package and set commands via command line option.
See more about that on Options section. By default, gcli use codegangsta/cli.
To check cli framework you can use, run 'gcli list'.
Usage:
gcli new [option] NAME
Options:
-command=name, -c Command name which you want to add.
This is valid only when cli pacakge support commands.
This can be specified multiple times. Synopsis can be
set after ":". Namely, you can specify command by
-command=NAME:SYNOPSYS. Only NAME is required.
You can set multiple variables at same time with ","
separator.
-flag=name, -f Global flag option name which you want to add.
This can be specified multiple times. By default, flag type
is string and its description is empty. You can set them,
with ":" separator. Namaly, you can specify flag by
-flag=NAME:TYPE:DESCIRPTION. Order must be flow this and
TYPE must be string, bool or int. Only NAME is required.
You can set multiple variables at same time with ","
separator.
-framework=name, -F Cli framework name. By default, gcli use "codegangsta/cli"
To check cli framework you can use, run 'gcli list'.
If you set invalid framework, it will be failed.
-owner=name, -o Command owner (author) name. This value is also used for
import path name. By default, owner name is extracted from
~/.gitconfig variable.
-skip-test, -T Skip generating *_test.go file. By default, gcli generates
test file If you specify this flag, gcli will not generate
test files.
Examples:
TO create todo command application skeleton which has 'add' and 'delete' command,
$ gcli new -command=add:"Add new task" -commnad=delete:"delete task" todo
Validate design template file
Validate design template file which has required filed. If not it returns
error and non zero value.
Usage:
gcli validate FILE
$ cd $GOPATH/src/github.com/YOUR_NAME
$ gcli new -F mitchellh_cli -c add -c list -c delete todo
*/
Expand Down
123 changes: 123 additions & 0 deletions godoc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package main

import (
"bytes"
"io"
"os"
"sort"
"text/template"

"github.com/mitchellh/cli"
)

// CommandDoc stores command documentation strings.
type CommandDoc struct {
Name string
Synopsis string
Help string
}

func runGodoc(commands map[string]cli.CommandFactory) int {
f, err := os.Create("doc.go")
if err != nil {
return 1
}
defer f.Close()

commandDocs := newCommandDocs(commands)

var buf bytes.Buffer
if err := tmpl(&buf, docTmpl, commandDocs); err != nil {
return 1
}

err = tmpl(f, godocTmpl, struct {
Content string
}{
Content: buf.String(),
})
if err != nil {
return 1
}
return 0
}

func newCommandDocs(commands map[string]cli.CommandFactory) []CommandDoc {
keys := make([]string, 0, len(commands))

// Extract key (command name) for sort.
for key, _ := range commands {
keys = append(keys, key)
}
sort.Strings(keys)

commandDocs := make([]CommandDoc, 0, len(commands))
for _, key := range keys {
if key == "version" {
continue
}
cmdFunc, ok := commands[key]
if !ok {
// Should not reach here..
panic("command not found: " + key)
}

cmd, _ := cmdFunc()
commandDocs = append(commandDocs, CommandDoc{
Name: key,
Synopsis: cmd.Synopsis(),
Help: cmd.Help(),
})
}

return commandDocs
}

// tmpl evaluates template content with data
// and write them to writer, return error if any
func tmpl(wr io.Writer, content string, data interface{}) error {

// funcs := funcMap()

tmpl, err := template.New("doc").Parse(content)
if err != nil {
return err
}

if err := tmpl.Execute(wr, data); err != nil {
return err
}

return nil
}

var docTmpl = `Command gcli generates a skeleon (codes and its directory structure) you need to start building CLI tool by Golang.
https://github.com/tcnksm/gcli
Usage:
gcli [-version] [-help] <command> [<options>]
Available commands:
{{ range .}}
{{ .Name | printf "%-11s"}} {{ .Synopsis }}{{end}}
Use "gcli <command> -help" for more information about command.
{{ range . }}
{{ .Synopsis }}
{{ .Help }}
{{ end }}
`

var godocTmpl = `// DO NOT EDIT THIS FILE.
// THIS FILE IS GENERATED BY GO GENERATE.
/*
{{ .Content }}
*/
package main
`

0 comments on commit 5c7c1ed

Please sign in to comment.