Add struct tags flag
This commit is contained in:
parent
e35ecd76c1
commit
4e8191b8dd
7 changed files with 116 additions and 10 deletions
|
@ -7,6 +7,7 @@ type Config struct {
|
|||
OutFolder string
|
||||
BaseDir string
|
||||
ExcludeTables []string
|
||||
Tags []string
|
||||
Debug bool
|
||||
NoTests bool
|
||||
NoHooks bool
|
||||
|
|
11
main.go
11
main.go
|
@ -64,6 +64,7 @@ func main() {
|
|||
rootCmd.PersistentFlags().StringP("pkgname", "p", "models", "The name you wish to assign to your generated package")
|
||||
rootCmd.PersistentFlags().StringP("basedir", "b", "", "The base directory has the templates and templates_test folders")
|
||||
rootCmd.PersistentFlags().StringSliceP("exclude", "x", nil, "Tables to be excluded from the generated package")
|
||||
rootCmd.PersistentFlags().StringSliceP("tag", "t", nil, "Struct tags to be included on your models in addition to json, yaml, toml")
|
||||
rootCmd.PersistentFlags().BoolP("debug", "d", false, "Debug mode prints stack traces on error")
|
||||
rootCmd.PersistentFlags().BoolP("no-tests", "", false, "Disable generated go test files")
|
||||
rootCmd.PersistentFlags().BoolP("no-hooks", "", false, "Disable hooks feature for your models")
|
||||
|
@ -114,7 +115,7 @@ func preRun(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
// BUG: https://github.com/spf13/viper/issues/200
|
||||
// Look up the value of ExcludeTables directly from PFlags in Cobra if we
|
||||
// Look up the value of ExcludeTables & Tags directly from PFlags in Cobra if we
|
||||
// detect a malformed value coming out of viper.
|
||||
// Once the bug is fixed we'll be able to move this into the init above
|
||||
cmdConfig.ExcludeTables = viper.GetStringSlice("exclude")
|
||||
|
@ -125,6 +126,14 @@ func preRun(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
}
|
||||
|
||||
cmdConfig.Tags = viper.GetStringSlice("tag")
|
||||
if len(cmdConfig.Tags) == 1 && strings.HasPrefix(cmdConfig.Tags[0], "[") {
|
||||
cmdConfig.Tags, err = cmd.PersistentFlags().GetStringSlice("tag")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if viper.IsSet("postgres.dbname") {
|
||||
cmdConfig.Postgres = PostgresConfig{
|
||||
User: viper.GetString("postgres.user"),
|
||||
|
|
23
sqlboiler.go
23
sqlboiler.go
|
@ -8,6 +8,7 @@ import (
|
|||
"go/build"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
|
@ -82,6 +83,11 @@ func New(config *Config) (*State, error) {
|
|||
return nil, errors.Wrap(err, "unable to initialize templates")
|
||||
}
|
||||
|
||||
err = s.initTags(config.Tags)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to initialize struct tags")
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
@ -126,6 +132,7 @@ func (s *State) Run(includeTests bool) error {
|
|||
PkgName: s.Config.PkgName,
|
||||
NoHooks: s.Config.NoHooks,
|
||||
NoAutoTimestamps: s.Config.NoAutoTimestamps,
|
||||
Tags: s.Config.Tags,
|
||||
|
||||
StringFuncs: templateStringMappers,
|
||||
}
|
||||
|
@ -250,6 +257,22 @@ func (s *State) initTables(exclude []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Tags must be in a format like: json, xml, etc.
|
||||
var rgxValidTag = regexp.MustCompile(`[a-zA-Z_\.]+`)
|
||||
|
||||
// initTags removes duplicate tags and validates the format
|
||||
// of all user tags are simple strings without quotes: [a-zA-Z_\.]+
|
||||
func (s *State) initTags(tags []string) error {
|
||||
s.Config.Tags = removeDuplicates(s.Config.Tags)
|
||||
for _, v := range s.Config.Tags {
|
||||
if !rgxValidTag.MatchString(v) {
|
||||
return errors.New("Invalid tag format %q supplied, only specify name, eg: xml")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// initOutFolder creates the folder that will hold the generated output.
|
||||
func (s *State) initOutFolder() error {
|
||||
return os.MkdirAll(s.Config.OutFolder, os.ModePerm)
|
||||
|
|
|
@ -487,3 +487,35 @@ func ContainsAny(a []string, finds ...string) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
// GenerateTags converts a slice of tag strings into tags that
|
||||
// can be passed onto the end of a struct, for example:
|
||||
// tags: ["xml", "db"] convert to: xml:"column_name" db:"column_name"
|
||||
func GenerateTags(tags []string, columnName string) string {
|
||||
buf := GetBuffer()
|
||||
defer PutBuffer(buf)
|
||||
|
||||
for _, tag := range tags {
|
||||
buf.WriteString(tag)
|
||||
buf.WriteString(`:"`)
|
||||
buf.WriteString(columnName)
|
||||
buf.WriteString(`" `)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// GenerateIgnoreTags converts a slice of tag strings into
|
||||
// ignore tags that can be passed onto the end of a struct, for example:
|
||||
// tags: ["xml", "db"] convert to: xml:"-" db:"-"
|
||||
func GenerateIgnoreTags(tags []string) string {
|
||||
buf := GetBuffer()
|
||||
defer PutBuffer(buf)
|
||||
|
||||
for _, tag := range tags {
|
||||
buf.WriteString(tag)
|
||||
buf.WriteString(`:"-" `)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
|
|
@ -426,3 +426,41 @@ func TestContainsAny(t *testing.T) {
|
|||
t.Errorf("Should not return true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTags(t *testing.T) {
|
||||
tags := GenerateTags([]string{}, "col_name")
|
||||
if tags != "" {
|
||||
t.Errorf("Expected empty string, got %s", tags)
|
||||
}
|
||||
|
||||
tags = GenerateTags([]string{"xml"}, "col_name")
|
||||
exp := `xml:"col_name" `
|
||||
if tags != exp {
|
||||
t.Errorf("expected %s, got %s", exp, tags)
|
||||
}
|
||||
|
||||
tags = GenerateTags([]string{"xml", "db"}, "col_name")
|
||||
exp = `xml:"col_name" db:"col_name" `
|
||||
if tags != exp {
|
||||
t.Errorf("expected %s, got %s", exp, tags)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateIgnoreTags(t *testing.T) {
|
||||
tags := GenerateIgnoreTags([]string{})
|
||||
if tags != "" {
|
||||
t.Errorf("Expected empty string, got %s", tags)
|
||||
}
|
||||
|
||||
tags = GenerateIgnoreTags([]string{"xml"})
|
||||
exp := `xml:"-" `
|
||||
if tags != exp {
|
||||
t.Errorf("expected %s, got %s", exp, tags)
|
||||
}
|
||||
|
||||
tags = GenerateIgnoreTags([]string{"xml", "db"})
|
||||
exp = `xml:"-" db:"-" `
|
||||
if tags != exp {
|
||||
t.Errorf("expected %s, got %s", exp, tags)
|
||||
}
|
||||
}
|
||||
|
|
13
templates.go
13
templates.go
|
@ -20,6 +20,7 @@ type templateData struct {
|
|||
PkgName string
|
||||
NoHooks bool
|
||||
NoAutoTimestamps bool
|
||||
Tags []string
|
||||
|
||||
StringFuncs map[string]func(string) string
|
||||
}
|
||||
|
@ -124,11 +125,13 @@ var templateFunctions = template.FuncMap{
|
|||
"camelCase": strmangle.CamelCase,
|
||||
|
||||
// String Slice ops
|
||||
"join": func(sep string, slice []string) string { return strings.Join(slice, sep) },
|
||||
"joinSlices": strmangle.JoinSlices,
|
||||
"stringMap": strmangle.StringMap,
|
||||
"prefixStringSlice": strmangle.PrefixStringSlice,
|
||||
"containsAny": strmangle.ContainsAny,
|
||||
"join": func(sep string, slice []string) string { return strings.Join(slice, sep) },
|
||||
"joinSlices": strmangle.JoinSlices,
|
||||
"stringMap": strmangle.StringMap,
|
||||
"prefixStringSlice": strmangle.PrefixStringSlice,
|
||||
"containsAny": strmangle.ContainsAny,
|
||||
"generateTags": strmangle.GenerateTags,
|
||||
"generateIgnoreTags": strmangle.GenerateIgnoreTags,
|
||||
|
||||
// String Map ops
|
||||
"makeStringMap": strmangle.MakeStringMap,
|
||||
|
|
|
@ -2,22 +2,22 @@
|
|||
{{.Function.Name}} *{{.ForeignTable.NameGo}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $dot := . -}}
|
||||
{{- $tableNameSingular := .Table.Name | singular -}}
|
||||
{{- $modelName := $tableNameSingular | titleCase -}}
|
||||
{{- $modelNameCamel := $tableNameSingular | camelCase -}}
|
||||
// {{$modelName}} is an object representing the database table.
|
||||
type {{$modelName}} struct {
|
||||
{{range $column := .Table.Columns -}}
|
||||
{{titleCase $column.Name}} {{$column.Type}} `boil:"{{$column.Name}}" json:"{{$column.Name}}{{if $column.Nullable}},omitempty{{end}}" toml:"{{$column.Name}}" yaml:"{{$column.Name}}{{if $column.Nullable}},omitempty{{end}}"`
|
||||
{{titleCase $column.Name}} {{$column.Type}} `{{generateTags $dot.Tags $column.Name}}boil:"{{$column.Name}}" json:"{{$column.Name}}{{if $column.Nullable}},omitempty{{end}}" toml:"{{$column.Name}}" yaml:"{{$column.Name}}{{if $column.Nullable}},omitempty{{end}}"`
|
||||
{{end -}}
|
||||
{{- if .Table.IsJoinTable -}}
|
||||
{{- else}}
|
||||
R *{{$modelNameCamel}}R `boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
L {{$modelNameCamel}}L `boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
R *{{$modelNameCamel}}R `{{generateIgnoreTags $dot.Tags}}boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
L {{$modelNameCamel}}L `{{generateIgnoreTags $dot.Tags}}boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
{{end -}}
|
||||
}
|
||||
|
||||
{{- $dot := . -}}
|
||||
{{- if .Table.IsJoinTable -}}
|
||||
{{- else}}
|
||||
// {{$modelNameCamel}}R is where relationships are stored.
|
||||
|
|
Loading…
Add table
Reference in a new issue