gqlgen: Generate imports wrong package and gives error
What happened?
When running go run github.com/99designs/gqlgen generate
the generated resolver functions imports the wrong package.
if I use the github.com/pkg/errors library in my resolvers and then later on I trigger the generate
command, gqlgen will remove this import and instead import the standard library’s errors
package.
PRE go run github.com/99designs/gqlgen generate
// user.resolvers.go
import (
"context"
"github.com/pkg/errors"
"github.com/foo/bar/app"
)
func (r *queryResolver) Me(ctx context.Context) (*app.User, error) {
user,err := app.UserFromContext(ctx)
if err != nil {
return nil, errors.Wrap(err, "no user in context")
}
return user, nil
}
POST go run github.com/99designs/gqlgen generate
validation failed: packages.Load: /github.com/foo/bar/graph/resolver/user.resolvers.go: Wrap not declared by package errors
Updated generated file…
// user.resolvers.go
import (
"context"
"errors"
"github.com/foo/bar/app"
)
func (r *queryResolver) Me(ctx context.Context) (*app.User, error) {
user,err := app.UserFromContext(ctx)
if err != nil {
return nil, errors.Wrap(err, "no user in context")
}
return user, nil
}
So even though stdlib errors
pkg doesn’t have a Wrap
function, it will still be added to the import statement rather than using the one that was previously declared github.com/pkg/errors
followed by reporting that the function is not declared in that package.
gqlconfig.yml
schema:
- "graph/schema/**/*.graphql"
exec:
filename: graph/generated/generated.go
package: generated
resolver:
layout: follow-schema
dir: graph/resolver
package: resolver
struct_tag: gql
omit_slice_element_pointers: true
autobind:
- github.com/foo/bar/app
What did you expect?
import / use the already declared package rather than attempting to import it’s own
Minimal graphql.schema and models to reproduce
# schema/schema.graphql
schema {
query: Query
mutation: Mutation
}
type Query
type Mutation
# schema/types/user.graphql
extend type Query {
me: User
}
type User {
id: ID!
email: String!
name: String
}
versions
gqlgen version
? v0.11.3go version
? 1.14- dep or go modules? go mod
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 31
- Comments: 24 (2 by maintainers)
Commits related to this issue
- fix: fix generation of wrong imports for error package resovles: #1171 — committed to pjvds/gqlgen by pjvds 3 years ago
- fix: fix generation of wrong imports for error package resovles: #1171 — committed to pjvds/gqlgen by pjvds 3 years ago
- remove go packages imports for resolver.gotpl (#1171) — committed to smoole/gqlgen by smoole 3 years ago
- Update resolver.gotpl - remove reserved import of errors package fix for [#1171](https://github.com/99designs/gqlgen/issues/1171) — committed to willdhorn/gqlgen by willdhorn a year ago
hey guys, any update on this ?
Bump. This is a genuine issue and none of the mentioned fixes are really satisfactory. I’m happy to work on a PR if someone can tell me it’s okay to make a configuration option for replacing packages Alternatively, would be nice to know why
golang.org/x/tools/imports
was made to not touch imports and a custom implementation was made instead. I’ll mention @vektah who is the author for the commit breml mentioned. Hopefully we can get this moving 🙂An alternative to @duckbrain his solution it to use
gofmt
to update the imports. Just run the following at the root of your project after you (re-)generated the files:As a hacky workaround until this gets fixed, I created a plugin to remove the line and re-run goimports after it generates the errant file.
@pjvds many users may not want to use “github.com/pkg/errors” and GQLGen has no way of knowing that github.com/pkg/errors is a drop-in replacement for errors. @j0hnsmith’s workaround seems pretty reasonable to me.
The general problem is GQLGen may request an import who’s name conflicts with an existing import. The best way I could think to solve the problem is add a configuration option to map imports to a replacement, kind of like a
replace
directive ingo.mod
, but it replaces the generated import. It would be up to the user to ensure the replaced package is compatible with GQLGen’s usage of it.See: https://github.com/99designs/gqlgen/blob/5ad012e3d7be1127706b9c8a3da0378df3a98ec1/codegen/templates/import.go#L43 where the import is handled.
Alternatively the specific problem was introduced by the resolvers template moving from
panic("not implemented")
topanic(errors.Errorf("not implemented"))
.Adding an alias seems to make said aliased imports get removed entirely, in my case.
Edit: Spoke too soon, seems to work for some packages but not others.
"github.com/99designs/gqlgen/graphql"
for example, if aliased, gets removed.I wonder why
gqlgen
does insertions and deletions of the imports on its own in contrast to relying ongolang.org/x/tools/imports
, which is purely made for this purpose, used with great success in most IDE/editors and is maintained by the Go maintainers.The pruning happens in https://github.com/99designs/gqlgen/blob/master/internal/imports/prune.go and while
golang.org/x/tools/imports
is used, it is forced to not touch the imports (see: https://github.com/99designs/gqlgen/blob/master/internal/imports/prune.go#L46). The respective commit (https://github.com/99designs/gqlgen/commit/732be3959b402bbd3b864c5f40f475640f1334c5) states “Don’t let goimports guess import paths” in the commit message, but does not give a reason for this decision nor a reference to an issue.Wouldn’t this issue be resolved, if the line
{{ reserveImport "errors" }}
(https://github.com/99designs/gqlgen/blob/master/plugin/resolvergen/resolver.gotpl#L7) is removed andgolang.org/x/tools/imports
would not be be limited to formatting only?https://github.com/99designs/gqlgen/blob/master/plugin/resolvergen/resolver.gotpl#L7
del this will resolve this issue. Why add lines:
fmt aliase f
after gqlgen generate, f was deleted
Running
gofmt
doesn’t fix the imports for me 😦