Skip to content

Commit

Permalink
optimize: command action & context & regexp
Browse files Browse the repository at this point in the history
  • Loading branch information
WindomZ committed Mar 8, 2017
1 parent b6a3bbd commit 1e51aae
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 31 deletions.
23 changes: 21 additions & 2 deletions actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,34 @@ package commander
type actor struct {
names []string
action Action
keys []string
}

func (a *actor) Action(action Action) {
func (a *actor) addKeys(keys []string) {
if keys != nil && len(keys) != 0 {
a.keys = append(a.keys, keys...)
}
}

func (a *actor) Action(action Action, keys ...[]string) {
a.action = action
if len(keys) != 0 {
a.addKeys(keys[0])
}
}

func (a actor) allow(c *Context) (b bool) {
for _, key := range a.names {
b, _ = c.Doc.GetBool(key)
if b, _ = c.Doc.GetBool(key); b {
return
}
}
for _, key := range a.keys {
if b, _ = c.Doc.GetBool(key); b {
return
} else if b = c.Doc.Contain(key); b {
return
}
}
return
}
Expand Down
12 changes: 8 additions & 4 deletions arguments.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package commander

import "regexp"

type Arguments []*Argument

func (a Arguments) IsEmpty() bool {
Expand All @@ -10,14 +8,20 @@ func (a Arguments) IsEmpty() bool {

func (a *Arguments) Set(usage string) {
*a = (*a)[:0]
if strs := regexp.MustCompile(`(?i:<|\[)[A-Za-z0-9_\[\]<>-]+(?i:>|])`).
FindAllString(usage, -1); len(strs) != 0 {
if strs := RegexpArgument(usage); len(strs) != 0 {
for _, str := range strs {
*a = append(*a, newArgument(str))
}
}
}

func (a Arguments) Get() (r []string) {
for _, arg := range a {
r = append(r, arg.name)
}
return
}

func (a Arguments) UsagesString() (r []string) {
for _, arg := range a {
r = append(r, arg.UsageString())
Expand Down
19 changes: 11 additions & 8 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package commander
import (
"bytes"
"fmt"
"regexp"
"os"
"strings"
)

Expand Down Expand Up @@ -44,8 +44,7 @@ func newCommand(usage string, root bool, args ...interface{}) *Command {
}

func (c *Command) regexpNames() {
c.names = regexp.MustCompile(`[A-Za-z0-9_-]+`).FindAllString(
regexp.MustCompile(`^[A-Za-z0-9_|\(\)\s-]+`).FindString(c.usage), -1)
c.names = RegexpCommand(c.usage)
}

func (c *Command) regexpArguments() {
Expand Down Expand Up @@ -91,8 +90,8 @@ func (c *Command) Annotation(title string, contents []string) Commander {
return c
}

func (c *Command) Action(action Action) Commander {
c.actor.Action(action)
func (c *Command) Action(action Action, keys ...[]string) Commander {
c.actor.Action(action, keys...)
return c
}

Expand Down Expand Up @@ -131,6 +130,7 @@ func (c *Command) LineArgument(usage string, args ...interface{}) Commander {
if cmd.arguments.IsEmpty() {
return cmd
}
cmd.addKeys(cmd.arguments.Get())
c.commands = append(c.commands, cmd)
return cmd
}
Expand Down Expand Up @@ -232,11 +232,14 @@ func (c Command) Parse(args ...[]string) (*Context, error) {
if len(args) != 0 {
argv = args[0]
}
if argv == nil && len(os.Args) > 1 {
argv = os.Args
}
d, err := Parse(c.GetHelpMessage(), argv, true, c.version, false)
if err != nil {
return nil, err
}
context := newContext(d)
context := newContext(argv, d)
if r := c.run(context); r != nil {
if r.Break() {
return context, r.Error()
Expand All @@ -252,10 +255,10 @@ func (c Command) run(context *Context) Result {
if r := c.options.run(context); r != nil && r.Break() {
return r
}
if r := c.actor.run(context); r != nil && r.Break() {
if r := c.commands.run(context); r != nil && r.Break() {
return r
}
return c.commands.run(context)
return c.actor.run(context)
}
return nil
}
2 changes: 1 addition & 1 deletion commander.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type Commander interface {
Version(ver string) Commander
Description(desc string) Commander
Annotation(title string, contents []string) Commander
Action(action Action) Commander
Action(action Action, keys ...[]string) Commander
Command(usage string, args ...interface{}) Commander
Option(usage string, args ...interface{}) Commander
LineArgument(usage string, args ...interface{}) Commander
Expand Down
14 changes: 11 additions & 3 deletions context.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package commander

import "fmt"

type Context struct {
Doc DocoptMap
Args ContextArgs
Doc DocoptMap
}

func newContext(d DocoptMap) *Context {
func newContext(args []string, d DocoptMap) *Context {
return &Context{
Doc: d,
Args: ContextArgs(args),
Doc: d,
}
}

func (c Context) String() string {
return fmt.Sprintf("%#v", c)
}
26 changes: 26 additions & 0 deletions context_args.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package commander

import "strings"

type ContextArgs []string

func (c ContextArgs) Get(index int) string {
if index >= 0 && index < len(c) {
return c[index]
}
return ""
}

func (c ContextArgs) String(offsets ...int) string {
var offset int = 0
if len(offsets) != 0 {
offset = offsets[0]
}
if len(c) <= offset {
offset = len(c) - 1
}
if offset < 0 {
offset = 0
}
return strings.Join(c[offset:], "")
}
13 changes: 11 additions & 2 deletions docopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ func (d DocoptMap) Get(key string) interface{} {
}

func (d DocoptMap) Contain(key string) bool {
_, ok := d[key]
return ok
v, ok := d[key]
return ok && v != nil
}

func (d DocoptMap) GetString(key string) string {
Expand All @@ -29,6 +29,15 @@ func (d DocoptMap) GetString(key string) string {
return ""
}

func (d DocoptMap) GetStrings(key string) []string {
if v := d.Get(key); v != nil {
if s, ok := v.([]string); ok {
return s
}
}
return []string{}
}

func (d DocoptMap) GetBool(key string) (bool, bool) {
b, err := strconv.ParseBool(d.GetString(key))
return b, err == nil
Expand Down
4 changes: 1 addition & 3 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ func newOption(usage string, args ...interface{}) *Option {
}

func (o *Option) regexpNames() {
o.names = regexp.MustCompile(`-{1,2}[A-Za-z0-9_-]+\b`).
FindAllString(regexp.MustCompile(`(<|\[)[A-Za-z0-9_\[\]<>-]+\b(>|])`).
ReplaceAllString(o.usage, ""), -1)
o.names = RegexpOption(o.usage)
}

func (o *Option) regexpArguments() {
Expand Down
17 changes: 17 additions & 0 deletions regexp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package commander

import "regexp"

func RegexpCommand(str string) []string {
return regexp.MustCompile(`[A-Za-z0-9_-]+`).FindAllString(
regexp.MustCompile(`^[A-Za-z0-9_|\(\)\s-]+`).FindString(str), -1)
}
func RegexpArgument(str string) []string {
return regexp.MustCompile(`(?i:<|\[)[A-Za-z0-9_\[\]<>-]+\b(?i:>|])`).
FindAllString(str, -1)
}
func RegexpOption(str string) []string {
return regexp.MustCompile(`-{1,2}[A-Za-z0-9_-]+\b`).
FindAllString(regexp.MustCompile(`(<|\[)[A-Za-z0-9_\[\]<>-]+\b(>|])`).
ReplaceAllString(str, ""), -1)
}
63 changes: 63 additions & 0 deletions regexp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package commander

import (
"github.com/WindomZ/testify/assert"
"testing"
)

func TestRegexpCommand(t *testing.T) {
assert.Equal(t,
RegexpCommand("new <name>"),
[]string{"new"},
)
assert.Equal(t,
RegexpCommand("ship <name> move <x> <y>"),
[]string{"ship"},
)
assert.Equal(t,
RegexpCommand("(set|remove) <x> <y> [--moored|--drifting]"),
[]string{"set", "remove"},
)
}

func TestRegexpArgument(t *testing.T) {
assert.Equal(t,
RegexpArgument("new <name>"),
[]string{"<name>"},
)
assert.Equal(t,
RegexpArgument("ship <name> move <x> <y>"),
[]string{"<name>", "<x>", "<y>"},
)
assert.Equal(t,
RegexpArgument("(set|remove) <x> <y> [--moored|--drifting]"),
[]string{"<x>", "<y>"},
)
}

func TestRegexpOption(t *testing.T) {
assert.Equal(t,
RegexpOption("new <name>"),
[]string(nil),
)
assert.Equal(t,
RegexpOption("-p <x-y>"),
[]string{"-p"},
)
assert.Equal(t,
RegexpOption("-p"),
[]string{"-p"},
)
assert.Equal(t,
RegexpOption("-p, --pepper"),
[]string{"-p", "--pepper"},
)
assert.Equal(t,
RegexpOption("--pepper"),
[]string{"--pepper"},
)
assert.Equal(t,
RegexpOption("(set|remove) <x> <y> [--not-ss | -a | --moored|--drifting]"),
[]string{"--not-ss", "-a", "--moored", "--drifting"},
)
}
12 changes: 4 additions & 8 deletions tests/regexp.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
package tests

import "regexp"
import "github.com/WindomZ/go-commander"

func RegexpCommand(str string) []string {
return regexp.MustCompile(`[A-Za-z0-9_-]+\b`).FindAllString(
regexp.MustCompile(`^[A-Za-z0-9_|\(\)\s-]+`).FindString(str), -1)
return commander.RegexpCommand(str)
}
func RegexpArgument(str string) []string {
return regexp.MustCompile(`(?i:<|\[)[A-Za-z0-9_\[\]<>-]+\b(?i:>|])`).
FindAllString(str, -1)
return commander.RegexpArgument(str)
}
func RegexpOption(str string) []string {
return regexp.MustCompile(`-{1,2}[A-Za-z0-9_-]+\b`).
FindAllString(regexp.MustCompile(`(<|\[)[A-Za-z0-9_\[\]<>-]+\b(>|])`).
ReplaceAllString(str, ""), -1)
return commander.RegexpOption(str)
}

0 comments on commit 1e51aae

Please sign in to comment.