3
0

Add codegen template + logic, modifiyed codegen.go to accept new files

This commit is contained in:
Urban Klinc
2020-11-26 10:17:52 +01:00
parent 0d632dfdae
commit df9ebe54aa
3 changed files with 191 additions and 3 deletions

View File

@@ -0,0 +1,48 @@
package {{ .Package }}
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// {{ .Source }}
{{ if $.Imports -}}
import (
{{- range .Imports }}
{{ normalizeImport . }}
{{- end }}
){{ end }}
type (
{{ export $.Name }}Opt struct {
{{- range $prop := $.Properties}}
{{ export $prop.Name }} {{ $prop.Type }} `env:"{{ toUpper $prop.Env}}"`
{{- end }}
}
)
// {{ export $.Name }} initializes and returns a {{ export $.Name }}Opt with default values
func {{ export $.Name }}() (o *{{ export $.Name }}Opt) {
o = &{{ export $.Name }}Opt{
{{- range $prop := $.Properties }}
{{- if $prop.Default }}
{{ export $prop.Name }}: {{ $prop.Default }},
{{- end }}
{{- end }}
}
fill(o)
// Function that allows access to custom logic inside the parent function.
// The custom logic in the other file should be like:
// func (o *{{ export $.Name}}) Defaults() {...}
func(o interface{}) {
if def, ok := o.(interface{ Defaults() }); ok {
def.Defaults()
}
}(o)
return
}

View File

@@ -3,13 +3,14 @@ package codegen
import (
"flag"
"fmt"
"github.com/Masterminds/sprig"
"github.com/cortezaproject/corteza-server/pkg/cli"
"github.com/fsnotify/fsnotify"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/Masterminds/sprig"
"github.com/cortezaproject/corteza-server/pkg/cli"
"github.com/fsnotify/fsnotify"
)
func Proc() {
@@ -47,6 +48,10 @@ func Proc() {
storeSrc []string
storeDefs []*storeDef
optionSrcPath = filepath.Join("pkg", "options", "*.yaml")
optionSrc []string
optionDefs []*optionsDef
tpls *template.Template
tplBase = template.New("").
Funcs(map[string]interface{}{
@@ -55,6 +60,7 @@ func Proc() {
"unexport": unexport,
"toggleExport": toggleExport,
"toLower": strings.ToLower,
"toUpper": strings.ToUpper,
"cc2underscore": cc2underscore,
"normalizeImport": normalizeImport,
"comment": func(text string, skip1st bool) string {
@@ -123,6 +129,9 @@ func Proc() {
storeSrc = glob(storeSrcPath)
output("loaded %d store definitions from %s\n", len(storeSrc), storeSrcPath)
optionSrc = glob(optionSrcPath)
output("loaded %d option defenitions from %s\n", len(optionSrc), optionSrcPath)
if watchChanges {
if watcher != nil {
watcher.Close()
@@ -137,6 +146,7 @@ func Proc() {
fileList = append(fileList, typeSrc...)
fileList = append(fileList, restSrc...)
fileList = append(fileList, storeSrc...)
fileList = append(fileList, optionSrc...)
for _, d := range fileList {
cli.HandleError(watcher.Add(d))
@@ -189,6 +199,14 @@ func Proc() {
return
}
if optionDefs, err = procOptions(optionSrc...); err == nil {
err = genOptions(tpls, optionDefs...)
}
if outputErr(err, "fail to process options:\n") {
return
}
}()
if !watchChanges {

122
pkg/codegen/options.go Normal file
View File

@@ -0,0 +1,122 @@
package codegen
import (
"fmt"
"io"
"os"
"path"
"strings"
"text/template"
"gopkg.in/yaml.v3"
)
type (
optionsDef struct {
Source string
outputDir string
Name string
// List of imports
// Used only by generated file and not pre-generated-user-file
Imports []string `yaml:"imports"`
Properties optionsPropSet `yaml:"props"`
}
optionsPropSet []*optionsProp
optionsProp struct {
Name string
Type string
Env string
Default *optionsPropDefault
}
optionsPropDefault string
)
// Processes multiple options defenitions
func procOptions(mm ...string) (dd []*optionsDef, err error) {
var (
f io.ReadCloser
d *optionsDef
)
dd = make([]*optionsDef, 0)
for _, m := range mm {
err = func() error {
if f, err = os.Open(m); err != nil {
return err
}
defer f.Close()
d = &optionsDef{}
if err := yaml.NewDecoder(f).Decode(d); err != nil {
return err
}
for _, j := range d.Properties {
if j.Type == "" {
j.Type = "string"
}
if j.Env == "" {
j.Env = strings.ToUpper(d.Name + "_" + cc2underscore(j.Name))
}
}
d.Source = m
d.outputDir = path.Dir(m)
dd = append(dd, d)
return nil
}()
if err != nil {
return nil, fmt.Errorf("could not process %s: %w", m, err)
}
}
return dd, nil
}
// Custom UnmarshelYAML function for
func (pd *optionsPropDefault) UnmarshalYAML(n *yaml.Node) error {
val := n.Value
if n.Style == yaml.DoubleQuotedStyle {
val = "\"" + val + "\""
}
*pd = optionsPropDefault(val)
return nil
}
// Gets package name from file path
func (o optionsDef) Package() string {
return path.Base(path.Dir(o.Source))
}
func genOptions(tpl *template.Template, dd ...*optionsDef) (err error) {
var (
tplOptionsGen = tpl.Lookup("options.go.tpl")
dst string
)
for _, d := range dd {
dst = path.Join(d.outputDir, path.Base(d.Source)[:strings.LastIndex(path.Base(d.Source), ".")]+".gen.go")
err = goTemplate(dst, tplOptionsGen, d)
if err != nil {
return
}
}
return nil
}