Skip to content

Commit

Permalink
define StructTagCases to support multiple case style
Browse files Browse the repository at this point in the history
- also make the template easier to extend fields
- refactor template functions
- define tag case style constants
  • Loading branch information
c9s committed Dec 21, 2023
1 parent 1ed4b2b commit 0149243
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 29 deletions.
1 change: 1 addition & 0 deletions boilingcore/boilingcore.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ func (s *State) Run() error {
NoBackReferencing: s.Config.NoBackReferencing,
AlwaysWrapErrors: s.Config.AlwaysWrapErrors,
StructTagCasing: s.Config.StructTagCasing,
StructTagCases: s.Config.StructTagCases,
TagIgnore: make(map[string]struct{}),
Tags: s.Config.Tags,
RelationTag: s.Config.RelationTag,
Expand Down
28 changes: 25 additions & 3 deletions boilingcore/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ import (
"github.com/volatiletech/sqlboiler/v4/importers"
)

type TagCase string

const (
TagCaseCamel TagCase = "camel"
TagCaseSnake TagCase = "snake"
TagCaseTitle TagCase = "title"
)

// Config for the running of the commands
type Config struct {
DriverName string `toml:"driver_name,omitempty" json:"driver_name,omitempty"`
Expand All @@ -39,9 +47,16 @@ type Config struct {
NoBackReferencing bool `toml:"no_back_reference,omitempty" json:"no_back_reference,omitempty"`
AlwaysWrapErrors bool `toml:"always_wrap_errors,omitempty" json:"always_wrap_errors,omitempty"`
Wipe bool `toml:"wipe,omitempty" json:"wipe,omitempty"`
StructTagCasing string `toml:"struct_tag_casing,omitempty" json:"struct_tag_casing,omitempty"`
RelationTag string `toml:"relation_tag,omitempty" json:"relation_tag,omitempty"`
TagIgnore []string `toml:"tag_ignore,omitempty" json:"tag_ignore,omitempty"`

StructTagCases StructTagCases `toml:"struct_tag_cases,omitempty" json:"struct_tag_cases,omitempty"`

// StructTagCasing is a legacy config field, which is migrated to StructTagCases
// when StructTagCasing is used, it will be converted to StructTagCases{All: Value}
// Deprecated: use StructTagCases instead.
StructTagCasing string `toml:"struct_tag_casing,omitempty" json:"struct_tag_casing,omitempty"`

RelationTag string `toml:"relation_tag,omitempty" json:"relation_tag,omitempty"`
TagIgnore []string `toml:"tag_ignore,omitempty" json:"tag_ignore,omitempty"`

Imports importers.Collection `toml:"imports,omitempty" json:"imports,omitempty"`

Expand All @@ -63,6 +78,13 @@ type AutoColumns struct {
Deleted string `toml:"deleted,omitempty" json:"deleted,omitempty"`
}

type StructTagCases struct {
Json TagCase `toml:"json,omitempty" json:"json,omitempty"`
Yaml TagCase `toml:"yaml,omitempty" json:"yaml,omitempty"`
Toml TagCase `toml:"toml,omitempty" json:"toml,omitempty"`
Boil TagCase `toml:"boil,omitempty" json:"boil,omitempty"`
}

// TypeReplace replaces a column type with something else
type TypeReplace struct {
Tables []string `toml:"tables,omitempty" json:"tables,omitempty"`
Expand Down
53 changes: 44 additions & 9 deletions boilingcore/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import (

"github.com/Masterminds/sprig/v3"
"github.com/friendsofgo/errors"
"github.com/volatiletech/sqlboiler/v4/drivers"
"github.com/volatiletech/strmangle"

"github.com/volatiletech/sqlboiler/v4/drivers"
)

// templateData for sqlboiler templates
Expand Down Expand Up @@ -58,8 +59,12 @@ type templateData struct {
RelationTag string

// Generate struct tags as camelCase or snake_case
// Deprecated: use StructTagCases instead.
StructTagCasing string

// Generate struct tags as camelCase or snake_case
StructTagCases StructTagCases

// Contains field names that should have tags values set to '-'
TagIgnore map[string]struct{}

Expand Down Expand Up @@ -133,7 +138,9 @@ func (t templateList) Templates() []string {
return ret
}

func loadTemplates(lazyTemplates []lazyTemplate, testTemplates bool, customFuncs template.FuncMap) (*templateList, error) {
func loadTemplates(
lazyTemplates []lazyTemplate, testTemplates bool, customFuncs template.FuncMap,
) (*templateList, error) {
tpl := template.New("")

for _, t := range lazyTemplates {
Expand Down Expand Up @@ -286,13 +293,14 @@ var templateFunctions = template.FuncMap{
"ignore": strmangle.Ignore,

// 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,
"generateTags": strmangle.GenerateTags,
"generateIgnoreTags": strmangle.GenerateIgnoreTags,
"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,
"generateTagWithCase": generateTagWithCase,
"generateIgnoreTags": strmangle.GenerateIgnoreTags,

// Enum ops
"parseEnumName": strmangle.ParseEnumName,
Expand Down Expand Up @@ -333,3 +341,30 @@ var templateFunctions = template.FuncMap{
"columnDBTypes": drivers.ColumnDBTypes,
"getTable": drivers.GetTable,
}

func generateTagWithCase(tagName, tagValue string, c TagCase, nullable bool) string {
buf := strmangle.GetBuffer()
defer strmangle.PutBuffer(buf)

buf.WriteString(tagName)
buf.WriteString(`:"`)
switch c {
case TagCaseSnake:
// we use snake case by default, so we can simply render the value to the buffer
buf.WriteString(tagValue)
case TagCaseTitle:
buf.WriteString(strmangle.TitleCase(tagValue))
case TagCaseCamel:
buf.WriteString(strmangle.CamelCase(tagValue))
default:
buf.WriteString(tagValue)
}

if nullable {
buf.WriteString(",omitempty")
}

buf.WriteString(`" `)

return buf.String()
}
35 changes: 28 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,20 @@ func preRun(cmd *cobra.Command, args []string) error {
AlwaysWrapErrors: viper.GetBool("always-wrap-errors"),
Wipe: viper.GetBool("wipe"),
StructTagCasing: strings.ToLower(viper.GetString("struct-tag-casing")), // camel | snake | title
TagIgnore: viper.GetStringSlice("tag-ignore"),
RelationTag: viper.GetString("relation-tag"),
TemplateDirs: viper.GetStringSlice("templates"),
Tags: viper.GetStringSlice("tag"),
Replacements: viper.GetStringSlice("replace"),
Aliases: boilingcore.ConvertAliases(viper.Get("aliases")),
TypeReplaces: boilingcore.ConvertTypeReplace(viper.Get("types")),
StructTagCases: boilingcore.StructTagCases{
// make this compatible with the legacy struct-tag-casing config
Json: withDefaultCase(viper.GetString("struct-tag-cases.json"), viper.GetString("struct-tag-casing")),
Yaml: withDefaultCase(viper.GetString("struct-tag-cases.yaml"), viper.GetString("struct-tag-casing")),
Toml: withDefaultCase(viper.GetString("struct-tag-cases.toml"), viper.GetString("struct-tag-casing")),
Boil: withDefaultCase(viper.GetString("struct-tag-cases.boil"), viper.GetString("struct-tag-casing")),
},
TagIgnore: viper.GetStringSlice("tag-ignore"),
RelationTag: viper.GetString("relation-tag"),
TemplateDirs: viper.GetStringSlice("templates"),
Tags: viper.GetStringSlice("tag"),
Replacements: viper.GetStringSlice("replace"),
Aliases: boilingcore.ConvertAliases(viper.Get("aliases")),
TypeReplaces: boilingcore.ConvertTypeReplace(viper.Get("types")),
AutoColumns: boilingcore.AutoColumns{
Created: viper.GetString("auto-columns.created"),
Updated: viper.GetString("auto-columns.updated"),
Expand Down Expand Up @@ -293,3 +300,17 @@ func allKeys(prefix string) []string {
}
return keySlice
}

func withDefaultCase(configCase string, defaultCases ...string) boilingcore.TagCase {
if len(configCase) > 0 {
return boilingcore.TagCase(strings.ToLower(configCase))
}

for _, c := range defaultCases {
if len(c) > 0 {
return boilingcore.TagCase(strings.ToLower(c))
}
}

return boilingcore.TagCaseSnake
}
36 changes: 26 additions & 10 deletions templates/main/00_struct.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,34 @@ type {{$alias.UpSingular}} struct {
{{- $orig_col_name := $column.Name -}}
{{- range $column.Comment | splitLines -}} // {{ . }}
{{end -}}

{{if ignore $orig_tbl_name $orig_col_name $.TagIgnore -}}
{{$colAlias}} {{$column.Type}} `{{generateIgnoreTags $.Tags}}boil:"{{$column.Name}}" json:"-" toml:"-" yaml:"-"`
{{else if eq $.StructTagCasing "title" -}}
{{$colAlias}} {{$column.Type}} `{{generateTags $.Tags $column.Name}}boil:"{{$column.Name}}" json:"{{$column.Name | titleCase}}{{if $column.Nullable}},omitempty{{end}}" toml:"{{$column.Name | titleCase}}" yaml:"{{$column.Name | titleCase}}{{if $column.Nullable}},omitempty{{end}}"`
{{else if eq $.StructTagCasing "camel" -}}
{{$colAlias}} {{$column.Type}} `{{generateTags $.Tags $column.Name}}boil:"{{$column.Name}}" json:"{{$column.Name | camelCase}}{{if $column.Nullable}},omitempty{{end}}" toml:"{{$column.Name | camelCase}}" yaml:"{{$column.Name | camelCase}}{{if $column.Nullable}},omitempty{{end}}"`
{{else if eq $.StructTagCasing "alias" -}}
{{$colAlias}} {{$column.Type}} `{{generateTags $.Tags $colAlias}}boil:"{{$column.Name}}" json:"{{$colAlias}}{{if $column.Nullable}},omitempty{{end}}" toml:"{{$colAlias}}" yaml:"{{$colAlias}}{{if $column.Nullable}},omitempty{{end}}"`
{{else -}}
{{$colAlias}} {{$column.Type}} `{{generateTags $.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 -}}
{{end -}}
{{- else -}}

{{- /* render column alias and column type */ -}}
{{ $colAlias }} {{ $column.Type -}}

{{- /* handle struct tags */ -}}
`
{{- if eq $.StructTagCasing "alias" -}}
{{- generateTags $.Tags $colAlias -}}
{{- generateTagWithCase "json" $colAlias "default" $column.Nullable -}}
{{- generateTagWithCase "yaml" $colAlias "default" $column.Nullable -}}
{{- generateTagWithCase "toml" $colAlias "default" $column.Nullable -}}
{{- generateTagWithCase "boil" $colAlias "default" $column.Nullable -}}
{{- else -}}
{{- generateTags $.Tags $column.Name }}
{{- generateTagWithCase "json" $column.Name $.StructTagCases.Json $column.Nullable -}}
{{- generateTagWithCase "yaml" $column.Name $.StructTagCases.Yaml $column.Nullable -}}
{{- generateTagWithCase "toml" $column.Name $.StructTagCases.Toml $column.Nullable -}}
{{- generateTagWithCase "boil" $column.Name $.StructTagCases.Boil $column.Nullable -}}
{{- end -}}
`

{{ end -}}
{{ end -}}

{{- if or .Table.IsJoinTable .Table.IsView -}}
{{- else}}
R *{{$alias.DownSingular}}R `{{generateTags $.Tags $.RelationTag}}boil:"{{$.RelationTag}}" json:"{{$.RelationTag}}" toml:"{{$.RelationTag}}" yaml:"{{$.RelationTag}}"`
Expand Down

0 comments on commit 0149243

Please sign in to comment.