From de925b752f6612d47011ca37af69b0c21b46ae28 Mon Sep 17 00:00:00 2001 From: Stanislas Michalak Date: Sun, 2 Sep 2018 12:38:14 +0200 Subject: [PATCH] Migrate inflect to flect Fixes #194 --- associations/belongs_to_association.go | 4 +- associations/has_many_association.go | 4 +- associations/has_one_association.go | 4 +- associations/many_to_many_association.go | 16 ++++---- model.go | 7 ++-- soda/cmd/generate/attribute.go | 8 ++-- soda/cmd/generate/model.go | 47 +++++++++++++++--------- soda/cmd/generate/model_cmd.go | 14 +++---- soda/cmd/generate/model_test.go | 4 +- 9 files changed, 59 insertions(+), 49 deletions(-) diff --git a/associations/belongs_to_association.go b/associations/belongs_to_association.go index 8402166a..7c9b2b91 100644 --- a/associations/belongs_to_association.go +++ b/associations/belongs_to_association.go @@ -4,9 +4,9 @@ import ( "fmt" "reflect" + "github.com/gobuffalo/flect" "github.com/gobuffalo/pop/columns" "github.com/gobuffalo/pop/nulls" - "github.com/markbates/inflect" ) // belongsToAssociation is the implementation for the belongs_to @@ -60,7 +60,7 @@ func belongsToAssociationBuilder(p associationParams) (Association, error) { } ownerPrimaryTags := columns.TagsFor(ownerPrimaryField) if dbField := ownerPrimaryTags.Find("db").Value; dbField == "" { - ownerPrimaryTableField = inflect.Underscore(ownerPrimaryField.Name) //autodetect without db tag + ownerPrimaryTableField = flect.Underscore(ownerPrimaryField.Name) //autodetect without db tag } else { ownerPrimaryTableField = dbField } diff --git a/associations/has_many_association.go b/associations/has_many_association.go index 6e006bc2..4bc643d0 100644 --- a/associations/has_many_association.go +++ b/associations/has_many_association.go @@ -4,8 +4,8 @@ import ( "fmt" "reflect" + "github.com/gobuffalo/flect" "github.com/gobuffalo/pop/nulls" - "github.com/markbates/inflect" ) // hasManyAssociation is the implementation for the has_many @@ -78,7 +78,7 @@ func (a *hasManyAssociation) Interface() interface{} { // Constraint returns the content for a where clause, and the args // needed to execute it. func (a *hasManyAssociation) Constraint() (string, []interface{}) { - tn := inflect.Underscore(a.ownerName) + tn := flect.Underscore(a.ownerName) condition := fmt.Sprintf("%s_id = ?", tn) if a.fkID != "" { condition = fmt.Sprintf("%s = ?", a.fkID) diff --git a/associations/has_one_association.go b/associations/has_one_association.go index 7854535d..d7bb040b 100644 --- a/associations/has_one_association.go +++ b/associations/has_one_association.go @@ -4,8 +4,8 @@ import ( "fmt" "reflect" + "github.com/gobuffalo/flect" "github.com/gobuffalo/pop/nulls" - "github.com/markbates/inflect" ) type hasOneAssociation struct { @@ -62,7 +62,7 @@ func (h *hasOneAssociation) Interface() interface{} { // Constraint returns the content for a where clause, and the args // needed to execute it. func (h *hasOneAssociation) Constraint() (string, []interface{}) { - tn := inflect.Underscore(h.ownerName) + tn := flect.Underscore(h.ownerName) condition := fmt.Sprintf("%s_id = ?", tn) if h.fkID != "" { condition = fmt.Sprintf("%s = ?", h.fkID) diff --git a/associations/many_to_many_association.go b/associations/many_to_many_association.go index 8a9f518a..ac371b06 100644 --- a/associations/many_to_many_association.go +++ b/associations/many_to_many_association.go @@ -5,8 +5,8 @@ import ( "reflect" "time" + "github.com/gobuffalo/flect" "github.com/gobuffalo/uuid" - "github.com/markbates/inflect" ) type manyToManyAssociation struct { @@ -72,15 +72,15 @@ func (m *manyToManyAssociation) Interface() interface{} { // Constraint returns the content for a where clause, and the args // needed to execute it. func (m *manyToManyAssociation) Constraint() (string, []interface{}) { - modelColumnID := fmt.Sprintf("%s%s", inflect.Underscore(m.model.Type().Name()), "_id") + modelColumnID := fmt.Sprintf("%s%s", flect.Underscore(m.model.Type().Name()), "_id") var columnFieldID string i := reflect.Indirect(m.fieldValue) if i.Kind() == reflect.Slice || i.Kind() == reflect.Array { t := i.Type().Elem() - columnFieldID = fmt.Sprintf("%s%s", inflect.Underscore(t.Name()), "_id") + columnFieldID = fmt.Sprintf("%s%s", flect.Underscore(t.Name()), "_id") } else { - columnFieldID = fmt.Sprintf("%s%s", inflect.Underscore(i.Type().Name()), "_id") + columnFieldID = fmt.Sprintf("%s%s", flect.Underscore(i.Type().Name()), "_id") } if m.fkID != "" { @@ -88,7 +88,7 @@ func (m *manyToManyAssociation) Constraint() (string, []interface{}) { } if m.primaryID != "" { - modelColumnID = m.primaryID + modelColumnID = m.primaryID } subQuery := fmt.Sprintf("select %s from %s where %s = ?", columnFieldID, m.manyToManyTableName, modelColumnID) @@ -115,14 +115,14 @@ func (m *manyToManyAssociation) BeforeSetup() error { func (m *manyToManyAssociation) Statements() []AssociationStatement { statements := []AssociationStatement{} - modelColumnID := fmt.Sprintf("%s%s", inflect.Underscore(m.model.Type().Name()), "_id") + modelColumnID := fmt.Sprintf("%s%s", flect.Underscore(m.model.Type().Name()), "_id") var columnFieldID string i := reflect.Indirect(m.fieldValue) if i.Kind() == reflect.Slice || i.Kind() == reflect.Array { t := i.Type().Elem() - columnFieldID = fmt.Sprintf("%s%s", inflect.Underscore(t.Name()), "_id") + columnFieldID = fmt.Sprintf("%s%s", flect.Underscore(t.Name()), "_id") } else { - columnFieldID = fmt.Sprintf("%s%s", inflect.Underscore(i.Type().Name()), "_id") + columnFieldID = fmt.Sprintf("%s%s", flect.Underscore(i.Type().Name()), "_id") } for i := 0; i < m.fieldValue.Len(); i++ { diff --git a/model.go b/model.go index 752a95bf..d1b11e71 100644 --- a/model.go +++ b/model.go @@ -6,8 +6,9 @@ import ( "sync" "time" + "github.com/gobuffalo/flect" + nflect "github.com/gobuffalo/flect/name" "github.com/gobuffalo/uuid" - "github.com/markbates/inflect" "github.com/pkg/errors" ) @@ -78,7 +79,7 @@ func (m *Model) TableName() string { tableMapMu.Lock() if tableMap[name] == "" { - m.tableName = inflect.Tableize(name) + m.tableName = nflect.Tableize(name) tableMap[name] = m.tableName } return tableMap[name] @@ -122,7 +123,7 @@ func (m *Model) fieldByName(s string) (reflect.Value, error) { } func (m *Model) associationName() string { - tn := inflect.Singularize(m.TableName()) + tn := flect.Singularize(m.TableName()) return fmt.Sprintf("%s_id", tn) } diff --git a/soda/cmd/generate/attribute.go b/soda/cmd/generate/attribute.go index 6878e1b9..866912fa 100644 --- a/soda/cmd/generate/attribute.go +++ b/soda/cmd/generate/attribute.go @@ -4,18 +4,18 @@ import ( "fmt" "strings" - "github.com/markbates/inflect" + "github.com/gobuffalo/flect" ) type attribute struct { - Name inflect.Name + Name flect.Ident OriginalType string GoType string Nullable bool } func (a attribute) String() string { - return fmt.Sprintf("\t%s %s `%s:\"%s\" db:\"%s\"`", a.Name.Camel(), a.GoType, structTag, a.Name.Underscore(), a.Name.Underscore()) + return fmt.Sprintf("\t%s %s `%s:\"%s\" db:\"%s\"`", a.Name.Pascalize(), a.GoType, structTag, a.Name.Underscore(), a.Name.Underscore()) } func (a attribute) IsValidable() bool { @@ -45,7 +45,7 @@ func newAttribute(base string, model *model) attribute { got = col[2] } a := attribute{ - Name: inflect.Name(col[0]), + Name: flect.New(col[0]), OriginalType: col[1], GoType: got, Nullable: nullable, diff --git a/soda/cmd/generate/model.go b/soda/cmd/generate/model.go index 41c780b7..fd55ab33 100644 --- a/soda/cmd/generate/model.go +++ b/soda/cmd/generate/model.go @@ -13,19 +13,20 @@ import ( "path/filepath" "strings" + "github.com/gobuffalo/flect" "github.com/gobuffalo/makr" "github.com/pkg/errors" "github.com/gobuffalo/fizz" + nflect "github.com/gobuffalo/flect/name" "github.com/gobuffalo/pop" "github.com/markbates/going/defaults" - "github.com/markbates/inflect" ) type model struct { Package string Imports []string - Name inflect.Name + Name nflect.Ident Attributes []attribute ValidatableAttributes []attribute @@ -40,23 +41,35 @@ func (m model) Generate() error { defer g.Fmt(".") ctx := makr.Data{} ctx["model"] = m - ctx["plural_model_name"] = m.Name.ModelPlural() - ctx["model_name"] = m.Name.Model() + ctx["plural_model_name"] = m.modelNamePlural() + ctx["model_name"] = m.modelName() ctx["package_name"] = m.Package ctx["test_package_name"] = m.testPkgName() - ctx["char"] = strings.ToLower(string([]byte(m.Name)[0])) + ctx["char"] = m.Name.Char() ctx["encoding_type"] = structTag ctx["encoding_type_char"] = strings.ToLower(string([]byte(structTag)[0])) - fname := filepath.Join(m.Package, m.Name.File()+".go") + fname := filepath.Join(m.Package, m.Name.File(".go").String()) g.Add(makr.NewFile(fname, modelTemplate)) - tfname := filepath.Join(m.Package, m.Name.File()+"_test.go") + tfname := filepath.Join(m.Package, m.Name.File("_test.go").String()) g.Add(makr.NewFile(tfname, modelTestTemplate)) return g.Run(".", ctx) } +func (m model) modelName() string { + x := strings.Split(m.Name.String(), "/") + for i, s := range x { + x[i] = flect.New(s).Singularize().Pascalize().String() + } + return strings.Join(x, "") +} + +func (m model) modelNamePlural() string { + return flect.New(m.modelName()).Pluralize().Pascalize().String() +} + func (m model) testPkgName() string { pkg := m.Package @@ -95,7 +108,7 @@ func (m model) testPkgName() string { } func (m *model) addAttribute(a attribute) { - if a.Name == "id" { + if a.Name.String() == "id" { // No need to create a default ID m.HasID = true // Ensure ID is the first attribute @@ -126,7 +139,7 @@ func (m *model) addID() { m.Imports = append(m.Imports, "github.com/gobuffalo/uuid") } - id := inflect.Name("id") + id := flect.New("id") a := attribute{Name: id, OriginalType: "uuid.UUID", GoType: "uuid.UUID"} // Ensure ID is the first attribute m.Attributes = append([]attribute{a}, m.Attributes...) @@ -144,7 +157,7 @@ func (m model) generateModelFile() error { func (m model) generateFizz(path string) error { migrationPath := defaults.String(path, "./migrations") - return pop.MigrationCreate(migrationPath, fmt.Sprintf("create_%s", m.Name.Table()), "fizz", []byte(m.Fizz()), []byte(m.UnFizz())) + return pop.MigrationCreate(migrationPath, fmt.Sprintf("create_%s", m.Name.Tableize()), "fizz", []byte(m.Fizz()), []byte(m.UnFizz())) } func (m model) generateSQL(path, env string) error { @@ -157,14 +170,14 @@ func (m model) generateSQL(path, env string) error { d := db.Dialect f := d.FizzTranslator() - return pop.MigrationCreate(migrationPath, fmt.Sprintf("create_%s.%s", m.Name.Table(), d.Name()), "sql", []byte(m.GenerateSQLFromFizz(m.Fizz(), f)), []byte(m.GenerateSQLFromFizz(m.UnFizz(), f))) + return pop.MigrationCreate(migrationPath, fmt.Sprintf("create_%s.%s", m.Name.Tableize(), d.Name()), "sql", []byte(m.GenerateSQLFromFizz(m.Fizz(), f)), []byte(m.GenerateSQLFromFizz(m.UnFizz(), f))) } // Fizz generates the create table instructions func (m model) Fizz() string { - s := []string{fmt.Sprintf("create_table(\"%s\") {", m.Name.Table())} + s := []string{fmt.Sprintf("create_table(\"%s\") {", m.Name.Tableize())} for _, a := range m.Attributes { - switch a.Name { + switch a.Name.String() { case "created_at", "updated_at": case "id": s = append(s, fmt.Sprintf("\tt.Column(\"id\", \"%s\", {\"primary\": true})", fizzColType(a.OriginalType))) @@ -182,7 +195,7 @@ func (m model) Fizz() string { // UnFizz generates the drop table instructions func (m model) UnFizz() string { - return fmt.Sprintf("drop_table(\"%s\")", m.Name.Table()) + return fmt.Sprintf("drop_table(\"%s\")", m.Name.Tableize()) } // GenerateSQLFromFizz generates SQL instructions from fizz instructions @@ -198,10 +211,10 @@ func newModel(name string) model { m := model{ Package: "models", Imports: []string{"time", "github.com/gobuffalo/pop", "github.com/gobuffalo/validate"}, - Name: inflect.Name(name), + Name: nflect.New(name), Attributes: []attribute{ - {Name: inflect.Name("created_at"), OriginalType: "time.Time", GoType: "time.Time"}, - {Name: inflect.Name("updated_at"), OriginalType: "time.Time", GoType: "time.Time"}, + {Name: flect.New("created_at"), OriginalType: "time.Time", GoType: "time.Time"}, + {Name: flect.New("updated_at"), OriginalType: "time.Time", GoType: "time.Time"}, }, ValidatableAttributes: []attribute{}, } diff --git a/soda/cmd/generate/model_cmd.go b/soda/cmd/generate/model_cmd.go index 63e92cd0..c5214d13 100644 --- a/soda/cmd/generate/model_cmd.go +++ b/soda/cmd/generate/model_cmd.go @@ -4,8 +4,6 @@ import ( "fmt" "strings" - "github.com/markbates/inflect" - "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -18,9 +16,6 @@ func init() { ModelCmd.Flags().StringVarP(&structTag, "struct-tag", "", "json", "sets the struct tags for model (xml or json)") ModelCmd.Flags().StringVarP(&migrationType, "migration-type", "", "fizz", "sets the type of migration files for model (sql or fizz)") ModelCmd.Flags().BoolVarP(&skipMigration, "skip-migration", "s", false, "Skip creating a new fizz migration for this model.") - - inflect.AddAcronym("ID") - inflect.AddAcronym("UUID") } // ModelCmd is the cmd to generate a model @@ -66,13 +61,14 @@ func Model(name string, opts map[string]interface{}, attributes []string) error return errors.New("invalid struct tags (use xml or json)") } - attrs := make(map[inflect.Name]struct{}) + attrs := make(map[string]struct{}) for _, def := range attributes { a := newAttribute(def, &model) - if _, found := attrs[a.Name]; found { - return fmt.Errorf("duplicated field \"%s\"", a.Name.String()) + f := a.Name.String() + if _, found := attrs[f]; found { + return fmt.Errorf("duplicated field \"%s\"", f) } - attrs[a.Name] = struct{}{} + attrs[f] = struct{}{} model.addAttribute(a) } diff --git a/soda/cmd/generate/model_test.go b/soda/cmd/generate/model_test.go index 748dbfbf..83d03d0e 100644 --- a/soda/cmd/generate/model_test.go +++ b/soda/cmd/generate/model_test.go @@ -55,7 +55,7 @@ func Test_model_addID(t *testing.T) { r.Equal(m.HasID, true) r.Equal(m.HasUUID, true) - r.Equal(string(m.Attributes[0].Name), "id") + r.Equal(m.Attributes[0].Name.String(), "id") r.Equal(string(m.Attributes[0].GoType), "uuid.UUID") m = newModel("car") @@ -64,7 +64,7 @@ func Test_model_addID(t *testing.T) { r.Equal(m.HasID, true) r.Equal(m.HasUUID, false) - r.Equal(string(m.Attributes[0].Name), "id") + r.Equal(m.Attributes[0].Name.String(), "id") r.Equal(string(m.Attributes[0].GoType), "int") }