Skip to content

Commit

Permalink
Merge pull request #179 from vektah/models-config-error
Browse files Browse the repository at this point in the history
Improve Output Filename and Package Handling
  • Loading branch information
Mathew Byrne authored Jul 10, 2018
2 parents 6391596 + 936bc76 commit 43212c0
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 57 deletions.
1 change: 1 addition & 0 deletions codegen/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ func (cfg *Config) bind() (*Build, error) {
Interfaces: cfg.buildInterfaces(namedTypes, prog),
Inputs: inputs,
Imports: imports.finalize(),
SchemaRaw: cfg.SchemaStr,
}

if qr, ok := cfg.schema.EntryPoints["query"]; ok {
Expand Down
21 changes: 0 additions & 21 deletions codegen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ package codegen
import (
"bytes"
"fmt"
"go/build"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
"syscall"

"github.com/pkg/errors"
Expand All @@ -30,7 +28,6 @@ func Generate(cfg Config) error {
return errors.Wrap(err, "model plan failed")
}
if len(modelsBuild.Models) > 0 || len(modelsBuild.Enums) > 0 {
modelsBuild.PackageName = cfg.Model.Package
var buf *bytes.Buffer
buf, err = templates.Run("models.gotpl", modelsBuild)
if err != nil {
Expand All @@ -57,8 +54,6 @@ func Generate(cfg Config) error {
if err != nil {
return errors.Wrap(err, "exec plan failed")
}
build.SchemaRaw = cfg.SchemaStr
build.PackageName = cfg.Exec.Package

var buf *bytes.Buffer
buf, err = templates.Run("generated.gotpl", build)
Expand Down Expand Up @@ -129,22 +124,6 @@ func abs(path string) string {
return filepath.ToSlash(absPath)
}

func importPath(dir string, pkgName string) string {
fullPkgName := filepath.Join(filepath.Dir(dir), pkgName)

for _, gopath := range filepath.SplitList(build.Default.GOPATH) {
gopath = filepath.Join(gopath, "src") + string(os.PathSeparator)
if len(gopath) > len(fullPkgName) {
continue
}
if strings.EqualFold(gopath, fullPkgName[0:len(gopath)]) {
fullPkgName = fullPkgName[len(gopath):]
break
}
}
return filepath.ToSlash(fullPkgName)
}

func gofmt(filename string, b []byte) ([]byte, error) {
out, err := imports.Process(filename, b, nil)
if err != nil {
Expand Down
31 changes: 0 additions & 31 deletions codegen/codegen_test.go

This file was deleted.

49 changes: 44 additions & 5 deletions codegen/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package codegen

import (
"fmt"
"go/build"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/pkg/errors"
"github.com/vektah/gqlgen/neelance/schema"
Expand Down Expand Up @@ -80,25 +82,59 @@ func (c *PackageConfig) normalize() error {
return errors.New("Filename is required")
}
c.Filename = abs(c.Filename)
// If Package is not set, first attempt to load the package at the output dir. If that fails
// fallback to just the base dir name of the output filename.
if c.Package == "" {
c.Package = filepath.Base(c.Dir())
cwd, _ := os.Getwd()
pkg, _ := build.Default.Import(c.ImportPath(), cwd, 0)
if pkg.Name != "" {
c.Package = pkg.Name
} else {
c.Package = filepath.Base(c.Dir())
}
}
c.Package = sanitizePackageName(c.Package)
return nil
}

func (c *PackageConfig) ImportPath() string {
return importPath(c.Dir(), c.Package)
dir := c.Dir()
for _, gopath := range filepath.SplitList(build.Default.GOPATH) {
gopath = filepath.Join(gopath, "src") + string(os.PathSeparator)
if len(gopath) > len(dir) {
continue
}
if strings.EqualFold(gopath, dir[0:len(gopath)]) {
dir = dir[len(gopath):]
break
}
}
return filepath.ToSlash(dir)
}

func (c *PackageConfig) Dir() string {
return filepath.ToSlash(filepath.Dir(c.Filename))
}

func (c *PackageConfig) Check() error {
if strings.ContainsAny(c.Package, "./\\") {
return fmt.Errorf("package should be the output package name only, do not include the output filename")
}
if c.Filename != "" && !strings.HasSuffix(c.Filename, ".go") {
return fmt.Errorf("filename should be path to a go source file")
}
return nil
}

func (cfg *Config) Check() error {
err := cfg.Models.Check()
if err != nil {
return fmt.Errorf("config: %s", err.Error())
if err := cfg.Models.Check(); err != nil {
return errors.Wrap(err, "config.models")
}
if err := cfg.Exec.Check(); err != nil {
return errors.Wrap(err, "config.exec")
}
if err := cfg.Model.Check(); err != nil {
return errors.Wrap(err, "config.model")
}
return nil
}
Expand All @@ -115,6 +151,9 @@ func (tm TypeMap) Check() error {
if entry.Model == "" {
return fmt.Errorf("model %s: entityPath is not defined", typeName)
}
if strings.LastIndex(entry.Model, ".") < strings.LastIndex(entry.Model, "/") {
return fmt.Errorf("model %s: invalid type specifier \"%s\" - you need to specify a struct to map to", typeName, entry.Model)
}
}
return nil
}
Expand Down
26 changes: 26 additions & 0 deletions codegen/config_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package codegen

import (
"go/build"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -52,3 +54,27 @@ func TestLoadDefaultConfig(t *testing.T) {
require.Equal(t, cfg.SchemaFilename, "schema.graphql")
})
}

func Test_fullPackageName(t *testing.T) {
origBuildContext := build.Default
defer func() { build.Default = origBuildContext }()

t.Run("gopath longer than package name", func(t *testing.T) {
p := PackageConfig{Filename: "/b/src/y/foo/bar/baz.go"}
build.Default.GOPATH = "/a/src/xxxxxxxxxxxxxxxxxxxxxxxx:/b/src/y"
var got string
ok := assert.NotPanics(t, func() { got = p.ImportPath() })
if ok {
assert.Equal(t, "/b/src/y/foo/bar", got)
}
})
t.Run("stop searching on first hit", func(t *testing.T) {
p := PackageConfig{Filename: "/a/src/x/foo/bar/baz.go"}
build.Default.GOPATH = "/a/src/x:/b/src/y"
var got string
ok := assert.NotPanics(t, func() { got = p.ImportPath() })
if ok {
assert.Equal(t, "/a/src/x/foo/bar", got)
}
})
}

0 comments on commit 43212c0

Please sign in to comment.