Skip to content

Commit

Permalink
added GoInitialismsConfig which overrides the initialisms to be regar…
Browse files Browse the repository at this point in the history
…ded (#2683)

* added GoInitialismsConfig which overrides the initialisms to be regarded

* typo

* adjusted examples and documentation

* removed test with side-effects, adjustend yaml indentations, changed example entry "ID" to "CC" (again? I though I already did that)

* comply with linter
  • Loading branch information
JonasDoe authored Jun 21, 2023
1 parent ee6add4 commit 3b295bb
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 57 deletions.
4 changes: 4 additions & 0 deletions codegen/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Config struct {
Models TypeMap `yaml:"models,omitempty"`
StructTag string `yaml:"struct_tag,omitempty"`
Directives map[string]DirectiveConfig `yaml:"directives,omitempty"`
GoInitialisms GoInitialismsConfig `yaml:"go_initialisms,omitempty"`
OmitSliceElementPointers bool `yaml:"omit_slice_element_pointers,omitempty"`
OmitGetters bool `yaml:"omit_getters,omitempty"`
OmitComplexity bool `yaml:"omit_complexity,omitempty"`
Expand Down Expand Up @@ -201,6 +202,9 @@ func CompleteConfig(config *Config) error {

config.Sources = append(config.Sources, &ast.Source{Name: filename, Input: string(schemaRaw)})
}

config.GoInitialisms.setInitialisms()

return nil
}

Expand Down
94 changes: 94 additions & 0 deletions codegen/config/initialisms.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package config

import "strings"

// commonInitialisms is a set of common initialisms.
// Only add entries that are highly unlikely to be non-initialisms.
// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
var commonInitialisms = map[string]bool{
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"CSV": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTP": true,
"HTTPS": true,
"ICMP": true,
"ID": true,
"IP": true,
"JSON": true,
"KVK": true,
"LHS": true,
"PDF": true,
"PGP": true,
"QPS": true,
"QR": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"SVG": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"URI": true,
"URL": true,
"UTF8": true,
"UUID": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
}

// GetInitialisms returns the initialisms to capitalize in Go names. If unchanged, default initialisms will be returned
var GetInitialisms = func() map[string]bool {
return commonInitialisms
}

// GoInitialismsConfig allows to modify the default behavior of naming Go methods, types and properties
type GoInitialismsConfig struct {
// If true, the Initialisms won't get appended to the default ones but replace them
ReplaceDefaults bool `yaml:"replace_defaults"`
// Custom initialisms to be added or to replace the default ones
Initialisms []string `yaml:"initialisms"`
}

// setInitialisms adjustes GetInitialisms based on its settings.
func (i GoInitialismsConfig) setInitialisms() {
toUse := i.determineGoInitialisms()
GetInitialisms = func() map[string]bool {
return toUse
}
}

// determineGoInitialisms returns the Go initialims to be used, based on its settings.
func (i GoInitialismsConfig) determineGoInitialisms() (initialismsToUse map[string]bool) {
if i.ReplaceDefaults {
initialismsToUse = make(map[string]bool, len(i.Initialisms))
for _, initialism := range i.Initialisms {
initialismsToUse[strings.ToUpper(initialism)] = true
}
} else {
initialismsToUse = make(map[string]bool, len(commonInitialisms)+len(i.Initialisms))
for initialism, value := range commonInitialisms {
initialismsToUse[strings.ToUpper(initialism)] = value
}
for _, initialism := range i.Initialisms {
initialismsToUse[strings.ToUpper(initialism)] = true
}
}
return initialismsToUse
}
39 changes: 39 additions & 0 deletions codegen/config/initialisms_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package config

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestGoInitialismsConfig(t *testing.T) {
t.Run("load go initialisms config", func(t *testing.T) {
config, err := LoadConfig("testdata/cfg/goInitialisms.yml")
require.NoError(t, err)
require.True(t, config.GoInitialisms.ReplaceDefaults)
require.Len(t, config.GoInitialisms.Initialisms, 2)
})
t.Run("empty initialism config doesn't change anything", func(t *testing.T) {
tt := GoInitialismsConfig{}
result := tt.determineGoInitialisms()
assert.Equal(t, len(commonInitialisms), len(result))
})
t.Run("initialism config appends if desired", func(t *testing.T) {
tt := GoInitialismsConfig{ReplaceDefaults: false, Initialisms: []string{"ASDF"}}
result := tt.determineGoInitialisms()
assert.Equal(t, len(commonInitialisms)+1, len(result))
assert.True(t, result["ASDF"])
})
t.Run("initialism config replaces if desired", func(t *testing.T) {
tt := GoInitialismsConfig{ReplaceDefaults: true, Initialisms: []string{"ASDF"}}
result := tt.determineGoInitialisms()
assert.Equal(t, 1, len(result))
assert.True(t, result["ASDF"])
})
t.Run("initialism config uppercases the initialsms", func(t *testing.T) {
tt := GoInitialismsConfig{Initialisms: []string{"asdf"}}
result := tt.determineGoInitialisms()
assert.True(t, result["ASDF"])
})
}
5 changes: 5 additions & 0 deletions codegen/config/testdata/cfg/goInitialisms.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
go_initialisms:
replace_defaults: true
initialisms:
- 'CC'
- 'BCC'
58 changes: 4 additions & 54 deletions codegen/templates/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,22 +465,23 @@ func wordWalker(str string, f func(*wordInfo)) {
}
i++

initialisms := config.GetInitialisms()
// [w,i) is a word.
word := string(runes[w:i])
if !eow && commonInitialisms[word] && !unicode.IsLower(runes[i]) {
if !eow && initialisms[word] && !unicode.IsLower(runes[i]) {
// through
// split IDFoo → ID, Foo
// but URLs → URLs
} else if !eow {
if commonInitialisms[word] {
if initialisms[word] {
hasCommonInitial = true
}
continue
}

matchCommonInitial := false
upperWord := strings.ToUpper(word)
if commonInitialisms[upperWord] {
if initialisms[upperWord] {
// If the uppercase word (string(runes[w:i]) is "ID" or "IP"
// AND
// the word is the first two characters of the str
Expand Down Expand Up @@ -553,57 +554,6 @@ func sanitizeKeywords(name string) string {
return name
}

// commonInitialisms is a set of common initialisms.
// Only add entries that are highly unlikely to be non-initialisms.
// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
var commonInitialisms = map[string]bool{
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"CSV": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTP": true,
"HTTPS": true,
"ICMP": true,
"ID": true,
"IP": true,
"JSON": true,
"KVK": true,
"LHS": true,
"PDF": true,
"PGP": true,
"QPS": true,
"QR": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"SVG": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"URI": true,
"URL": true,
"UTF8": true,
"UUID": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
}

func rawQuote(s string) string {
return "`" + strings.ReplaceAll(s, "`", "`+\"`\"+`") + "`"
}
Expand Down
12 changes: 9 additions & 3 deletions docs/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ menu:
security:
funcs:
getenv:
- '^HUGO_'
- 'VERSIONS'
- 'CURRENT_VERSION'
- '^HUGO_'
- 'VERSIONS'
- 'CURRENT_VERSION'

go_initialisms:
replace_defaults: false
initialisms:
- 'CC'
- 'BCC'
7 changes: 7 additions & 0 deletions docs/content/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ resolver:
# Optional: set to skip running `go mod tidy` when generating server code
# skip_mod_tidy: true

# Optional: set to modify the initialisms regarded for Go names
# go_initialisms:
# replace_defaults: false # if true, the default initialisms will get dropped in favor of the new ones instead of being added
# initialisms: # List of initialisms to for Go names
# - 'CC'
# - 'BCC'

# gqlgen will search for any type names in the schema in these go packages
# if they match it will use them, otherwise it will generate them.
# autobind:
Expand Down

0 comments on commit 3b295bb

Please sign in to comment.