From bdf149a26febdc216dc2c85614cfd6c4d2bf4d90 Mon Sep 17 00:00:00 2001 From: tcnksm Date: Sun, 23 Aug 2015 21:47:04 +0900 Subject: [PATCH 1/6] Add doc.go --- doc.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 doc.go diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..555734c --- /dev/null +++ b/doc.go @@ -0,0 +1,30 @@ +/* +Command gcli generates the codes and its directory structure you need to start building CLI tool by Go. https://github.com/tcnksm/gcli + +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) + +Usage: + + $ gcli [-version] [-help] [] + +Available commands are: + + 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, + + + $ cd $GOPATH/src/github.com/YOUR_NAME + $ gcli new -F mitchellh_cli -c add -c list -c delete todo + + +*/ +package main From 5c7c1eda3e5b213f73effdfa36959217debd3d5d Mon Sep 17 00:00:00 2001 From: tcnksm Date: Sat, 10 Oct 2015 20:43:33 +0900 Subject: [PATCH 2/6] Generate godoc by command --- cli.go | 9 ++++ doc.go | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++----- godoc.go | 123 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 279 insertions(+), 14 deletions(-) create mode 100644 godoc.go diff --git a/cli.go b/cli.go index c5dbd7f..9de0e17 100644 --- a/cli.go +++ b/cli.go @@ -32,6 +32,9 @@ 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" @@ -39,6 +42,12 @@ func RunCustom(args []string, commands map[string]cli.CommandFactory) int { args = newArgs break } + + // Generating godoc (doc.go). This is only for gcli developper. + if arg == "-godoc" { + return runGodoc(commands) + + } } cli := &cli.CLI{ diff --git a/doc.go b/doc.go index 555734c..3dda1da 100644 --- a/doc.go +++ b/doc.go @@ -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] [] + +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 -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] [] + 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 */ diff --git a/godoc.go b/godoc.go new file mode 100644 index 0000000..77d3992 --- /dev/null +++ b/godoc.go @@ -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] [] + +Available commands: +{{ range .}} + {{ .Name | printf "%-11s"}} {{ .Synopsis }}{{end}} + +Use "gcli -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 +` From f10927050e9feba8fda8c3538474732db5eefecd Mon Sep 17 00:00:00 2001 From: tcnksm Date: Sat, 10 Oct 2015 21:05:41 +0900 Subject: [PATCH 3/6] Change help() for godoc generating --- command/apply.go | 13 ++++++++----- command/design.go | 11 +++++++---- command/list.go | 6 ++++-- command/new.go | 15 ++++++++------- command/validate.go | 9 ++++++--- 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/command/apply.go b/command/apply.go index fe52a02..cecbf39 100644 --- a/command/apply.go +++ b/command/apply.go @@ -178,12 +178,15 @@ func (c *ApplyCommand) Synopsis() string { // and the complete list of flags the command accepts. func (c *ApplyCommand) Help() string { helpText := ` -Usage: gcli apply [option] FILE +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 apply [option] FILE - 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'. Options: diff --git a/command/design.go b/command/design.go index 4786e9e..e26fdcd 100644 --- a/command/design.go +++ b/command/design.go @@ -126,11 +126,14 @@ func (c *DesignCommand) Synopsis() string { // and the complete list of flags the command accepts. func (c *DesignCommand) Help() string { helpText := ` -Usage: gcli design [option] NAME +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 - 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. Options: diff --git a/command/list.go b/command/list.go index a3e7bf8..9c03f79 100644 --- a/command/list.go +++ b/command/list.go @@ -56,9 +56,11 @@ func (c *ListCommand) Synopsis() string { // and the complete list of flags the command accepts. func (c *ListCommand) Help() string { helpText := ` -Usage: gcli list +Show all avairable cli frameworks. - Show all avairable cli frameworks. +Usage: + + gcli list ` return strings.TrimSpace(helpText) } diff --git a/command/new.go b/command/new.go index 5a9b855..408d623 100644 --- a/command/new.go +++ b/command/new.go @@ -150,12 +150,14 @@ func (c *NewCommand) Synopsis() string { // and the complete list of flags the command accepts. func (c *NewCommand) Help() string { helpText := ` -Usage: gcli new [option] NAME +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'. - 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: @@ -190,8 +192,7 @@ Options: Examples: - This example shows creating todo command application skeleton - which has 'add' and 'delete' command by using mitchellh/cli package. +To create todo command application skeleton which has 'add' and 'delete' command, $ gcli new -command=add:"Add new task" -commnad=delete:"delete task" todo ` diff --git a/command/validate.go b/command/validate.go index 9dfe09b..dc3036f 100644 --- a/command/validate.go +++ b/command/validate.go @@ -75,10 +75,13 @@ func (c *ValidateCommand) Synopsis() string { // and the complete list of flags the command accepts. func (c *ValidateCommand) Help() string { helpText := ` -Usage: gcli validate FILE +Validate design template file which has required filed. If not it returns +error and non zero value. + +Usage: + + gcli validate FILE - Validate design template file which has required filed. If not it returns - error and non zero value. ` return strings.TrimSpace(helpText) } From 155a0c7314f2a3aff3dc07fc2d0ebc6421abaa8a Mon Sep 17 00:00:00 2001 From: tcnksm Date: Sat, 10 Oct 2015 21:07:31 +0900 Subject: [PATCH 4/6] Add godoc generating task --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 5dff3ad..95d71cf 100644 --- a/Makefile +++ b/Makefile @@ -37,3 +37,8 @@ test-docker: test-functional: build devdeps @echo "====> Run functional test" cd tests; go test -v ./... + +godoc: build + @echo "====> Generate doc.go" + @rm doc.go + @./bin/gcli -godoc From dfb9feb6f69c65faa419eebcd64fc38678f30bf0 Mon Sep 17 00:00:00 2001 From: tcnksm Date: Sat, 10 Oct 2015 21:07:39 +0900 Subject: [PATCH 5/6] Typo --- doc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc.go b/doc.go index 3dda1da..c7e8bd1 100644 --- a/doc.go +++ b/doc.go @@ -142,7 +142,7 @@ Options: Examples: -TO create todo command application skeleton which has 'add' and 'delete' command, +To create todo command application skeleton which has 'add' and 'delete' command, $ gcli new -command=add:"Add new task" -commnad=delete:"delete task" todo From c460dda05b57cc0563fc3a69a4826decb1defddc Mon Sep 17 00:00:00 2001 From: tcnksm Date: Sat, 10 Oct 2015 21:12:32 +0900 Subject: [PATCH 6/6] Exclude doc.go from test --- test.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test.sh b/test.sh index cec98ce..4121f49 100755 --- a/test.sh +++ b/test.sh @@ -3,7 +3,7 @@ # If `gofmt` & `golint` has output (means something wrong), # it will exit with non-zero status -TARGET=$(find . -name "*.go" | grep -v "bindata.go") +TARGET=$(find . -name "*.go" | grep -v "bindata.go" | grep -v "doc.go") echo -e "----> Run gofmt" FMT_RES=$(gofmt -l ${TARGET}) if [ -n "${FMT_RES}" ]; then @@ -22,6 +22,7 @@ fi echo -e "----> Run golint" LINT_RES=$(golint ./... | \ grep -v "bindata.go" | \ + grep -v "doc.go" | \ grep -v "type name will be used as command.CommandFlag by other packages" | \ grep -v "Framework_go_cmd" | \ grep -v "Framework_codegangsta_cli" | \