-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[cmd] Add gotmpl to generate code using template
- 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
Showing
2 changed files
with
85 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | ||
|
||
} |