diff --git a/.circleci/config.yml b/.circleci/config.yml index 4e0c9ec..970c892 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,39 +1,12 @@ version: 2 jobs: - go1.7: &base + build: docker: - - image: golang:1.7 - working_directory: /go/src/github.com/vektah/dataloaden + - image: golang:1.11 + working_directory: /projects/dataloaden steps: &steps - checkout - - run: > - curl -L -o /bin/dep https://github.com/golang/dep/releases/download/v0.4.1/dep-linux-amd64 && - chmod +x /bin/dep && - go get -u github.com/alecthomas/gometalinter && - gometalinter --install && - dep ensure --vendor-only - - run: go install -v . - run: go generate ./example/... && if [[ $(git diff) ]] ; then echo "you need to run go generate" ; git diff ; exit 1 ; fi - - run: go vet ./example/... - run: go test -bench=. -benchmem -v ./example/... - run: go test -bench=. -benchmem -v ./example/... -race - run: go test -coverprofile=coverage.txt -covermode=atomic ./example && bash <(curl -s https://codecov.io/bash) - - run: gometalinter --disable gocyclo ./example - - go1.8: - <<: *base - docker: - - image: golang:1.8 - - go1.9: - <<: *base - docker: - - image: golang:1.9 - -workflows: - version: 2 - build: - jobs: - - "go1.7" - - "go1.8" - - "go1.9" diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index c9d865c..0000000 --- a/Gopkg.lock +++ /dev/null @@ -1,58 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" - name = "github.com/davecgh/go-spew" - packages = ["spew"] - pruneopts = "UT" - revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" - version = "v1.1.1" - -[[projects]] - digest = "1:cf31692c14422fa27c83a05292eb5cbe0fb2775972e8f1f8446a71549bd8980b" - name = "github.com/pkg/errors" - packages = ["."] - pruneopts = "UT" - revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4" - version = "v0.8.1" - -[[projects]] - digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" - name = "github.com/pmezard/go-difflib" - packages = ["difflib"] - pruneopts = "UT" - revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.0.0" - -[[projects]] - digest = "1:5da8ce674952566deae4dbc23d07c85caafc6cfa815b0b3e03e41979cedb8750" - name = "github.com/stretchr/testify" - packages = [ - "assert", - "require", - ] - pruneopts = "UT" - revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053" - version = "v1.3.0" - -[[projects]] - digest = "1:2c57a52b1792fad8b668be56c76a9a4959f7b665b8474cfa188c652ef1a2b82d" - name = "golang.org/x/tools" - packages = [ - "go/ast/astutil", - "imports", - ] - pruneopts = "UT" - revision = "66487607e2081c7c2af2281c62c14ee000d5024b" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = [ - "github.com/pkg/errors", - "github.com/stretchr/testify/require", - "golang.org/x/tools/imports", - ] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100644 index d92df3b..0000000 --- a/Gopkg.toml +++ /dev/null @@ -1,11 +0,0 @@ -[[constraint]] - name = "github.com/stretchr/testify" - version = "1.2.1" - -[[constraint]] - revision = "66487607e2081c7c2af2281c62c14ee000d5024b" - name = "golang.org/x/tools" - -[prune] - go-tests = true - unused-packages = true diff --git a/README.md b/README.md index 2e902d1..645c3cf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ ### The DATALOADer gENerator [![CircleCI](https://circleci.com/gh/Vektah/dataloaden.svg?style=svg)](https://circleci.com/gh/Vektah/dataloaden) [![Go Report Card](https://goreportcard.com/badge/github.com/vektah/dataloaden)](https://goreportcard.com/report/github.com/vektah/dataloaden) [![codecov](https://codecov.io/gh/vektah/dataloaden/branch/master/graph/badge.svg)](https://codecov.io/gh/vektah/dataloaden) +Requires golang 1.11+ for modules support. This is a tool for generating type safe data loaders for go, inspired by https://github.com/facebook/dataloader. @@ -58,6 +59,22 @@ dataloaden -slice github.com/dataloaden/example.User Now each key is expected to return a slice of values and the `fetch` function has the return type `[][]User`. +#### Using with go modules + +Create a tools.go that looks like this: +```go +// +build tools + +package main + +import _ "github.com/vektah/dataloaden" +``` + +This will allow go modules to see the dependency. + +You can invoke it from anywhere within your module now using `go run github.com/vektah/dataloaden` and +always get the pinned version. + #### Wait, how do I use context with this? I don't think context makes sense to be passed through a data loader. Consider a few scenarios: diff --git a/appveyor.yml b/appveyor.yml index 6ad6f08..ee3ff89 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,13 +3,13 @@ version: "{build}" # Source Config skip_branch_with_pr: true -clone_folder: c:\gopath\src\github.com\vektah\dataloaden +clone_folder: c:\projects\dataloaden # Build host environment: GOPATH: c:\gopath - GOVERSION: 1.10 + GOVERSION: 1.11.5 PATH: '%PATH%;c:\gopath\bin' init: @@ -28,6 +28,5 @@ build: false deploy: false test_script: - - go get -t ./... - go generate ./... - - go test ./... + - go test -parallel 8 ./... diff --git a/example/pkgname/user.go b/example/pkgname/user.go index c10c7ac..754c48c 100644 --- a/example/pkgname/user.go +++ b/example/pkgname/user.go @@ -1,3 +1,3 @@ package differentpkg -//go:generate go run ../../dataloaden.go -keys string github.com/vektah/dataloaden/example.User +//go:generate go run github.com/vektah/dataloaden -keys string github.com/vektah/dataloaden/example.User diff --git a/example/slice/user.go b/example/slice/user.go index f98a171..9b43ab4 100644 --- a/example/slice/user.go +++ b/example/slice/user.go @@ -1,4 +1,4 @@ -//go:generate go run ../../dataloaden.go -keys int -slice github.com/vektah/dataloaden/example.User +//go:generate go run github.com/vektah/dataloaden -keys int -slice github.com/vektah/dataloaden/example.User package slice diff --git a/example/user.go b/example/user.go index 8a86c6c..587f1c6 100644 --- a/example/user.go +++ b/example/user.go @@ -1,4 +1,4 @@ -//go:generate go run ../dataloaden.go -keys string github.com/vektah/dataloaden/example.User +//go:generate go run github.com/vektah/dataloaden -keys string github.com/vektah/dataloaden/example.User package example diff --git a/example/user_test.go b/example/user_test.go index 3f8797d..4937f06 100644 --- a/example/user_test.go +++ b/example/user_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -80,8 +81,8 @@ func TestUserLoader(t *testing.T) { defer mu.Unlock() require.Len(t, fetches, 2) - require.Len(t, fetches[0], 5) - require.Len(t, fetches[1], 3) + assert.Len(t, fetches[0], 5) + assert.Len(t, fetches[1], 3) }) t.Run("fetch more", func(t *testing.T) { diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..01c7c28 --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module github.com/vektah/dataloaden + +require ( + github.com/davecgh/go-spew v1.1.0 // indirect + github.com/pkg/errors v0.8.1 + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.2.1 + golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e6bd4bb --- /dev/null +++ b/go.sum @@ -0,0 +1,11 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golangci/golangci-lint v1.13.1 h1:e4khAARYjxlcEtEZgPqqaeoIVWlHmsZ4c+g5nJUpdUQ= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U= +github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6 h1:iZgcI2DDp6zW5v9Z/5+f0NuqoxNdmzg4hivjk2WLXpY= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go index 93296e1..e40642d 100644 --- a/pkg/generator/generator.go +++ b/pkg/generator/generator.go @@ -3,13 +3,13 @@ package generator import ( "bytes" "fmt" - "go/build" "io/ioutil" "path/filepath" "strings" "unicode" "github.com/pkg/errors" + "golang.org/x/tools/go/packages" "golang.org/x/tools/imports" ) @@ -49,9 +49,15 @@ func getData(typeName string, keyType string, slice bool, wd string) (templateDa return templateData{}, fmt.Errorf("type must be in the form package.Name") } - pkgData := getPackage(wd) name := parts[len(parts)-1] - data.Package = pkgData + importPath := strings.Join(parts[:len(parts)-1], ".") + + genPkg := getPackage(wd) + if genPkg == nil { + return templateData{}, fmt.Errorf("unable to find package info for " + wd) + } + + data.Package = genPkg.Name data.LoaderName = name + "Loader" data.BatchName = lcFirst(name) + "Batch" data.Name = lcFirst(name) @@ -66,24 +72,26 @@ func getData(typeName string, keyType string, slice bool, wd string) (templateDa } // if we are inside the same package as the type we don't need an import and can refer directly to the type - pkgName := strings.Join(parts[:len(parts)-1], ".") - if strings.HasSuffix(filepath.ToSlash(wd), pkgName) { + if genPkg.PkgPath == importPath { data.ValType = prefix + name } else { - data.Import = pkgName + data.Import = importPath data.ValType = prefix + filepath.Base(data.Import) + "." + name } return data, nil } -func getPackage(wd string) string { - result, err := build.ImportDir(wd, build.IgnoreVendor) - if err != nil { - return filepath.Base(wd) +func getPackage(dir string) *packages.Package { + p, _ := packages.Load(&packages.Config{ + Dir: dir, + }, ".") + + if len(p) != 1 { + return nil } - return result.Name + return p[0] } func writeTemplate(filepath string, data templateData) error {