Skip to content

Commit

Permalink
Merge pull request #16 from tcnksm/list
Browse files Browse the repository at this point in the history
Add list command
  • Loading branch information
tcnksm committed Jun 22, 2015
2 parents 40f590f + b421404 commit 10f4792
Show file tree
Hide file tree
Showing 28 changed files with 176 additions and 126 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ gcli

## Usage

To start new command line tool,
To start new command line tool, run below. It generates new cli skeleton project. At least, you must provide executable name.

```bash
$ gcli new [options] NAME
```
It generates new cli skeleton project. At least, you must provide executable name.

To see available frameworks,

```bash
$ gcli list
```

See more usage,

Expand Down
4 changes: 2 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ This is road map of `gcli`, what I'm doing for next release and planing for futu

## 0.2.1

- `list` command
- `godoc`
- More verbose outputs
- More verbose outputs in `skeleton` package
- More document for flag
- Global option for command pattern
- `go vet` `golint`, `gofmt` test for artifacts
- **Done**: `list` command
- **Done**: `go vet`, `golint`, `gofmt` test for `gcli`
- **Done**: `wercker.yml` to run test on Wercker

Expand Down
35 changes: 33 additions & 2 deletions command/list.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package command

import "strings"
import (
"bytes"
"fmt"
"strings"

"github.com/olekukonko/tablewriter"
"github.com/tcnksm/gcli/skeleton"
)

