Search code examples
gographqlgqlgensqlboiler

not able to generate generated_sort.go from gqlgen-sqlboiler


I am using sqlboiler version: v4.14.2 gqlgen version: v0.17.33 gqlgen-sqlboiler version : v3.3.12 https://github.com/web-ridge/gqlgen-sqlboiler

After following readme.md pre requisite getting following error while running convert.go following is convert.go

package main

import (
    "github.com/99designs/gqlgen/codegen/config"
    "github.com/rs/zerolog/log"
    gbgen "github.com/web-ridge/gqlgen-sqlboiler/v3"
    "github.com/web-ridge/gqlgen-sqlboiler/v3/cache"
    "github.com/web-ridge/gqlgen-sqlboiler/v3/structs"
    "os"
    "os/exec"
    "strings"
)

func main() {
    // change working directory to parent directory where all configs are located
    newDir, _ := os.Getwd()
    os.Chdir(strings.TrimSuffix(newDir, "/convert"))

    enableSoftDeletes := true
    boilerArgs := []string{"mysql", "--no-back-referencing", "--wipe", "-d"}
    if enableSoftDeletes {
        boilerArgs = append(boilerArgs, "--add-soft-deletes")
    }
    cmd := exec.Command("sqlboiler", boilerArgs...)

    err := cmd.Run()
    if err != nil {
        log.Fatal().Err(err).Str("command", cmd.String()).Msg("error generating dm models running sql-boiler")
    }

    output := structs.Config{
        Directory:   "helpers", // supports root or sub directories
        PackageName: "helpers",
    }
    backend := structs.Config{
        Directory:   "models",
        PackageName: "models",
    }
    frontend := structs.Config{
        Directory:   "models",
        PackageName: "models",
    }

    boilerCache := cache.InitializeBoilerCache(backend)

    generateSchema := true
    generatedSchema := !generateSchema
    if generateSchema {
        if err := gbgen.SchemaWrite(
            gbgen.SchemaConfig{
                BoilerCache:         boilerCache,
                Directives:          []string{"isAuthenticated"},
                SkipInputFields:     []string{"createdAt", "updatedAt", "deletedAt"},
                GenerateMutations:   true,
                GenerateBatchCreate: false,
                GenerateBatchDelete: false,
                GenerateBatchUpdate: false,
                HookShouldAddModel: func(model gbgen.SchemaModel) bool {
                    if model.Name == "Config" {
                        return false
                    }
                    return true
                },
                HookChangeFields: func(model *gbgen.SchemaModel, fields []*gbgen.SchemaField, parenType gbgen.ParentType) []*gbgen.SchemaField {
                    //profile: UserPayload! @isAuthenticated

                    return fields
                },
                HookChangeField: func(model *gbgen.SchemaModel, field *gbgen.SchemaField) {
                    //"userId", "userOrganizationId",
                    if field.Name == "userId" && model.Name != "UserUserOrganization" {
                        field.SkipInput = true
                    }
                    if field.Name == "userOrganizationId" && model.Name != "UserUserOrganization" {
                        field.SkipInput = true
                    }
                },
            },
            "../schema.graphql",
            gbgen.SchemaGenerateConfig{
                MergeSchema: false,
            },
        ); err != nil {
            log.Fatal().Err(err).Msg("error generating schema")
        }
        generatedSchema = true
    }
    if generatedSchema {

        cfg, err := config.LoadConfigFromDefaultLocations()
        if err != nil {
            log.Fatal().Err(err).Msg("error loading config")
        }

        data, err := gbgen.NewModelPlugin().GenerateCode(cfg)
        if err != nil {
            log.Fatal().Err(err).Msg("error generating graphql models using gqlgen")
        }

        modelCache := cache.InitializeModelCache(cfg, boilerCache, output, backend, frontend)

        if err := gbgen.NewConvertPlugin(
            modelCache,
            gbgen.ConvertPluginConfig{
                DatabaseDriver: gbgen.MySQL,
                //Searchable: {
                //  Company: {
                //      Column: dm.CompanyColumns.Name
                //  },
                //},
            },
        ).GenerateCode(); err != nil {
            log.Fatal().Err(err).Msg("error while generating convert/filters")
        }

        if err := gbgen.NewResolverPlugin(
            config.ResolverConfig{
                Filename: "resolvers/all_generated_resolvers.go",
                Package:  "resolvers",
                Type:     "Resolver",
            },
            output,
            boilerCache,
            modelCache,
            gbgen.ResolverPluginConfig{

                EnableSoftDeletes: enableSoftDeletes,
                // Authorization scopes can be used to override e.g. userId, organizationId, tenantId
                // This will be resolved used the provided ScopeResolverName if the result of the AddTrigger=true
                // You would need this if you don't want to require these fields in your schema but you want to add them
                // to the db model.
                // If you do have these fields in your schema but want them authorized you could use a gqlgen directive
                AuthorizationScopes: []*gbgen.AuthorizationScope{},
                //  {
                //      ImportPath:        "github.com/my-repo/app/backend/auth",
                //      ImportAlias:       "auth",
                //      ScopeResolverName: "UserIDFromContext", // function which is called with the context of the resolver
                //      BoilerColumnName:  "UserID",
                //      AddHook: func(model *gbgen.BoilerModel, resolver *gbgen.Resolver, templateKey string) bool {
                //          // fmt.Println(model.Name)
                //          // fmt.Println(templateKey)
                //          // templateKey contains a unique where the resolver tries to add something
                //          // e.g.
                //          // most of the time you can ignore this

                //          // we want the delete call to work for every object we don't want to take in account te user-id here
                //          if resolver.IsDelete {
                //              return false
                //          }

                //          var addResolver bool
                //          for _, field := range model.Fields {
                //              if field.Name == "UserID" {
                //                  addResolver = true
                //              }
                //          }
                //          return addResolver
                //      },
                //  },
                //  {
                //      ImportPath:        "github.com/my-repo/app/backend/auth",
                //      ImportAlias:       "auth",
                //      ScopeResolverName: "UserOrganizationIDFromContext", // function which is called with the context of the resolver
                //      BoilerColumnName:  "UserOrganizationID",

                //      AddHook: func(model *gbgen.BoilerModel, resolver *gbgen.Resolver, templateKey string) bool {
                //          // fmt.Println(model.Name)
                //          // fmt.Println(templateKey)
                //          // templateKey contains a unique where the resolver tries to add something
                //          // e.g.
                //          // most of the time you can ignore this
                //          var addResolver bool
                //          for _, field := range model.Fields {
                //              if field.Name == "UserOrganizationID" {
                //                  addResolver = true
                //              }
                //          }
                //          return addResolver
                //      },
                //  },
                // },
            },
        ).GenerateCode(data); err != nil {
            log.Fatal().Err(err).Msg("error while generating resolvers")
        }

    }
}

