diff --git a/.github/workflows/check-linting b/.github/workflows/check-linting index e91d021383f..b7b771bcb35 100755 --- a/.github/workflows/check-linting +++ b/.github/workflows/check-linting @@ -2,6 +2,7 @@ set -euo pipefail -curl -sL --fail https://github.com/golangci/golangci-lint/releases/download/v1.23.2/golangci-lint-1.23.2-linux-amd64.tar.gz | tar zxv --strip-components=1 --dir=/go/bin +mkdir /tmp/golangci +curl -sL --fail https://github.com/golangci/golangci-lint/releases/download/v1.29.0/golangci-lint-1.29.0-linux-amd64.tar.gz | tar zxv --strip-components=1 --dir=/tmp/golangci -golangci-lint run +/tmp/golangci/golangci-lint run diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index beba6a25d70..00000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Continuous Integration -on: [push, pull_request] - -jobs: - lint: - runs-on: ubuntu-latest - container: golang:1.13 - steps: - - uses: actions/checkout@v1 - - run: go mod download - - run: .github/workflows/check-fmt - - run: .github/workflows/check-linting - - run: .github/workflows/check-generate - - test: - runs-on: ubuntu-latest - container: golang:1.13 - steps: - - uses: actions/checkout@v1 - - run: go mod download - - run: go test -race ./... - - coverage: - runs-on: ubuntu-latest - container: golang:1.13 - steps: - - uses: actions/checkout@v1 - - run: go mod download - - run: .github/workflows/check-coverage - env: - COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - integration: - runs-on: ubuntu-latest - timeout-minutes: 3 - container: alpine:3.10 - steps: - - uses: actions/checkout@v1 - - run: apk add --no-cache --no-progress nodejs npm go musl-dev git bash - - run: go mod download - - run: cd integration ; npm install - - run: .github/workflows/check-integration - - federation: - runs-on: ubuntu-latest - container: alpine:3.10 - steps: - - uses: actions/checkout@v1 - - run: apk add --no-cache --no-progress nodejs npm go musl-dev git bash - - run: go mod download - - run: cd example/federation ; npm install - - run: .github/workflows/check-federation - - windows: - runs-on: windows-latest - steps: - - run: git config --global core.autocrlf input - - uses: actions/setup-go@v1 - with: - go-version: 1.13 - - uses: actions/checkout@v1 - - run: go generate ./... - - run: go test -timeout 20m ./... diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 00000000000..444a93386d8 --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,24 @@ +name: Integration +on: [push, pull_request] + +jobs: + integration: + runs-on: ubuntu-latest + timeout-minutes: 3 + container: alpine:3.10 + steps: + - uses: actions/checkout@v1 + - run: apk add --no-cache --no-progress nodejs npm go musl-dev git bash + - run: go mod download + - run: cd integration ; npm install + - run: .github/workflows/check-integration + + federation: + runs-on: ubuntu-latest + container: alpine:3.10 + steps: + - uses: actions/checkout@v1 + - run: apk add --no-cache --no-progress nodejs npm go musl-dev git bash + - run: go mod download + - run: cd example/federation ; npm install + - run: .github/workflows/check-federation diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000000..27b256b6f9f --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,25 @@ +name: Lint +on: [push, pull_request] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-go@v2 + with: { go-version: 1.14 } + - run: go mod download + - run: .github/workflows/check-fmt + - run: .github/workflows/check-linting + - run: .github/workflows/check-generate + + coverage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-go@v2 + with: { go-version: 1.14 } + - run: go mod download + - run: .github/workflows/check-coverage + env: + COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000000..d7c6fccf28c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,18 @@ +name: Test +on: [push, pull_request] + +jobs: + test: + strategy: + matrix: + go: [1.12, 1.14] + os: [ubuntu-latest, windows-latest] + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + - run: go mod download + - run: go test -race ./... diff --git a/.golangci.yml b/.golangci.yml index 331d4e350ac..8d513868009 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -18,7 +18,6 @@ linters: - gocritic - gofmt - goimports - - gosec - gosimple - govet - ineffassign diff --git a/codegen/field.go b/codegen/field.go index 74c077a71c9..2d12980e004 100644 --- a/codegen/field.go +++ b/codegen/field.go @@ -491,7 +491,7 @@ func (f *Field) ShortResolverDeclaration() string { } func (f *Field) ComplexitySignature() string { - res := fmt.Sprintf("func(childComplexity int") + res := "func(childComplexity int" for _, arg := range f.Args { res += fmt.Sprintf(", %s %s", arg.VarName, templates.CurrentImports.LookupType(arg.TypeReference.GO)) } diff --git a/codegen/testserver/directive_test.go b/codegen/testserver/directive_test.go index 1c63441e010..3e5b485cc06 100644 --- a/codegen/testserver/directive_test.go +++ b/codegen/testserver/directive_test.go @@ -11,6 +11,8 @@ import ( "github.com/stretchr/testify/require" ) +type ckey string + func TestDirectives(t *testing.T) { resolvers := &Stub{} ok := "Ok" @@ -48,7 +50,7 @@ func TestDirectives(t *testing.T) { } resolvers.QueryResolver.DirectiveField = func(ctx context.Context) (*string, error) { - if s, ok := ctx.Value("request_id").(*string); ok { + if s, ok := ctx.Value(ckey("request_id")).(*string); ok { return s, nil } @@ -149,7 +151,7 @@ func TestDirectives(t *testing.T) { return next(ctx) }, Logged: func(ctx context.Context, obj interface{}, next graphql.Resolver, id string) (interface{}, error) { - return next(context.WithValue(ctx, "request_id", &id)) + return next(context.WithValue(ctx, ckey("request_id"), &id)) }, ToNull: func(ctx context.Context, obj interface{}, next graphql.Resolver) (interface{}, error) { return nil, nil @@ -172,13 +174,13 @@ func TestDirectives(t *testing.T) { })) srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - path, _ := ctx.Value("path").([]int) - return next(context.WithValue(ctx, "path", append(path, 1))) + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 1))) }) srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - path, _ := ctx.Value("path").([]int) - return next(context.WithValue(ctx, "path", append(path, 2))) + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 2))) }) c := client.New(srv) diff --git a/codegen/testserver/middleware_test.go b/codegen/testserver/middleware_test.go index 721f4532272..07591dafc09 100644 --- a/codegen/testserver/middleware_test.go +++ b/codegen/testserver/middleware_test.go @@ -31,13 +31,13 @@ func TestMiddleware(t *testing.T) { NewExecutableSchema(Config{Resolvers: resolvers}), ) srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - path, _ := ctx.Value("path").([]int) - return next(context.WithValue(ctx, "path", append(path, 1))) + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 1))) }) srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - path, _ := ctx.Value("path").([]int) - return next(context.WithValue(ctx, "path", append(path, 2))) + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 2))) }) srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { @@ -58,7 +58,7 @@ func TestMiddleware(t *testing.T) { called := false resolvers.UserResolver.Friends = func(ctx context.Context, obj *User) ([]*User, error) { - assert.Equal(t, []int{1, 2, 1, 2}, ctx.Value("path")) + assert.Equal(t, []int{1, 2, 1, 2}, ctx.Value(ckey("path"))) called = true return []*User{}, nil } diff --git a/codegen/testserver/subscription_test.go b/codegen/testserver/subscription_test.go index 1731aae9b46..d855fcc69bf 100644 --- a/codegen/testserver/subscription_test.go +++ b/codegen/testserver/subscription_test.go @@ -72,13 +72,13 @@ func TestSubscriptions(t *testing.T) { NewExecutableSchema(Config{Resolvers: resolvers}), ) srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - path, _ := ctx.Value("path").([]int) - return next(context.WithValue(ctx, "path", append(path, 1))) + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 1))) }) srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - path, _ := ctx.Value("path").([]int) - return next(context.WithValue(ctx, "path", append(path, 2))) + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 2))) }) c := client.New(srv) diff --git a/example/chat/resolvers.go b/example/chat/resolvers.go index 023b88f664e..baeee1c1976 100644 --- a/example/chat/resolvers.go +++ b/example/chat/resolvers.go @@ -11,6 +11,8 @@ import ( "github.com/99designs/gqlgen/graphql" ) +type ckey string + type resolver struct { Rooms map[string]*Chatroom mu sync.Mutex // nolint: structcheck @@ -35,14 +37,14 @@ func New() Config { }, Directives: DirectiveRoot{ User: func(ctx context.Context, obj interface{}, next graphql.Resolver, username string) (res interface{}, err error) { - return next(context.WithValue(ctx, "username", username)) + return next(context.WithValue(ctx, ckey("username"), username)) }, }, } } func getUsername(ctx context.Context) string { - if username, ok := ctx.Value("username").(string); ok { + if username, ok := ctx.Value(ckey("username")).(string); ok { return username } return "" diff --git a/example/todo/todo.go b/example/todo/todo.go index fdacb112d67..28a31fdc866 100644 --- a/example/todo/todo.go +++ b/example/todo/todo.go @@ -15,8 +15,10 @@ import ( var you = &User{ID: 1, Name: "You"} var them = &User{ID: 2, Name: "Them"} +type ckey string + func getUserId(ctx context.Context) int { - if id, ok := ctx.Value("userId").(int); ok { + if id, ok := ctx.Value(ckey("userId")).(int); ok { return id } return you.ID @@ -53,7 +55,7 @@ func New() Config { return next(ctx) } c.Directives.User = func(ctx context.Context, obj interface{}, next graphql.Resolver, id int) (interface{}, error) { - return next(context.WithValue(ctx, "userId", id)) + return next(context.WithValue(ctx, ckey("userId"), id)) } return c } diff --git a/graphql/handler/transport/websocket_test.go b/graphql/handler/transport/websocket_test.go index 15bf4515095..a02fb17002d 100644 --- a/graphql/handler/transport/websocket_test.go +++ b/graphql/handler/transport/websocket_test.go @@ -21,6 +21,8 @@ import ( "github.com/vektah/gqlparser/v2/ast" ) +type ckey string + func TestWebsocket(t *testing.T) { handler := testserver.New() handler.AddTransport(transport.Websocket{}) @@ -194,7 +196,7 @@ func TestWebsocketInitFunc(t *testing.T) { h := testserver.New() h.AddTransport(transport.Websocket{ InitFunc: func(ctx context.Context, initPayload transport.InitPayload) (context.Context, error) { - return context.WithValue(ctx, "newkey", "newvalue"), nil + return context.WithValue(ctx, ckey("newkey"), "newvalue"), nil }, }) srv := httptest.NewServer(h) @@ -232,7 +234,7 @@ func TestWebsocketInitFunc(t *testing.T) { t.Run("can return context for request from WebsocketInitFunc", func(t *testing.T) { es := &graphql.ExecutableSchemaMock{ ExecFunc: func(ctx context.Context) graphql.ResponseHandler { - assert.Equal(t, "newvalue", ctx.Value("newkey")) + assert.Equal(t, "newvalue", ctx.Value(ckey("newkey"))) return graphql.OneShot(&graphql.Response{Data: []byte(`{"empty":"ok"}`)}) }, SchemaFunc: func() *ast.Schema { @@ -248,7 +250,7 @@ func TestWebsocketInitFunc(t *testing.T) { h.AddTransport(transport.Websocket{ InitFunc: func(ctx context.Context, initPayload transport.InitPayload) (context.Context, error) { - return context.WithValue(ctx, "newkey", "newvalue"), nil + return context.WithValue(ctx, ckey("newkey"), "newvalue"), nil }, }) diff --git a/internal/code/imports.go b/internal/code/imports.go index e861a6eb5d0..b56d80fc54c 100644 --- a/internal/code/imports.go +++ b/internal/code/imports.go @@ -80,6 +80,7 @@ func goModuleRoot(dir string) (string, bool) { // ImportPathForDir takes a path and returns a golang import path for the package func ImportPathForDir(dir string) (res string) { dir, err := filepath.Abs(dir) + if err != nil { panic(err) } @@ -99,4 +100,4 @@ func ImportPathForDir(dir string) (res string) { return "" } -var modregex = regexp.MustCompile("module (.*)\n") +var modregex = regexp.MustCompile(`module ([^\s]*)`) diff --git a/internal/code/imports_test.go b/internal/code/imports_test.go index ec00982f3cd..2dcbf9f04fb 100644 --- a/internal/code/imports_test.go +++ b/internal/code/imports_test.go @@ -12,6 +12,7 @@ import ( func TestImportPathForDir(t *testing.T) { wd, err := os.Getwd() + require.NoError(t, err) assert.Equal(t, "github.com/99designs/gqlgen/internal/code", ImportPathForDir(wd)) diff --git a/internal/imports/prune_test.go b/internal/imports/prune_test.go index a50220d7578..26ff109fc52 100644 --- a/internal/imports/prune_test.go +++ b/internal/imports/prune_test.go @@ -2,6 +2,7 @@ package imports import ( "io/ioutil" + "strings" "testing" "github.com/99designs/gqlgen/internal/code" @@ -13,7 +14,7 @@ func TestPrune(t *testing.T) { b, err := Prune("testdata/unused.go", mustReadFile("testdata/unused.go"), &code.Packages{}) require.NoError(t, err) - require.Equal(t, string(mustReadFile("testdata/unused.expected.go")), string(b)) + require.Equal(t, strings.Replace(string(mustReadFile("testdata/unused.expected.go")), "\r\n", "\n", -1), string(b)) } func mustReadFile(filename string) []byte { diff --git a/internal/rewrite/rewriter.go b/internal/rewrite/rewriter.go index 98ec37e58b6..c6dde523e7a 100644 --- a/internal/rewrite/rewriter.go +++ b/internal/rewrite/rewriter.go @@ -29,6 +29,13 @@ func New(importPath string) (*Rewriter, error) { if len(pkgs) == 0 { return nil, fmt.Errorf("package not found for importPath: %s", importPath) } + if len(pkgs[0].Errors) != 0 { + for _, e := range pkgs[0].Errors { + if e.Kind == packages.ListError { + return nil, e + } + } + } return &Rewriter{ pkg: pkgs[0], diff --git a/internal/rewrite/rewriter_test.go b/internal/rewrite/rewriter_test.go index 763eaa2768c..6f7502e486f 100644 --- a/internal/rewrite/rewriter_test.go +++ b/internal/rewrite/rewriter_test.go @@ -1,6 +1,7 @@ package rewrite import ( + "strings" "testing" "github.com/stretchr/testify/assert" @@ -20,7 +21,7 @@ func TestRewriter(t *testing.T) { m.Field++ // trailing comment -`, body) +`, strings.Replace(body, "\r\n", "\n", -1)) imps := r.ExistingImports("testdata/example.go") require.Len(t, imps, 2)