From d07d22a910524921889f754e93a2d5255e3e612a Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Thu, 16 Dec 2021 14:45:17 +0300 Subject: [PATCH 1/3] Capitalize prefix/suffix acronyms in default resource config's kind name Signed-off-by: Alper Rifat Ulucinar --- pkg/config/defaults.go | 4 ++- pkg/types/builder.go | 5 ++-- pkg/types/{ => name}/name.go | 20 ++++++++++++++- pkg/types/{ => name}/name_test.go | 41 ++++++++++++++++++++++++++++++- pkg/types/reference.go | 5 ++-- 5 files changed, 68 insertions(+), 7 deletions(-) rename pkg/types/{ => name}/name.go (90%) rename pkg/types/{ => name}/name_test.go (83%) diff --git a/pkg/config/defaults.go b/pkg/config/defaults.go index c31baf61..c4947b6a 100644 --- a/pkg/config/defaults.go +++ b/pkg/config/defaults.go @@ -21,6 +21,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/iancoleman/strcase" + + typeName "github.com/crossplane-contrib/terrajet/pkg/types/name" ) // Commonly used resource configurations. @@ -95,7 +97,7 @@ func DefaultResource(name string, terraformSchema *schema.Resource, opts ...Reso Name: name, TerraformResource: terraformSchema, ShortGroup: group, - Kind: kind, + Kind: typeName.CapitalizeAcronyms(kind), Version: "v1alpha1", ExternalName: NameAsIdentifier, References: map[string]Reference{}, diff --git a/pkg/types/builder.go b/pkg/types/builder.go index a492b748..1acc469a 100644 --- a/pkg/types/builder.go +++ b/pkg/types/builder.go @@ -30,6 +30,7 @@ import ( "github.com/crossplane-contrib/terrajet/pkg/config" "github.com/crossplane-contrib/terrajet/pkg/types/comments" + "github.com/crossplane-contrib/terrajet/pkg/types/name" ) const ( @@ -102,7 +103,7 @@ func (g *Builder) buildResource(res *schema.Resource, cfg *config.Resource, tfPa var obsTags []string //nolint:prealloc for _, snakeFieldName := range keys { sch := res.Schema[snakeFieldName] - fieldName := NewNameFromSnake(snakeFieldName) + fieldName := name.NewNameFromSnake(snakeFieldName) comment, err := comments.New(sch.Description) if err != nil { return nil, nil, errors.Wrapf(err, "cannot build comment for description: %s", sch.Description) @@ -159,7 +160,7 @@ func (g *Builder) buildResource(res *schema.Resource, cfg *config.Resource, tfPa tfTag = "-" fieldType = typeSecretKeySelector - jsonTag = NewNameFromCamel(fieldNameCamel).LowerCamelComputed + jsonTag = name.NewNameFromCamel(fieldNameCamel).LowerCamelComputed if sch.Optional { fieldType = types.NewPointer(typeSecretKeySelector) jsonTag += ",omitempty" diff --git a/pkg/types/name.go b/pkg/types/name/name.go similarity index 90% rename from pkg/types/name.go rename to pkg/types/name/name.go index 6712658c..d0b9115f 100644 --- a/pkg/types/name.go +++ b/pkg/types/name/name.go @@ -14,9 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -package types +package name import ( + "fmt" "strings" "github.com/fatih/camelcase" @@ -46,6 +47,23 @@ func NewNameFromSnake(s string) Name { } } +// CapitalizeAcronyms capitalizes prefix and suffix acronyms found in s +func CapitalizeAcronyms(s string) string { + if s == "" { + return s + } + sl := strings.ToLower(s) + for lower, camel := range lowerToCamelAcronyms { + switch { + case strings.HasPrefix(sl, lower): + s = fmt.Sprintf("%s%s", camel, strings.Title(s[len(lower):])) + case strings.HasSuffix(sl, lower): + s = fmt.Sprintf("%s%s", s[0:len(s)-len(lower)], camel) + } + } + return s +} + // NewNameFromCamel produces a Name, using given camel case string as source of // truth. func NewNameFromCamel(s string) Name { diff --git a/pkg/types/name_test.go b/pkg/types/name/name_test.go similarity index 83% rename from pkg/types/name_test.go rename to pkg/types/name/name_test.go index 13c477a1..8a6669ab 100644 --- a/pkg/types/name_test.go +++ b/pkg/types/name/name_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package types +package name import ( "testing" @@ -157,3 +157,42 @@ func TestNewNameFromCamel(t *testing.T) { }) } } + +func TestCapitalizeAcronyms(t *testing.T) { + tests := map[string]struct { + arg string + want string + }{ + "NameWithPrefixAcronym": { + arg: "Sqlserver", + want: "SQLServer", + }, + "NameWithSuffixAcronym": { + arg: "Serverid", + want: "ServerID", + }, + "NameWithMultipleAcronyms": { + arg: "Sqlserverid", + want: "SQLServerID", + }, + "NameWithInterimAcronym": { + arg: "Mysqlserver", + want: "Mysqlserver", + }, + "NameOnlyAcronyms": { + arg: "Sqlid", + want: "SQLID", + }, + "EmptyName": { + arg: "", + want: "", + }, + } + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + if got := CapitalizeAcronyms(tt.arg); got != tt.want { + t.Errorf("CapitalizeAcronyms(tt.arg) = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/types/reference.go b/pkg/types/reference.go index 75a5cf5e..4af9939f 100644 --- a/pkg/types/reference.go +++ b/pkg/types/reference.go @@ -11,6 +11,7 @@ import ( "github.com/crossplane-contrib/terrajet/pkg/config" "github.com/crossplane-contrib/terrajet/pkg/types/comments" + "github.com/crossplane-contrib/terrajet/pkg/types/name" ) const ( @@ -42,8 +43,8 @@ func (g *Builder) generateReferenceFields(t *types.TypeName, f *types.Var, r con sfn = f.Name() + "Selector" } - rn := NewNameFromCamel(rfn) - sn := NewNameFromCamel(sfn) + rn := name.NewNameFromCamel(rfn) + sn := name.NewNameFromCamel(sfn) refTag := fmt.Sprintf(`json:"%s,omitempty" tf:"-"`, rn.LowerCamelComputed) selTag := fmt.Sprintf(`json:"%s,omitempty" tf:"-"`, sn.LowerCamelComputed) From 925f3e826427f0a34f04a8132edb2204e8298c6f Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Fri, 17 Dec 2021 01:43:40 +0300 Subject: [PATCH 2/3] Assume acronyms are always tokens split with underscores Signed-off-by: Alper Rifat Ulucinar --- pkg/config/defaults.go | 2 +- pkg/config/defaults_test.go | 45 +++++++++++++++++++++++++++++++++++++ pkg/types/name/name.go | 18 --------------- pkg/types/name/name_test.go | 39 -------------------------------- 4 files changed, 46 insertions(+), 58 deletions(-) diff --git a/pkg/config/defaults.go b/pkg/config/defaults.go index c4947b6a..9137aba4 100644 --- a/pkg/config/defaults.go +++ b/pkg/config/defaults.go @@ -97,7 +97,7 @@ func DefaultResource(name string, terraformSchema *schema.Resource, opts ...Reso Name: name, TerraformResource: terraformSchema, ShortGroup: group, - Kind: typeName.CapitalizeAcronyms(kind), + Kind: typeName.NewNameFromCamel(kind).Camel, Version: "v1alpha1", ExternalName: NameAsIdentifier, References: map[string]Reference{}, diff --git a/pkg/config/defaults_test.go b/pkg/config/defaults_test.go index 741f7df1..75a2e72a 100644 --- a/pkg/config/defaults_test.go +++ b/pkg/config/defaults_test.go @@ -66,6 +66,51 @@ func TestDefaultResource(t *testing.T) { Sensitive: NopSensitive, }, }, + "NameWithPrefixAcronym": { + reason: "It should return prefix acronym in capital case", + args: args{ + name: "aws_db_sql_server", + }, + want: &Resource{ + Name: "aws_db_sql_server", + ShortGroup: "db", + Kind: "SQLServer", + Version: "v1alpha1", + ExternalName: NameAsIdentifier, + References: map[string]Reference{}, + Sensitive: NopSensitive, + }, + }, + "NameWithSuffixAcronym": { + reason: "It should return suffix acronym in capital case", + args: args{ + name: "aws_db_server_id", + }, + want: &Resource{ + Name: "aws_db_server_id", + ShortGroup: "db", + Kind: "ServerID", + Version: "v1alpha1", + ExternalName: NameAsIdentifier, + References: map[string]Reference{}, + Sensitive: NopSensitive, + }, + }, + "NameWithMultipleAcronyms": { + reason: "It should return both prefix & suffix acronyms in capital case", + args: args{ + name: "aws_db_sql_server_id", + }, + want: &Resource{ + Name: "aws_db_sql_server_id", + ShortGroup: "db", + Kind: "SQLServerID", + Version: "v1alpha1", + ExternalName: NameAsIdentifier, + References: map[string]Reference{}, + Sensitive: NopSensitive, + }, + }, } // TODO(muvaf): Find a way to compare function pointers. diff --git a/pkg/types/name/name.go b/pkg/types/name/name.go index d0b9115f..63eb848e 100644 --- a/pkg/types/name/name.go +++ b/pkg/types/name/name.go @@ -17,7 +17,6 @@ limitations under the License. package name import ( - "fmt" "strings" "github.com/fatih/camelcase" @@ -47,23 +46,6 @@ func NewNameFromSnake(s string) Name { } } -// CapitalizeAcronyms capitalizes prefix and suffix acronyms found in s -func CapitalizeAcronyms(s string) string { - if s == "" { - return s - } - sl := strings.ToLower(s) - for lower, camel := range lowerToCamelAcronyms { - switch { - case strings.HasPrefix(sl, lower): - s = fmt.Sprintf("%s%s", camel, strings.Title(s[len(lower):])) - case strings.HasSuffix(sl, lower): - s = fmt.Sprintf("%s%s", s[0:len(s)-len(lower)], camel) - } - } - return s -} - // NewNameFromCamel produces a Name, using given camel case string as source of // truth. func NewNameFromCamel(s string) Name { diff --git a/pkg/types/name/name_test.go b/pkg/types/name/name_test.go index 8a6669ab..46936c29 100644 --- a/pkg/types/name/name_test.go +++ b/pkg/types/name/name_test.go @@ -157,42 +157,3 @@ func TestNewNameFromCamel(t *testing.T) { }) } } - -func TestCapitalizeAcronyms(t *testing.T) { - tests := map[string]struct { - arg string - want string - }{ - "NameWithPrefixAcronym": { - arg: "Sqlserver", - want: "SQLServer", - }, - "NameWithSuffixAcronym": { - arg: "Serverid", - want: "ServerID", - }, - "NameWithMultipleAcronyms": { - arg: "Sqlserverid", - want: "SQLServerID", - }, - "NameWithInterimAcronym": { - arg: "Mysqlserver", - want: "Mysqlserver", - }, - "NameOnlyAcronyms": { - arg: "Sqlid", - want: "SQLID", - }, - "EmptyName": { - arg: "", - want: "", - }, - } - for name, tt := range tests { - t.Run(name, func(t *testing.T) { - if got := CapitalizeAcronyms(tt.arg); got != tt.want { - t.Errorf("CapitalizeAcronyms(tt.arg) = %v, want %v", got, tt.want) - } - }) - } -} From 2dd0d7e2f67ea2f617a52c2fb75d423a1ca39fc8 Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Fri, 17 Dec 2021 15:51:58 +0300 Subject: [PATCH 3/3] Rename NewNameFrom{Snake,Camel} as NewFrom{Snake,Camel} Signed-off-by: Alper Rifat Ulucinar --- pkg/config/defaults.go | 2 +- pkg/types/builder.go | 4 ++-- pkg/types/name/name.go | 10 +++++----- pkg/types/name/name_test.go | 4 ++-- pkg/types/reference.go | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pkg/config/defaults.go b/pkg/config/defaults.go index 9137aba4..89a8fd72 100644 --- a/pkg/config/defaults.go +++ b/pkg/config/defaults.go @@ -97,7 +97,7 @@ func DefaultResource(name string, terraformSchema *schema.Resource, opts ...Reso Name: name, TerraformResource: terraformSchema, ShortGroup: group, - Kind: typeName.NewNameFromCamel(kind).Camel, + Kind: typeName.NewFromCamel(kind).Camel, Version: "v1alpha1", ExternalName: NameAsIdentifier, References: map[string]Reference{}, diff --git a/pkg/types/builder.go b/pkg/types/builder.go index 1acc469a..4ab4ba8e 100644 --- a/pkg/types/builder.go +++ b/pkg/types/builder.go @@ -103,7 +103,7 @@ func (g *Builder) buildResource(res *schema.Resource, cfg *config.Resource, tfPa var obsTags []string //nolint:prealloc for _, snakeFieldName := range keys { sch := res.Schema[snakeFieldName] - fieldName := name.NewNameFromSnake(snakeFieldName) + fieldName := name.NewFromSnake(snakeFieldName) comment, err := comments.New(sch.Description) if err != nil { return nil, nil, errors.Wrapf(err, "cannot build comment for description: %s", sch.Description) @@ -160,7 +160,7 @@ func (g *Builder) buildResource(res *schema.Resource, cfg *config.Resource, tfPa tfTag = "-" fieldType = typeSecretKeySelector - jsonTag = name.NewNameFromCamel(fieldNameCamel).LowerCamelComputed + jsonTag = name.NewFromCamel(fieldNameCamel).LowerCamelComputed if sch.Optional { fieldType = types.NewPointer(typeSecretKeySelector) jsonTag += ",omitempty" diff --git a/pkg/types/name/name.go b/pkg/types/name/name.go index 63eb848e..30c92883 100644 --- a/pkg/types/name/name.go +++ b/pkg/types/name/name.go @@ -23,9 +23,9 @@ import ( "github.com/iancoleman/strcase" ) -// NewNameFromSnake produces a Name, using given snake case string as source of +// NewFromSnake produces a Name, using given snake case string as source of // truth. -func NewNameFromSnake(s string) Name { +func NewFromSnake(s string) Name { originals := strings.Split(s, "_") camels := make([]string, len(originals)) computedCamels := make([]string, len(originals)) @@ -46,15 +46,15 @@ func NewNameFromSnake(s string) Name { } } -// NewNameFromCamel produces a Name, using given camel case string as source of +// NewFromCamel produces a Name, using given camel case string as source of // truth. -func NewNameFromCamel(s string) Name { +func NewFromCamel(s string) Name { originals := camelcase.Split(s) snakes := make([]string, len(originals)) for i, org := range originals { snakes[i] = strings.ToLower(org) } - return NewNameFromSnake(strings.Join(snakes, "_")) + return NewFromSnake(strings.Join(snakes, "_")) } // Name holds different variants of a name. diff --git a/pkg/types/name/name_test.go b/pkg/types/name/name_test.go index 46936c29..15b151cc 100644 --- a/pkg/types/name/name_test.go +++ b/pkg/types/name/name_test.go @@ -81,7 +81,7 @@ func TestNewNameFromSnake(t *testing.T) { for name, tc := range cases { t.Run(name, func(t *testing.T) { - got := NewNameFromSnake(tc.in) + got := NewFromSnake(tc.in) if diff := cmp.Diff(tc.want, got); diff != "" { t.Errorf("\nNewNameFromSnake(...): -want, +got:\n%s", diff) @@ -149,7 +149,7 @@ func TestNewNameFromCamel(t *testing.T) { for name, tc := range cases { t.Run(name, func(t *testing.T) { - got := NewNameFromCamel(tc.in) + got := NewFromCamel(tc.in) if diff := cmp.Diff(tc.want, got); diff != "" { t.Errorf("\nNewNameFromSnake(...): -want, +got:\n%s", diff) diff --git a/pkg/types/reference.go b/pkg/types/reference.go index 4af9939f..eb7bcfe0 100644 --- a/pkg/types/reference.go +++ b/pkg/types/reference.go @@ -43,8 +43,8 @@ func (g *Builder) generateReferenceFields(t *types.TypeName, f *types.Var, r con sfn = f.Name() + "Selector" } - rn := name.NewNameFromCamel(rfn) - sn := name.NewNameFromCamel(sfn) + rn := name.NewFromCamel(rfn) + sn := name.NewFromCamel(sfn) refTag := fmt.Sprintf(`json:"%s,omitempty" tf:"-"`, rn.LowerCamelComputed) selTag := fmt.Sprintf(`json:"%s,omitempty" tf:"-"`, sn.LowerCamelComputed)