Skip to content

Commit

Permalink
[resolvergen] add a configuration flag for enable_rewrite_for_single_…
Browse files Browse the repository at this point in the history
…file
  • Loading branch information
hailyngx committed Sep 3, 2024
1 parent 814f7c7 commit 53a1506
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 11 deletions.
17 changes: 9 additions & 8 deletions codegen/config/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ import (
)

type ResolverConfig struct {
Filename string `yaml:"filename,omitempty"`
FilenameTemplate string `yaml:"filename_template,omitempty"`
Package string `yaml:"package,omitempty"`
Type string `yaml:"type,omitempty"`
Layout ResolverLayout `yaml:"layout,omitempty"`
DirName string `yaml:"dir"`
OmitTemplateComment bool `yaml:"omit_template_comment,omitempty"`
ResolverTemplate string `yaml:"resolver_template,omitempty"`
Filename string `yaml:"filename,omitempty"`
FilenameTemplate string `yaml:"filename_template,omitempty"`
Package string `yaml:"package,omitempty"`
Type string `yaml:"type,omitempty"`
Layout ResolverLayout `yaml:"layout,omitempty"`
DirName string `yaml:"dir"`
OmitTemplateComment bool `yaml:"omit_template_comment,omitempty"`
ResolverTemplate string `yaml:"resolver_template,omitempty"`
EnableRewriteForSingleFile bool `yaml:"enable_rewrite_for_single_file,omitempty"`
}

type ResolverLayout string
Expand Down
62 changes: 62 additions & 0 deletions plugin/resolvergen/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ func (m *Plugin) GenerateCode(data *codegen.Data) error {

switch data.Config.Resolver.Layout {
case config.LayoutSingleFile:
if data.Config.Resolver.EnableRewriteForSingleFile {
return m.generateSingleFileEnableRewrite(data)
}
return m.generateSingleFile(data)
case config.LayoutFollowSchema:
return m.generatePerSchema(data)
Expand Down Expand Up @@ -96,6 +99,65 @@ func (m *Plugin) generateSingleFile(data *codegen.Data) error {
})
}

func (m *Plugin) generateSingleFileEnableRewrite(data *codegen.Data) error {
file := File{}
rewriter, err := rewrite.New(data.Config.Resolver.Dir())
if err != nil {
return err
}

for _, o := range data.Objects {
if o.HasResolvers() {
caser := cases.Title(language.English, cases.NoLower)
rewriter.MarkStructCopied(templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type))
rewriter.GetMethodBody(data.Config.Resolver.Type, caser.String(o.Name))

file.Objects = append(file.Objects, o)
}

for _, f := range o.Fields {
if !f.IsResolver {
continue
}

structName := templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type)
comment := strings.TrimSpace(strings.TrimLeft(rewriter.GetMethodComment(structName, f.GoFieldName), `\`))
implementation := strings.TrimSpace(rewriter.GetMethodBody(structName, f.GoFieldName))

resolver := Resolver{o, f, rewriter.GetPrevDecl(structName, f.GoFieldName), comment, implementation, nil}
file.Resolvers = append(file.Resolvers, &resolver)
}
}

if _, err := os.Stat(data.Config.Resolver.Filename); err == nil {
file.name = data.Config.Resolver.Filename
file.imports = rewriter.ExistingImports(file.name)
file.RemainingSource = rewriter.RemainingSource(file.name)
}

resolverBuild := &ResolverBuild{
File: &file,
PackageName: data.Config.Resolver.Package,
ResolverType: data.Config.Resolver.Type,
HasRoot: true,
OmitTemplateComment: data.Config.Resolver.OmitTemplateComment,
}

newResolverTemplate := resolverTemplate
if data.Config.Resolver.ResolverTemplate != "" {
newResolverTemplate = readResolverTemplate(data.Config.Resolver.ResolverTemplate)
}

return templates.Render(templates.Options{
PackageName: data.Config.Resolver.Package,
FileNotice: `// THIS CODE WILL BE UPDATED WITH SCHEMA CHANGES. PREVIOUS IMPLEMENTATION FOR SCHEMA CHANGES WILL BE KEPT IN THE COMMENT SECTION. IMPLEMENTATION FOR UNCHANGED SCHEMA WILL BE KEPT.`,
Filename: data.Config.Resolver.Filename,
Data: resolverBuild,
Packages: data.Config.Packages,
Template: newResolverTemplate,
})
}

