From f6c35be2128d8d0ec6c0c0d63bc0f135292ab5fe Mon Sep 17 00:00:00 2001 From: Thomas Prebble <6523587+tprebs@users.noreply.github.com> Date: Wed, 13 Oct 2021 14:12:52 +0100 Subject: [PATCH] Add ReplacePlugin option to replace a specific plugin (#1657) * Add Helper Option for replacing plugins * Update recipe to use ReplacePlugin instead of NoPlugin and AddPlugin * fix linting issue on comment --- api/option.go | 20 +++++++++ api/option_test.go | 58 +++++++++++++++++++++++++++ docs/content/recipes/modelgen-hook.md | 18 ++++----- 3 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 api/option_test.go diff --git a/api/option.go b/api/option.go index f7ba6774bd..ab41dfa205 100644 --- a/api/option.go +++ b/api/option.go @@ -18,3 +18,23 @@ func AddPlugin(p plugin.Plugin) Option { *plugins = append(*plugins, p) } } + +// ReplacePlugin replaces any existing plugin with a matching plugin name +func ReplacePlugin(p plugin.Plugin) Option { + return func(cfg *config.Config, plugins *[]plugin.Plugin) { + if plugins != nil { + found := false + ps := *plugins + for i, o := range ps { + if p.Name() == o.Name() { + ps[i] = p + found = true + } + } + if !found { + ps = append(ps, p) + } + *plugins = ps + } + } +} diff --git a/api/option_test.go b/api/option_test.go new file mode 100644 index 0000000000..749e29dd40 --- /dev/null +++ b/api/option_test.go @@ -0,0 +1,58 @@ +package api + +import ( + "testing" + + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/plugin" + "github.com/99designs/gqlgen/plugin/federation" + "github.com/99designs/gqlgen/plugin/modelgen" + "github.com/99designs/gqlgen/plugin/resolvergen" + "github.com/stretchr/testify/require" +) + +type testPlugin struct { +} + +// Name returns the plugin name +func (t *testPlugin) Name() string { + return "modelgen" +} + +// MutateConfig mutates the configuration +func (t *testPlugin) MutateConfig(_ *config.Config) error { + return nil +} + +func TestReplacePlugin(t *testing.T) { + + t.Run("replace plugin if exists", func(t *testing.T) { + pg := []plugin.Plugin{ + federation.New(), + modelgen.New(), + resolvergen.New(), + } + + expectedPlugin := &testPlugin{} + ReplacePlugin(expectedPlugin)(config.DefaultConfig(), &pg) + + require.EqualValues(t, federation.New(), pg[0]) + require.EqualValues(t, expectedPlugin, pg[1]) + require.EqualValues(t, resolvergen.New(), pg[2]) + }) + + t.Run("add plugin if doesn't exist", func(t *testing.T) { + pg := []plugin.Plugin{ + federation.New(), + resolvergen.New(), + } + + expectedPlugin := &testPlugin{} + ReplacePlugin(expectedPlugin)(config.DefaultConfig(), &pg) + + require.EqualValues(t, federation.New(), pg[0]) + require.EqualValues(t, resolvergen.New(), pg[1]) + require.EqualValues(t, expectedPlugin, pg[2]) + }) + +} diff --git a/docs/content/recipes/modelgen-hook.md b/docs/content/recipes/modelgen-hook.md index eb65d625c2..695ca74cb9 100644 --- a/docs/content/recipes/modelgen-hook.md +++ b/docs/content/recipes/modelgen-hook.md @@ -49,10 +49,8 @@ func main() { MutateHook: mutateHook, } - err = api.Generate(cfg, - api.NoPlugins(), - api.AddPlugin(&p), - ) + err = api.Generate(cfg, api.ReplacePlugin(&p)) + if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(3) @@ -82,7 +80,7 @@ type Object struct { ## FieldMutateHook -For more fine grained control over model generation, a graphql schema aware a FieldHook can be provided. This hook has access to type and field graphql definitions enabling the hook to modify the `modelgen.Field` using directives defined within the schema. +For more fine grained control over model generation, a graphql schema aware a FieldHook can be provided. This hook has access to type and field graphql definitions enabling the hook to modify the `modelgen.Field` using directives defined within the schema. The below recipe uses this feature to add validate tags to the generated model for use with `go-playground/validator` where the validate tags are defined in a constraint directive in the schema. @@ -103,11 +101,11 @@ func constraintFieldHook(td *ast.Definition, fd *ast.FieldDefinition, f *modelge c := fd.Directives.ForName("constraint") if c != nil { formatConstraint := c.Arguments.ForName("format") - + if formatConstraint != nil{ f.Tag += " validate:"+formatConstraint.Value.String() } - + } return f, nil @@ -125,10 +123,8 @@ func main() { FieldHook: constraintFieldHook, } - err = api.Generate(cfg, - api.NoPlugins(), - api.AddPlugin(&p), - ) + err = api.Generate(cfg, api.ReplacePlugin(&p)) + if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(3)