hybridgroup.gobot/cli/generate.go

418 lines
8.5 KiB
Go
Raw Normal View History

2013-12-03 06:50:02 +08:00
package main
import (
"fmt"
2014-12-25 01:53:48 +08:00
"io/ioutil"
2013-12-03 06:50:02 +08:00
"os"
2014-06-10 10:59:59 +08:00
"strings"
2013-12-03 06:50:02 +08:00
"text/template"
2014-07-13 00:49:18 +08:00
"github.com/codegangsta/cli"
2013-12-03 06:50:02 +08:00
)
type config struct {
2014-12-25 03:58:41 +08:00
Package string
2014-06-10 10:59:59 +08:00
Name string
UpperName string
FirstLetter string
Example string
dir string
2013-12-03 06:50:02 +08:00
}
2014-06-10 10:59:59 +08:00
func Generate() cli.Command {
return cli.Command{
Name: "generate",
Usage: "Generate new Gobot adaptors, drivers, and platforms",
2014-06-10 10:59:59 +08:00
Action: func(c *cli.Context) {
valid := false
for _, s := range []string{"adaptor", "driver", "platform"} {
if s == c.Args().First() {
valid = true
}
2014-06-10 10:59:59 +08:00
}
if valid == false {
fmt.Println("Invalid/no subcommand supplied.\n")
fmt.Println("Usage:")
2014-12-25 03:58:41 +08:00
fmt.Println(" gobot generate adaptor <name> [package] # generate a new Gobot adaptor")
fmt.Println(" gobot generate driver <name> [package] # generate a new Gobot driver")
fmt.Println(" gobot generate platform <name> [package] # generate a new Gobot platform")
return
2014-06-10 10:59:59 +08:00
}
2014-12-25 03:58:41 +08:00
if len(c.Args()) < 2 {
fmt.Println("Please provide a one word name.")
return
2014-12-25 01:53:48 +08:00
}
name := strings.ToLower(c.Args()[1])
2014-12-25 03:58:41 +08:00
packageName := name
if len(c.Args()) > 2 {
packageName = strings.ToLower(c.Args()[2])
}
upperName := strings.ToUpper(string(name[0])) + string(name[1:])
2014-06-10 10:59:59 +08:00
cfg := config{
2014-12-25 03:58:41 +08:00
Package: packageName,
2014-07-13 00:49:18 +08:00
UpperName: upperName,
Name: name,
FirstLetter: string(name[0]),
dir: ".",
2014-12-25 01:53:48 +08:00
}
switch c.Args().First() {
case "adaptor":
if err := generateAdaptor(cfg); err != nil {
fmt.Println(err)
}
case "driver":
if err := generateDriver(cfg); err != nil {
fmt.Println(err)
}
case "platform":
pwd, err := os.Getwd()
if err != nil {
fmt.Println(err)
return
}
dir := pwd + "/" + cfg.Name
fmt.Println("Creating", dir)
if err := os.MkdirAll(dir, 0700); err != nil {
fmt.Println(err)
return
}
cfg.dir = dir
examplesDir := dir + "/examples"
fmt.Println("Creating", examplesDir)
if err := os.MkdirAll(examplesDir, 0700); err != nil {
fmt.Println(err)
return
}
if err := generatePlatform(cfg); err != nil {
fmt.Println(err)
}
2014-12-25 01:53:48 +08:00
}
2014-06-10 10:59:59 +08:00
},
2014-02-25 12:18:12 +08:00
}
2013-12-03 06:50:02 +08:00
}
func generate(c config, file string, tmpl string) error {
fileLocation := c.dir + "/" + file
fmt.Println("Creating", fileLocation)
f, err := os.Create(fileLocation)
defer f.Close()
if err != nil {
return err
}
t, err := template.New("").Parse(tmpl)
if err != nil {
return err
}
return t.Execute(f, c)
}
func generateDriver(c config) error {
if err := generate(c, c.Name+"_driver.go", driver()); err != nil {
return err
}
2014-12-25 03:58:41 +08:00
return generate(c, c.Name+"_driver_test.go", driverTest())
}
func generateAdaptor(c config) error {
if err := generate(c, c.Name+"_adaptor.go", adaptor()); err != nil {
return err
}
return generate(c, c.Name+"_adaptor_test.go", adaptorTest())
}
func generatePlatform(c config) error {
if err := generateDriver(c); err != nil {
return err
}
if err := generateAdaptor(c); err != nil {
return err
}
dir := c.dir
exampleDir := dir + "/examples"
c.dir = exampleDir
2014-12-25 03:58:41 +08:00
if err := generate(c, "main.go", example()); err != nil {
return err
}
c.dir = dir
if exp, err := ioutil.ReadFile(exampleDir + "/main.go"); err != nil {
return err
} else {
c.Example = string(exp)
}
return generate(c, "README.md", readme())
}
2013-12-03 06:50:02 +08:00
func adaptor() string {
2014-12-25 03:58:41 +08:00
return `package {{.Package}}
2013-12-03 06:50:02 +08:00
2014-12-25 01:53:48 +08:00
type {{.UpperName}}Adaptor struct {
name string
2014-02-25 12:18:12 +08:00
}
func New{{.UpperName}}Adaptor() *{{.UpperName}}Adaptor {
2014-12-25 01:53:48 +08:00
return &{{.UpperName}}Adaptor{
name: "{{.UpperName}}",
2014-12-25 01:53:48 +08:00
}
2014-02-25 12:18:12 +08:00
}
2014-12-25 01:53:48 +08:00
func ({{.FirstLetter}} *{{.UpperName}}Adaptor) Name() string { return {{.FirstLetter}}.name }
2013-12-03 06:50:02 +08:00
func ({{.FirstLetter}} *{{.UpperName}}Adaptor) SetName(name string) { {{.FirstLetter}}.name = name }
func ({{.FirstLetter}} *{{.UpperName}}Adaptor) Connect() error { return nil }
2014-12-25 01:53:48 +08:00
func ({{.FirstLetter}} *{{.UpperName}}Adaptor) Finalize() error { return nil }
2014-12-25 01:53:48 +08:00
func ({{.FirstLetter}} *{{.UpperName}}Adaptor) Ping() string { return "pong" }
2013-12-03 06:50:02 +08:00
`
}
func driver() string {
2014-12-25 03:58:41 +08:00
return `package {{.Package}}
2013-12-03 06:50:02 +08:00
import (
2014-12-25 01:53:48 +08:00
"time"
"gobot.io/x/gobot"
2013-12-03 06:50:02 +08:00
)
2014-12-25 01:53:48 +08:00
const Hello string = "hello"
2013-12-03 06:50:02 +08:00
2014-12-25 01:53:48 +08:00
type {{.UpperName}}Driver struct {
name string
connection gobot.Connection
interval time.Duration
halt chan bool
gobot.Eventer
gobot.Commander
2014-02-25 12:18:12 +08:00
}
func New{{.UpperName}}Driver(a *{{.UpperName}}Adaptor) *{{.UpperName}}Driver {
2014-12-25 01:53:48 +08:00
{{.FirstLetter}} := &{{.UpperName}}Driver{
name: "{{.UpperName}}",
2014-12-25 01:53:48 +08:00
connection: a,
interval: 500*time.Millisecond,
halt: make(chan bool, 0),
Eventer: gobot.NewEventer(),
Commander: gobot.NewCommander(),
}
{{.FirstLetter}}.AddEvent(Hello)
{{.FirstLetter}}.AddCommand(Hello, func(params map[string]interface{}) interface{} {
return {{.FirstLetter}}.Hello()
})
return {{.FirstLetter}}
}
func ({{.FirstLetter}} *{{.UpperName}}Driver) Name() string { return {{.FirstLetter}}.name }
func ({{.FirstLetter}} *{{.UpperName}}Driver) SetName(name string) { {{.FirstLetter}}.name = name }
2014-12-25 01:53:48 +08:00
func ({{.FirstLetter}} *{{.UpperName}}Driver) Connection() gobot.Connection {
return {{.FirstLetter}}.connection
}
func ({{.FirstLetter}} *{{.UpperName}}Driver) adaptor() *{{.UpperName}}Adaptor {
return {{.FirstLetter}}.Connection().(*{{.UpperName}}Adaptor)
2013-12-03 06:50:02 +08:00
}
2014-12-25 01:53:48 +08:00
func ({{.FirstLetter}} *{{.UpperName}}Driver) Hello() string {
return "hello from " + {{.FirstLetter}}.Name() + "!"
}
func ({{.FirstLetter}} *{{.UpperName}}Driver) Ping() string {
return {{.FirstLetter}}.adaptor().Ping()
}
func ({{.FirstLetter}} *{{.UpperName}}Driver) Start() error {
2014-12-25 01:53:48 +08:00
go func() {
for {
{{.FirstLetter}}.Publish({{.FirstLetter}}.Event(Hello), {{.FirstLetter}}.Hello())
2014-12-25 01:53:48 +08:00
select {
case <- time.After({{.FirstLetter}}.interval):
case <- {{.FirstLetter}}.halt:
return
}
}
}()
return nil
}
func ({{.FirstLetter}} *{{.UpperName}}Driver) Halt() error {
2014-12-25 01:53:48 +08:00
{{.FirstLetter}}.halt <- true
return nil
2014-06-16 08:27:51 +08:00
}
2014-04-02 10:20:38 +08:00
`
}
2014-12-25 01:53:48 +08:00
func example() string {
return `
package main
2014-04-02 10:20:38 +08:00
import (
2014-12-25 01:53:48 +08:00
"../"
"fmt"
"time"
"gobot.io/x/gobot"
2014-04-02 10:20:38 +08:00
)
2014-12-25 01:53:48 +08:00
func main() {
gbot := gobot.NewMaster()
2014-04-02 10:20:38 +08:00
conn := {{.Package}}.New{{.UpperName}}Adaptor()
dev := {{.Package}}.New{{.UpperName}}Driver(conn)
2014-12-25 01:53:48 +08:00
work := func() {
dev.On(dev.Event({{.Package}}.Hello), func(data interface{}) {
2014-12-25 01:53:48 +08:00
fmt.Println(data)
})
gobot.Every(1200*time.Millisecond, func() {
fmt.Println(dev.Ping())
})
}
2014-04-02 10:20:38 +08:00
2014-12-25 01:53:48 +08:00
robot := gobot.NewRobot(
"robot",
[]gobot.Connection{conn},
[]gobot.Device{dev},
work,
)
gbot.AddRobot(robot)
gbot.Start()
2014-06-14 06:09:04 +08:00
}
2014-04-02 10:20:38 +08:00
`
2013-12-03 06:50:02 +08:00
}
2014-12-25 01:53:48 +08:00
func driverTest() string {
2014-12-25 03:58:41 +08:00
return `package {{.Package}}
2014-04-02 10:20:38 +08:00
import (
2014-12-25 01:53:48 +08:00
"testing"
"time"
"gobot.io/x/gobot"
"gobot.io/x/gobot/gobottest"
2014-04-02 10:20:38 +08:00
)
var _ gobot.Driver = (*{{.UpperName}}Driver)(nil)
2014-12-25 01:53:48 +08:00
func Test{{.UpperName}}Driver(t *testing.T) {
d := New{{.UpperName}}Driver(New{{.UpperName}}Adaptor())
2014-12-25 01:53:48 +08:00
gobottest.Assert(t, d.Name(), "{{.UpperName}}")
gobottest.Assert(t, d.Connection().Name(), "{{.UpperName}}")
2014-12-25 01:53:48 +08:00
ret := d.Command(Hello)(nil)
gobottest.Assert(t, ret.(string), "hello from {{.UpperName}}!")
2014-12-25 01:53:48 +08:00
gobottest.Assert(t, d.Ping(), "pong")
2014-12-25 01:53:48 +08:00
gobottest.Assert(t, len(d.Start()), 0)
2014-12-25 01:53:48 +08:00
time.Sleep(d.interval)
2014-12-25 01:53:48 +08:00
sem := make(chan bool, 0)
d.On(d.Event(Hello), func(data interface{}) {
2014-12-25 01:53:48 +08:00
sem <- true
})
select {
case <-sem:
case <-time.After(600 * time.Millisecond):
t.Errorf("Hello Event was not published")
}
gobottest.Assert(t, len(d.Halt()), 0)
2014-12-25 01:53:48 +08:00
d.On(d.Event(Hello), func(data interface{}) {
2014-12-25 01:53:48 +08:00
sem <- true
})
select {
case <-sem:
t.Errorf("Hello Event should not publish after Halt")
case <-time.After(600 * time.Millisecond):
}
2014-06-14 06:09:04 +08:00
}
2014-12-25 01:53:48 +08:00
`
2014-06-14 06:09:04 +08:00
}
2014-12-25 01:53:48 +08:00
func adaptorTest() string {
2014-12-25 03:58:41 +08:00
return `package {{.Package}}
2014-12-25 01:53:48 +08:00
import (
"testing"
"gobot.io/x/gobot"
"gobot.io/x/gobot/gobottest"
2014-12-25 01:53:48 +08:00
)
var _ gobot.Adaptor = (*{{.UpperName}}Adaptor)(nil)
2014-12-25 01:53:48 +08:00
func Test{{.UpperName}}Adaptor(t *testing.T) {
a := New{{.UpperName}}Adaptor()
2014-12-25 01:53:48 +08:00
gobottest.Assert(t, a.Name(), "{{.UpperName}}")
2014-12-25 01:53:48 +08:00
gobottest.Assert(t, len(a.Connect()), 0)
2014-12-25 01:53:48 +08:00
gobottest.Assert(t, a.Ping(), "pong")
2014-12-25 01:53:48 +08:00
gobottest.Assert(t, len(a.Connect()), 0)
2014-12-25 01:53:48 +08:00
gobottest.Assert(t, len(a.Finalize()), 0)
2013-12-03 06:50:02 +08:00
}
`
}
2014-02-25 12:18:12 +08:00
func readme() string {
2014-12-25 03:58:41 +08:00
return `# {{.Package}}
2014-02-25 12:18:12 +08:00
2014-06-10 10:59:59 +08:00
Gobot (http://gobot.io/) is a framework for robotics and physical computing using Go
2014-02-25 12:18:12 +08:00
2014-12-25 03:58:41 +08:00
This repository contains the Gobot adaptor and driver for {{.Package}}.
2014-02-25 12:18:12 +08:00
For more information about Gobot, check out the github repo at
https://gobot.io/x/gobot
2014-02-25 12:18:12 +08:00
## Installing
2014-12-25 03:58:41 +08:00
` + "```bash\ngo get path/to/repo/{{.Package}}\n```" + `
2014-02-25 12:18:12 +08:00
## Using
2014-12-25 01:53:48 +08:00
` + "```go{{.Example}}\n```" + `
2014-02-25 12:18:12 +08:00
## Connecting
2014-12-25 01:53:48 +08:00
Explain how to connect to the device here...
2014-02-25 12:18:12 +08:00
## License
Copyright (c) 2017 <Your Name Here>. Licensed under the <Insert license here> license.
2014-02-25 12:18:12 +08:00
`
}