func (m *Plugin) generatePerSchema(data *codegen.Data) error {
rewriter, err := rewrite.New(data.Config.Resolver.Dir())
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions plugin/resolvergen/resolver.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,7 @@
// - When renaming or deleting a resolver the old code will be put in here. You can safely delete
// it when you're done.
// - You have helper methods in this file. Move them out to keep these resolver files clean.
/*
{{ .RemainingSource }}
*/
{{ end }}
22 changes: 22 additions & 0 deletions plugin/resolvergen/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@ func TestLayoutSingleFile(t *testing.T) {
assertNoErrors(t, "github.com/99designs/gqlgen/plugin/resolvergen/testdata/singlefile/out")
}

func TestLayoutSingleFileWithEnableRewrite(t *testing.T) {
// Ensure the resolver file exists before running the test
resolverFilePath := "testdata/singlefile_enable_rewrite/out/resolver.go"
_, err := os.Stat(resolverFilePath)
if os.IsNotExist(err) {
t.Fatalf("Expected resolver file does not exist: %s", resolverFilePath)
}
require.NoError(t, err)

cfg, err := config.LoadConfig("testdata/singlefile_enable_rewrite/gqlgen.yml")
require.NoError(t, err)
p := Plugin{}

require.NoError(t, cfg.Init())

data, err := codegen.BuildData(cfg)
require.NoError(t, err)

require.NoError(t, p.GenerateCode(data))
assertNoErrors(t, "github.com/99designs/gqlgen/plugin/resolvergen/testdata/singlefile_enable_rewrite/out")
}

func TestLayoutFollowSchema(t *testing.T) {
testFollowSchemaPersistence(t, "testdata/followschema")

Expand Down
17 changes: 14 additions & 3 deletions plugin/resolvergen/testdata/singlefile/out/resolver.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
package customresolver

// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES.
// THIS CODE WILL BE UPDATED WITH SCHEMA CHANGES. PREVIOUS IMPLEMENTATION FOR SCHEMA CHANGES WILL BE KEPT IN THE COMMENT SECTION. IMPLEMENTATION FOR UNCHANGED SCHEMA WILL BE KEPT.

import (
"context"
"fmt"
)

type CustomResolverType struct{}

// Resolver is the resolver for the resolver field.
func (r *queryCustomResolverType) Resolver(ctx context.Context) (*Resolver, error) {
panic("not implemented")
panic(fmt.Errorf("not implemented: Resolver - resolver"))
}

// Name is the resolver for the name field.
func (r *resolverCustomResolverType) Name(ctx context.Context, obj *Resolver) (string, error) {
panic("not implemented")
panic(fmt.Errorf("not implemented: Name - name"))
}

// Query returns QueryResolver implementation.
Expand All @@ -26,3 +27,13 @@ func (r *CustomResolverType) Resolver() ResolverResolver { return &resolverCusto

type queryCustomResolverType struct{ *CustomResolverType }
type resolverCustomResolverType struct{ *CustomResolverType }

// !!! WARNING !!!
// The code below was going to be deleted when updating resolvers. It has been copied here so you have
// one last chance to move it out of harms way if you want. There are two reasons this happens:
// - When renaming or deleting a resolver the old code will be put in here. You can safely delete
// it when you're done.
// - You have helper methods in this file. Move them out to keep these resolver files clean.
/*
type CustomResolverType struct{}
*/
17 changes: 17 additions & 0 deletions plugin/resolvergen/testdata/singlefile_enable_rewrite/gqlgen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
schema:
- "testdata/schema.graphql"

exec:
filename: testdata/singlefile/out/ignored.go
model:
filename: testdata/singlefile/out/generated.go
resolver:
filename: testdata/singlefile/out/resolver.go
type: CustomResolverType
enable_rewrite_for_single_file: true

models:
Resolver:
model: github.com/99designs/gqlgen/plugin/resolvergen/testdata/singlefile/out.Resolver

omit_gqlgen_version_in_file_notice: true
13 changes: 13 additions & 0 deletions plugin/resolvergen/testdata/singlefile_enable_rewrite/out/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package customresolver

import "context"

type Resolver struct{}

type QueryResolver interface {
Resolver(ctx context.Context) (*Resolver, error)
}

type ResolverResolver interface {
Name(ctx context.Context, obj *Resolver) (string, error)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package customresolver

// THIS CODE WILL BE UPDATED WITH SCHEMA CHANGES. PREVIOUS IMPLEMENTATION FOR SCHEMA CHANGES WILL BE KEPT IN THE COMMENT SECTION. IMPLEMENTATION FOR UNCHANGED SCHEMA WILL BE KEPT.

import (
"context"
"fmt"
)

type CustomResolverType struct{}

// Resolver is the resolver for the resolver field.
func (r *queryCustomResolverType) Resolver(ctx context.Context) (*Resolver, error) {
panic(fmt.Errorf("not implemented: Resolver - resolver"))
}

// Name is the resolver for the name field.
func (r *resolverCustomResolverType) Name(ctx context.Context, obj *Resolver) (string, error) {
panic(fmt.Errorf("not implemented: Name - name"))
}

// Query returns QueryResolver implementation.
func (r *CustomResolverType) Query() QueryResolver { return &queryCustomResolverType{r} }

// Resolver returns ResolverResolver implementation.
func (r *CustomResolverType) Resolver() ResolverResolver { return &resolverCustomResolverType{r} }

type queryCustomResolverType struct{ *CustomResolverType }
type resolverCustomResolverType struct{ *CustomResolverType }

0 comments on commit 53a1506

Please sign in to comment.