Skip to content

Commit

Permalink
Add possibility to hook into modelgen plugin
Browse files Browse the repository at this point in the history
This change introduces option to implement custom hook for model
generation plugin without the need to completly copy the whole `modelgen` plugin.

One very possible case is as described in #876 and with this change the solution for
that can be:

```golang
func mutateHook(b *ModelBuild) *ModelBuild {
	for _, model := range b.Models {
		for _, field := range model.Fields {
			field.Tag += ` orm_binding:"` + model.Name + `.`  +  field.Name + `"`
		}
	}

	return b
}

...

func main() {
    p := modelgen.Plugin {
        MutateHook: mutateHook,
    }

    ...
}

```
  • Loading branch information
mskrip committed Nov 11, 2019
1 parent 99a55da commit 1f272d1
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 16 deletions.
18 changes: 16 additions & 2 deletions plugin/modelgen/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import (
"github.com/vektah/gqlparser/ast"
)

type BuildMutateHook = func(b *ModelBuild) *ModelBuild

func defaultBuildMutateHook(b *ModelBuild) *ModelBuild {
return b
}

type ModelBuild struct {
PackageName string
Interfaces []*Interface
Expand Down Expand Up @@ -50,10 +56,14 @@ type EnumValue struct {
}

func New() plugin.Plugin {
return &Plugin{}
return &Plugin{
MutateHook: defaultBuildMutateHook,
}
}

type Plugin struct{}
type Plugin struct {
MutateHook BuildMutateHook
}

var _ plugin.ConfigMutator = &Plugin{}

Expand Down Expand Up @@ -221,6 +231,10 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
return nil
}

if m.MutateHook != nil {
b = m.MutateHook(b)
}

return templates.Render(templates.Options{
PackageName: cfg.Model.Package,
Filename: cfg.Model.Filename,
Expand Down
31 changes: 30 additions & 1 deletion plugin/modelgen/models_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package modelgen

import (
"go/ast"
"go/parser"
"go/token"
"io/ioutil"
Expand All @@ -14,7 +15,9 @@ import (
func TestModelGeneration(t *testing.T) {
cfg, err := config.LoadConfig("testdata/gqlgen.yml")
require.NoError(t, err)
p := Plugin{}
p := Plugin{
MutateHook: mutateHook,
}
require.NoError(t, p.MutateConfig(cfg))

require.True(t, cfg.Models.UserDefined("MissingTypeNotNull"))
Expand Down Expand Up @@ -42,4 +45,30 @@ func TestModelGeneration(t *testing.T) {
require.True(t, len(words) > 1, "expected description %q to have more than one word", text)
}
})

t.Run("tags are applied", func(t *testing.T) {
node, err := parser.ParseFile(token.NewFileSet(), "./out/generated.go", nil, 0)
require.NoError(t, err)
for _, obj := range node.Scope.Objects {
if spec, ok := (obj.Decl).(*ast.TypeSpec); ok {
if st, ok := (spec.Type).(*ast.StructType); ok {
for _, field := range st.Fields.List {
fieldName := strings.ToLower(field.Names[0].String())
expectedTag := "`json:\"" + fieldName + "\" database:\"" + spec.Name.String() + fieldName + "\"`"
require.True(t, field.Tag.Value == expectedTag)
}
}
}
}
})
}

func mutateHook(b *ModelBuild) *ModelBuild {
for _, model := range b.Models {
for _, field := range model.Fields {
field.Tag += ` database:"` + model.Name + field.Name + `"`
}
}

return b
}
26 changes: 13 additions & 13 deletions plugin/modelgen/out/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1f272d1

Please sign in to comment.