Following is log

go run convert/convert.go

4:10PM DBG [boiler-cache] building cache

4:10PM DBG [boiler-cache] built cache!

4:10PM DBG write GraphQL schema to disk bytes=3918 file=../schema.graphql

4:10PM DBG formatting GraphQL schema

../schema.graphql 71ms 4:10PM DBG formatted GraphQL schema

4:10PM DBG [model-cache] get structs

4:10PM DBG [model-cache] get extra's from schema

4:10PM DBG [model-cache] enhance structs with information

4:10PM DBG [model-cache] built cache!

4:10PM DBG [convert] render generated_convert.gotpl

4:10PM DBG [convert] rendered generated_convert.gotpl

4:10PM DBG [convert] render generated_convert_batch.gotpl

4:10PM DBG [convert] rendered generated_convert_batch.gotpl

4:10PM DBG [convert] render generated_convert_input.gotpl

4:10PM DBG [convert] rendered generated_convert_input.gotpl

4:10PM DBG [convert] render generated_filter.gotpl

4:10PM DBG [convert] rendered generated_filter.gotpl

4:10PM DBG [convert] render generated_preload.gotpl

4:10PM DBG [convert] rendered generated_preload.gotpl

4:10PM DBG [convert] render generated_sort.gotpl

4:10PM ERR could not parse golang file error="src.go:1:1: expected 'package', found 'EOF'"

4:10PM ERR error while rendering generated_sort.gotpl error="errors while writing template to helpers/generated_sort.go writeError: , contentError: execute: template: :44:17: executing "" at <$field.Enum.Name>: nil pointer evaluating *structs.Enum.Name, importError: helpers/generated_sort.go:1:1: expected 'package', found 'EOF'"

4:10PM DBG [convert] rendered generated_sort.gotpl

4:10PM ERR could not parse golang file error="src.go:1:1: expected 'package', found 'EOF'"

4:10PM ERR could not close file error="invalid argument" fileName=resolvers/all_generated_resolvers.go

4:10PM FTL error while generating resolvers error="errors while printing template to resolvers/all_generated_resolvers.go invalid argument"

exit status 1

Please any help how to fix this ?


Solution

  • Resolved issue by mapping correct dir. in side convert.go in convert.go while creating structs

    //output represents folder where files will be generated from gqlgen-sqlboiler

    output := structs.Config{
            Directory:   "helpers", // supports root or sub directories
            PackageName: "helpers",
        }
    

    //backend is the folder where all sqlboiler models are generated

    backend := structs.Config{
        Directory:   "models",
        PackageName: "models",
    }
    

    //!!!important frontend is the folder where all graphql files are generated from gqlgen

    frontend := structs.Config{
        Directory:   "graph",
        PackageName: "graph",
    }
    

    front-end folder was wrongly mapped.