// ListCommand is a Command that lists all avairable frameworks
type ListCommand struct {
Expand All @@ -9,7 +16,31 @@ type ListCommand struct {

// Run lists all avairable frameworks.
func (c *ListCommand) Run(args []string) int {
// TODO

if len(args) > 0 {
msg := fmt.Sprintf("Invalid arguments: %s", strings.Join(args, " "))
c.UI.Error(msg)
return 1
}

outBuffer := new(bytes.Buffer)
// Create a table for output
table := tablewriter.NewWriter(outBuffer)
header := []string{"Name", "Command", "URL"}
table.SetHeader(header)
for _, f := range skeleton.Frameworks {
var cmd string
if len(f.CommandTemplates) > 0 {
cmd = "*"
}
table.Append([]string{f.Name, cmd, f.URL})
}

// Write a table
table.Render()

fmt.Fprintf(outBuffer, "COMMAND(*) means you can create command pattern CLI with that framework (you can use --command flag)")
c.UI.Output(outBuffer.String())
return 0
}

Expand Down
11 changes: 6 additions & 5 deletions command/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (c *NewCommand) Run(args []string) int {

parsedArgs := uflag.Args()
if len(parsedArgs) != 1 {
msg := fmt.Sprintf("invalid arguments: %s", strings.Join(parsedArgs, " "))
msg := fmt.Sprintf("Invalid arguments: %s", strings.Join(parsedArgs, " "))
c.UI.Error(msg)
return 1
}
Expand All @@ -89,8 +89,9 @@ func (c *NewCommand) Run(args []string) int {
return 1
}

framework, err := skeleton.Framework(frameworkStr)
framework, err := skeleton.FrameworkByName(frameworkStr)
if err != nil {
c.UI.Error(fmt.Sprintf("Failed to generate %q: %s", name, err.Error()))
return 1
}

Expand All @@ -100,8 +101,8 @@ func (c *NewCommand) Run(args []string) int {
if err != nil {
owner, err = gitconfig.Username()
if err != nil {
msg := "Cannot retrieve owner name\n" +
"Owener name is retrieved from `~/.gitcofig` file.\n" +
msg := "Cannot find owner name\n" +
"By default, owener name is retrieved from `~/.gitcofig` file.\n" +
"Please set one via -owner option or `~/.gitconfig` file."
c.UI.Error(msg)
return 1
Expand Down Expand Up @@ -138,7 +139,7 @@ func (c *NewCommand) Run(args []string) int {
// error was happened while executing skeleton.Generate().
// Run all templating and show all error.
if gotErr {
c.UI.Error(fmt.Sprintf("Failed to generate: %s", name))
c.UI.Error(fmt.Sprintf("Failed to generate %q", name))
return 1
}

Expand Down
6 changes: 6 additions & 0 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ func Commands(meta *command.Meta) map[string]cli.CommandFactory {
}, nil
},

"list": func() (cli.Command, error) {
return &command.ListCommand{
Meta: *meta,
}, nil
},

"version": func() (cli.Command, error) {
return &command.VersionCommand{
Meta: *meta,
Expand Down
123 changes: 103 additions & 20 deletions skeleton/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,114 @@ package skeleton

import "fmt"

const (
Framework_go_cmd = 100 + iota
Framework_codegangsta_cli
Framework_mitchellh_cli
// Framework represents framework
type Framework struct {
// Name is framework name
Name string

Framework_flag = 1000 + iota
)
// AltName is alternative name which represent Framework
AltNames []string

// Framework returns framework ID (unique variable in gcli)
// from name string. If not match any framework, it returns error.
func Framework(name string) (int, error) {
switch name {
case "go_cmd":
return Framework_go_cmd, nil
// Description is description of framework
Description string

case "codegangsta_cli", "codegagsta":
return Framework_codegangsta_cli, nil
// URL is framework project URL
URL string

case "mitchellh_cli", "mitchellh":
return Framework_mitchellh_cli, nil
// BaseTemplates
BaseTemplates []Template

case "flag":
return Framework_flag, nil
// CommandTemplate
CommandTemplates []Template
}

// CommonTemplates is collection of templates which are used all frameworks.
var CommonTemplates = []Template{
{"resource/tmpl/common/CHANGELOG.md.tmpl", "CHANGELOG.md"},
{"resource/tmpl/common/README.md.tmpl", "README.md"},
}

// Frameworks is collection of Framework.
var Frameworks = []*Framework{
{
Name: "mitchellh_cli",
AltNames: []string{"mitchellh"},
URL: "https://github.com/mitchellh/cli",
Description: `mitchellh/cli cli is a library for implementing powerful command-line interfaces in Go.
cli is the library that powers the CLI for Packer, Serf, and Consul.
`,
BaseTemplates: []Template{
{"resource/tmpl/mitchellh_cli/main.go.tmpl", "main.go"},
{"resource/tmpl/mitchellh_cli/version.go.tmpl", "version.go"},
{"resource/tmpl/mitchellh_cli/cli.go.tmpl", "cli.go"},
{"resource/tmpl/mitchellh_cli/commands.go.tmpl", "commands.go"},
{"resource/tmpl/mitchellh_cli/command/meta.go.tmpl", "command/meta.go"},
},
CommandTemplates: []Template{
{"resource/tmpl/mitchellh_cli/command/command.go.tmpl", "command/{{ .Name }}.go"},
{"resource/tmpl/mitchellh_cli/command/command_test.go.tmpl", "command/{{ .Name }}_test.go"},
},
},

{
Name: "codegangsta_cli",
AltNames: []string{"codegangsta"},
URL: "https://github.com/codegangsta/cli",
Description: `codegangsta/cli is simple, fast, and fun package for building command line apps in Go.
The goal is to enable developers to write fast and distributable command line applications in an expressive way.
`,
BaseTemplates: []Template{
{"resource/tmpl/codegangsta_cli/main.go.tmpl", "main.go"},
{"resource/tmpl/codegangsta_cli/version.go.tmpl", "version.go"},
{"resource/tmpl/codegangsta_cli/commands.go.tmpl", "commands.go"},
},
CommandTemplates: []Template{
{"resource/tmpl/codegangsta_cli/command/command.go.tmpl", "command/{{ .Name }}.go"},
{"resource/tmpl/codegangsta_cli/command/command_test.go.tmpl", "command/{{ .Name }}_test.go"},
},
},

{
Name: "go_cmd",
URL: "https://github.com/golang/go/tree/master/src/cmd/go",
Description: `
`,
BaseTemplates: []Template{
{"resource/tmpl/go_cmd/main.go.tmpl", "main.go"},
},
CommandTemplates: []Template{
{"resource/tmpl/go_cmd/command.go.tmpl", "{{ .Name }}.go"},
{"resource/tmpl/go_cmd/command_test.go.tmpl", "{{ .Name }}_test.go"},
},
},

{
Name: "flag",
AltNames: []string{},
URL: "https://golang.org/pkg/flag/",
Description: `Package flag implements command-line flag parsing.`,
BaseTemplates: []Template{
{"resource/tmpl/flag/main.go.tmpl", "main.go"},
{"resource/tmpl/flag/version.go.tmpl", "version.go"},
{"resource/tmpl/flag/cli.go.tmpl", "cli.go"},
{"resource/tmpl/flag/cli_test.go.tmpl", "cli_test.go"},
},
CommandTemplates: []Template{},
},
}

// FrameworkByName retuns Framework
func FrameworkByName(name string) (*Framework, error) {
for _, f := range Frameworks {
if f.Name == name {
return f, nil
}

default:
return -1, fmt.Errorf("invalid framework name: %s", name)
for _, alt := range f.AltNames {
if alt == name {
return f, nil
}
}
}
return nil, fmt.Errorf("invalid framework name: %s", name)
}
64 changes: 0 additions & 64 deletions skeleton/framework_template.go

This file was deleted.

12 changes: 6 additions & 6 deletions skeleton/framework_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ func TestFramework(t *testing.T) {
tests := []struct {
in string
success bool
expt int
expt string
}{
{"codegangsta_cli", true, Framework_codegangsta_cli},
{"not_exist_cli", false, Framework_codegangsta_cli},
{"codegangsta", true, "codegangsta_cli"},
{"not_exist_cli", false, ""},
}

for i, tt := range tests {
out, err := Framework(tt.in)
out, err := FrameworkByName(tt.in)
if tt.success && err != nil {
t.Errorf("#%d expects error not to be occurred: %s", i, err)
}
Expand All @@ -22,8 +22,8 @@ func TestFramework(t *testing.T) {
continue
}

if out != tt.expt {
t.Errorf("#%d expects %d to eq %d", i, out, tt.expt)
if out.Name != tt.expt {
t.Errorf("#%d expects %s to eq %s", i, out.Name, tt.expt)
}
}
}
Loading

0 comments on commit 10f4792

Please sign in to comment.