From b0d79115d07506920fea5f3f93086c9b4849f9e3 Mon Sep 17 00:00:00 2001 From: Mathew Byrne Date: Tue, 3 Apr 2018 17:15:41 +1000 Subject: [PATCH] Replace invalid package characters with an underscore This will sanatise local import names to a valid go identifier by replacing any non-word characters with an underscore. --- codegen/import_build.go | 7 ++- test/generated.go | 58 +++++++++++++++++++ test/invalid-identifier/invalid-identifier.go | 5 ++ test/resolvers_test.go | 18 ++++-- test/schema.graphql | 5 ++ test/types.json | 3 +- 6 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 test/invalid-identifier/invalid-identifier.go diff --git a/codegen/import_build.go b/codegen/import_build.go index cafbb25396f..657511e93c7 100644 --- a/codegen/import_build.go +++ b/codegen/import_build.go @@ -2,6 +2,7 @@ package codegen import ( "path/filepath" + "regexp" "strconv" "strings" ) @@ -29,6 +30,8 @@ func buildImports(types NamedTypes, destDir string) Imports { return imports } +var invalidPackageNameChar = regexp.MustCompile(`[^\w]`) + func (s Imports) addPkg(types NamedTypes, destDir string, pkg string) (Imports, *Import) { if pkg == "" { return s, nil @@ -40,11 +43,11 @@ func (s Imports) addPkg(types NamedTypes, destDir string, pkg string) (Imports, localName := "" if !strings.HasSuffix(destDir, pkg) { - localName = filepath.Base(pkg) + localName = invalidPackageNameChar.ReplaceAllLiteralString(filepath.Base(pkg), "_") i := 1 imp := s.findByName(localName) for imp != nil && imp.Package != pkg { - localName = filepath.Base(pkg) + strconv.Itoa(i) + localName = invalidPackageNameChar.ReplaceAllLiteralString(filepath.Base(pkg), "_") + strconv.Itoa(i) imp = s.findByName(localName) i++ if i > 10 { diff --git a/test/generated.go b/test/generated.go index eff50f80572..c2427e537a4 100644 --- a/test/generated.go +++ b/test/generated.go @@ -14,6 +14,7 @@ import ( query "github.com/vektah/gqlgen/neelance/query" schema "github.com/vektah/gqlgen/neelance/schema" introspection1 "github.com/vektah/gqlgen/test/introspection" + invalid_identifier "github.com/vektah/gqlgen/test/invalid-identifier" models "github.com/vektah/gqlgen/test/models" ) @@ -29,6 +30,7 @@ type Resolvers interface { Query_recursive(ctx context.Context, input *RecursiveInputSlice) (*bool, error) Query_mapInput(ctx context.Context, input *map[string]interface{}) (*bool, error) Query_collision(ctx context.Context) (*introspection1.It, error) + Query_invalidIdentifier(ctx context.Context) (*invalid_identifier.InvalidIdentifier, error) } type executableSchema struct { @@ -127,6 +129,33 @@ func (ec *executionContext) _InnerObject_id(ctx context.Context, field graphql.C return graphql.MarshalInt(res) } +var invalidIdentifierImplementors = []string{"InvalidIdentifier"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) _InvalidIdentifier(ctx context.Context, sel []query.Selection, obj *invalid_identifier.InvalidIdentifier) graphql.Marshaler { + fields := graphql.CollectFields(ec.Doc, sel, invalidIdentifierImplementors, ec.Variables) + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("InvalidIdentifier") + case "id": + out.Values[i] = ec._InvalidIdentifier_id(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) _InvalidIdentifier_id(ctx context.Context, field graphql.CollectedField, obj *invalid_identifier.InvalidIdentifier) graphql.Marshaler { + res := obj.ID + return graphql.MarshalInt(res) +} + var itImplementors = []string{"It"} // nolint: gocyclo, errcheck, gas, goconst @@ -219,6 +248,8 @@ func (ec *executionContext) _Query(ctx context.Context, sel []query.Selection) g out.Values[i] = ec._Query_mapInput(ctx, field) case "collision": out.Values[i] = ec._Query_collision(ctx, field) + case "invalidIdentifier": + out.Values[i] = ec._Query_invalidIdentifier(ctx, field) case "__schema": out.Values[i] = ec._Query___schema(ctx, field) case "__type": @@ -433,6 +464,28 @@ func (ec *executionContext) _Query_collision(ctx context.Context, field graphql. }) } +func (ec *executionContext) _Query_invalidIdentifier(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { + return graphql.Defer(func() (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + userErr := ec.Recover(r) + ec.Error(userErr) + ret = graphql.Null + } + }() + rctx := graphql.WithResolverContext(ctx, &graphql.ResolverContext{Field: field}) + res, err := ec.resolvers.Query_invalidIdentifier(rctx) + if err != nil { + ec.Error(err) + return graphql.Null + } + if res == nil { + return graphql.Null + } + return ec._InvalidIdentifier(ctx, field.Selections, res) + }) +} + func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { res := ec.introspectSchema() if res == nil { @@ -1139,6 +1192,10 @@ type It { id: ID! } +type InvalidIdentifier { + id: Int! +} + type Query { nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean nestedOutputs: [[OuterObject]] @@ -1146,5 +1203,6 @@ type Query { recursive(input: RecursiveInputSlice): Boolean mapInput(input: Changes): Boolean collision: It + invalidIdentifier: InvalidIdentifier } `) diff --git a/test/invalid-identifier/invalid-identifier.go b/test/invalid-identifier/invalid-identifier.go new file mode 100644 index 00000000000..1b13723059b --- /dev/null +++ b/test/invalid-identifier/invalid-identifier.go @@ -0,0 +1,5 @@ +package invalid_identifier + +type InvalidIdentifier struct { + ID int +} diff --git a/test/resolvers_test.go b/test/resolvers_test.go index 39cdfcca38e..1a8bd226aed 100644 --- a/test/resolvers_test.go +++ b/test/resolvers_test.go @@ -14,6 +14,7 @@ import ( gqlerrors "github.com/vektah/gqlgen/neelance/errors" "github.com/vektah/gqlgen/neelance/query" "github.com/vektah/gqlgen/test/introspection" + invalid_identifier "github.com/vektah/gqlgen/test/invalid-identifier" "github.com/vektah/gqlgen/test/models" ) @@ -77,12 +78,13 @@ func mkctx(doc *query.Document, errFn func(e error) string) context.Context { } type testResolvers struct { - inner models.InnerObject - innerErr error - nestedInputs *bool - nestedInputsErr error - nestedOutputs [][]models.OuterObject - nestedOutputsErr error + inner models.InnerObject + innerErr error + nestedInputs *bool + nestedInputsErr error + nestedOutputs [][]models.OuterObject + nestedOutputsErr error + invalidIdentifier *invalid_identifier.InvalidIdentifier } func (r *testResolvers) Query_shapes(ctx context.Context) ([]Shape, error) { @@ -113,6 +115,10 @@ func (r *testResolvers) Query_nestedOutputs(ctx context.Context) ([][]models.Out return r.nestedOutputs, r.nestedOutputsErr } +func (r *testResolvers) Query_invalidIdentifier(ctx context.Context) (*invalid_identifier.InvalidIdentifier, error) { + return r.invalidIdentifier, nil +} + type specialErr struct{} func (*specialErr) Error() string { diff --git a/test/schema.graphql b/test/schema.graphql index 029b976103a..52d9c475a4b 100644 --- a/test/schema.graphql +++ b/test/schema.graphql @@ -44,6 +44,10 @@ type It { id: ID! } +type InvalidIdentifier { + id: Int! +} + type Query { nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean nestedOutputs: [[OuterObject]] @@ -51,4 +55,5 @@ type Query { recursive(input: RecursiveInputSlice): Boolean mapInput(input: Changes): Boolean collision: It + invalidIdentifier: InvalidIdentifier } diff --git a/test/types.json b/test/types.json index 358fedf6dd3..58035934ffa 100644 --- a/test/types.json +++ b/test/types.json @@ -5,5 +5,6 @@ "Rectangle": "github.com/vektah/gqlgen/test.Rectangle", "RecursiveInputSlice": "github.com/vektah/gqlgen/test.RecursiveInputSlice", "It": "github.com/vektah/gqlgen/test/introspection.It", - "Changes": "map[string]interface{}" + "Changes": "map[string]interface{}", + "InvalidIdentifier": "github.com/vektah/gqlgen/test/invalid-identifier.InvalidIdentifier" }