1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
package modelgen
import (
"bytes"
"fmt"
"go/format"
"io/ioutil"
"log"
"text/template"
)
// Generator is an interface that allows to format code from a template and write it to a file
type Generator interface {
Generate(string, *template.Template, interface{}) error
Format(*template.Template, interface{}) ([]byte, error)
}
type generator struct {
dryRun bool
}
// Format returns a formatted byte slice by executing the template with the given args
func (g *generator) Format(tmpl *template.Template, args interface{}) ([]byte, error) {
buffer := bytes.Buffer{}
err := tmpl.Execute(&buffer, args)
if err != nil {
return nil, err
}
src, err := format.Source(buffer.Bytes())
if err != nil {
return nil, err
}
return src, nil
}
// Generate generates the code and writes it to specified file path
func (g *generator) Generate(filename string, tmpl *template.Template, args interface{}) error {
src, err := g.Format(tmpl, args)
if err != nil {
return err
}
if g.dryRun {
log.Printf("---- Content of file %s ----\n", filename)
log.Print(string(src))
fmt.Print("\n")
return nil
}
content, err := ioutil.ReadFile(filename)
if err == nil && bytes.Equal(content, src) {
return nil
}
return ioutil.WriteFile(filename, src, 0644)
}
// NewGenerator returns a new Generator
func NewGenerator(opts ...Option) (Generator, error) {
options, err := newOptions(opts...)
if err != nil {
return nil, err
}
return &generator{
dryRun: options.dryRun,
}, nil
}
|