Skip to content

Commit

Permalink
Start poking around at implementing a cli library for go
Browse files Browse the repository at this point in the history
  • Loading branch information
jordansissel committed Apr 29, 2014
1 parent 70f0831 commit 32475d5
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 0 deletions.
9 changes: 9 additions & 0 deletions go/clago/command.go
@@ -0,0 +1,9 @@
package clago

import (
)

type Command struct {
Name string
options []Option
}
10 changes: 10 additions & 0 deletions go/clago/command_test.go
@@ -0,0 +1,10 @@
package clago

import (
//"testing"
)

//func TestFun(t *testing.T) {
//c := Command{Name:"example"}
//t.Errorf("Option: %v\n", c)
//}
45 changes: 45 additions & 0 deletions go/clago/option.go
@@ -0,0 +1,45 @@
package clago

import (
"github.com/Sirupsen/logrus"
)

var log = logrus.New()

func init() {
log.Formatter = new(logrus.JSONFormatter)
log.Level = logrus.Debug
}

type Validator func(interface{}) error
type Option struct {
Name string
Description string
Parser Parser

validators []Validator
value interface{}
}

func (o *Option) Set(str string) {
logger := log.WithFields(logrus.Fields{"option": o.Name, "value": str})
var err error

logger.Debug("Parsing")
o.value, err = o.Parser.Parse(str)
if err != nil { panic("parse failure") }
logger.WithFields(logrus.Fields{"parsed": o.value}).Debug("Parsed")

logger.Debug("Validating")
for _, validator := range o.validators {
if err = validator(o.value); err != nil { panic("validate failure") }
}
}

func (o *Option) Value() interface{} {
return o.value
}

func (o *Option) AddValidation(v Validator) {
o.validators = append(o.validators, v)
}
70 changes: 70 additions & 0 deletions go/clago/option_parser.go
@@ -0,0 +1,70 @@
package clago

import (
"strconv"
)

type Parser int
const (
String Parser = iota // default parser
Bool
Uint8
Uint16
Uint32
Uint64
Int8
Int16
Int32
Int64
Float32
Float64

// Not really sure this is needed yet? ;)
//Complex64
//Complex128
)

func (p Parser) Parse(value string) (interface{}, error) {
switch p {
case Bool:
switch value {
case "true", "yes", "1": return true, nil
default: return false, nil
}
case Uint8:
conv, err := strconv.ParseUint(value, 0, 8)
return uint8(conv), err
case Uint16:
conv, err := strconv.ParseUint(value, 0, 16)
return uint16(conv), err
case Uint32:
conv, err := strconv.ParseUint(value, 0, 32)
return uint32(conv), err
case Uint64:
conv, err := strconv.ParseUint(value, 0, 64)
return uint64(conv), err
case Int8:
conv, err := strconv.ParseInt(value, 0, 8)
return int8(conv), err
case Int16:
conv, err := strconv.ParseInt(value, 0, 16)
return int16(conv), err
case Int32:
conv, err := strconv.ParseInt(value, 0, 32)
return int32(conv), err
case Int64:
conv, err := strconv.ParseInt(value, 0, 64)
return int64(conv), err
case Float32:
conv, err := strconv.ParseFloat(value, 32)
return float32(conv), err
case Float64:
conv, err := strconv.ParseFloat(value, 64)
return float64(conv), err
//case Complex64:
//case Complex128:
case String:
return value, nil
}
return nil, nil
}
87 changes: 87 additions & 0 deletions go/clago/option_test.go
@@ -0,0 +1,87 @@
package clago

import (
"testing"
//"reflect"
)

func TestDefaultParser(t *testing.T) {
p := String
str := "hello"
v, err := p.Parse(str)
if err != nil {
t.Errorf("String failed to parse")
}
if str != v {
t.Errorf("Strings didn't match")
}
}

func TestNumberParsers(t *testing.T) {
parsers := [...]Parser{ Uint8, Uint16, Uint32, Uint64, Int8, Int16, Int32, Int64, Float32, Float64 }

for _, p := range parsers {
testSpecificParser(t, p)
}
}

func testSpecificParser(t *testing.T, p Parser) {
v, err := p.Parse("100")
if err != nil {
t.Errorf("'100' failed to parse")
}

var ok bool
var equal bool
switch p {
case Uint8:
var i uint8
i, ok = v.(uint8)
equal = i == uint8(100)
case Uint16:
var i uint16
i, ok = v.(uint16)
equal = i == uint16(100)
case Uint32:
var i uint32
i, ok = v.(uint32)
equal = i == uint32(100)
case Uint64:
var i uint64
i, ok = v.(uint64)
equal = i == uint64(100)
case Int8:
var i int8
i, ok = v.(int8)
equal = i == int8(100)
case Int16:
var i int16
i, ok = v.(int16)
equal = i == int16(100)
case Int32:
var i int32
i, ok = v.(int32)
equal = i == int32(100)
case Int64:
var i int64
i, ok = v.(int64)
equal = i == int64(100)
case Float32:
var i float32
i, ok = v.(float32)
equal = i == float32(100)
case Float64:
var i float64
i, ok = v.(float64)
equal = i == float64(100)
case String:
ok = true
equal = v == "100"
}
if !ok {
t.Errorf("Parse %#v expected to return correct type. Got %t", p, v)
}
if !equal {
t.Errorf("Expected %s == %s", v, "100")
}
}

0 comments on commit 32475d5

Please sign in to comment.