Skip to content

Commit

Permalink
[cmd] Add gotmpl to generate code using template
Browse files Browse the repository at this point in the history
- mainly after https://github.com/benbjohnson/tmpl use go/format
- used by gommon log dyweb/gommon#17 to
generate different log level
- follow go's generated code standard, add special header
- comment out usage of `go.rice` in `Ayi install`
  • Loading branch information
at15 committed Jan 3, 2018
1 parent 6c3de0a commit 5e86526
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 2 deletions.
5 changes: 3 additions & 2 deletions .ayi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ dep-install:
- go get github.com/mitchellh/gox
- glide install
install:
- go build -o Ayi
- rice append -i github.com/dyweb/Ayi/app/web --exec Ayi
- go build -o Ayi
# disable it for now
# - rice append -i github.com/dyweb/Ayi/app/web --exec Ayi
- sh -c "mv Ayi $GOPATH/bin/Ayi"
test:
- go install
Expand Down
82 changes: 82 additions & 0 deletions cmd/gotmpl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package cmd

import (
"github.com/spf13/cobra"
"encoding/json"
"io/ioutil"
"html/template"
"bytes"
"strings"
"go/format"
"fmt"
)

// generate go file using go's built in template, port from https://github.com/benbjohnson/tmpl

var gotmplData string
var gotmplDataPath string

var gotmplCmd = &cobra.Command{
Use: "gotmpl",
Short: "generate go file using text/template",
Long: "generate go file using text/template",
Run: func(cmd *cobra.Command, args []string) {
log.Info("go tmpl!")
if len(args) < 1 {
log.Fatal("must provide template file path i.e. logger_gen.go.tmpl")
}
src := args[0]
dst := strings.TrimSuffix(src, ".tmpl")
if src == dst || !strings.HasSuffix(dst, ".go") {
log.Fatal("only template for go code is supported")
}
// parse data
var data interface{}
if gotmplDataPath != "" {
json.Unmarshal(mustRead(gotmplDataPath), &data)
} else if gotmplData != "" {
json.Unmarshal([]byte(gotmplData), &data)
} else {
log.Fatal("no data specified")
}
log.Debugf("data %v", data)
// load template
source := mustRead(src)
// render template
tmpl, err := template.New("main").Parse(string(source))
if err != nil {
log.Fatalf("invalid template %s %v", src, err)
}
var buf bytes.Buffer
// standard header, as suggested by https://github.com/golang/go/issues/13560#issuecomment-288457920
buf.WriteString(fmt.Sprintf("// Code generated by Ayi gotmpl from %s DO NOT EDIT.\n", src))
if err := tmpl.Execute(&buf, data); err != nil {
log.Fatalf("can't render template %v", err)
}
formatted, err := format.Source(buf.Bytes())
if err != nil {
log.Fatalf("can't format code %v", err)
}
// stat -c %a pkg.go
if err := ioutil.WriteFile(dst, formatted, 644); err != nil {
log.Fatalf("can't write generated code to %s %v", dst, err)
}
},
}

func mustRead(p string) []byte {
if b, err := ioutil.ReadFile(p); err != nil {
log.Fatalf("can't read %s %v", p, err)
return nil
} else {
return b
}
}

func init() {
RootCmd.AddCommand(gotmplCmd)

gotmplCmd.Flags().StringVar(&gotmplData, "data", "", "data in json")
gotmplCmd.Flags().StringVar(&gotmplDataPath, "datap", "", "data (json) file path")

}

0 comments on commit 5e86526

Please sign in to comment.