deals with go modules and sub-packages

Этот коммит содержится в:
hgouchet 2018-09-29 12:28:54 +02:00
родитель 6943e03b65
коммит b03bcc9c55

Просмотреть файл

@ -4,6 +4,7 @@ package godog
import (
"bytes"
"encoding/json"
"fmt"
"go/build"
"go/parser"
@ -303,45 +304,68 @@ func makeImportValid(r rune) rune {
// it scans test files for contexts
// and produces a testmain source code.
func buildTestMain(pkg *build.Package) ([]byte, bool, error) {
var contexts []string
var importPath string
name := "main"
var (
contexts []string
err error
name, importPath string
)
if nil != pkg {
ctxs, err := processPackageTestFiles(
contexts, err = processPackageTestFiles(
pkg.TestGoFiles,
pkg.XTestGoFiles,
)
if err != nil {
return nil, false, err
}
contexts = ctxs
// for module support, query the module import path
// @TODO: maybe there is a better way to read it
out, err := exec.Command("go", "list", "-m").CombinedOutput()
if err != nil {
// is not using modules or older go version
importPath = pkg.ImportPath
} else {
// otherwise read the module name from command output
importPath = strings.TrimSpace(string(out))
}
importPath = parseImport(pkg.ImportPath)
name = pkg.Name
} else {
name = "main"
}
data := struct {
Name string
Contexts []string
ImportPath string
}{name, contexts, importPath}
}{
Name: name,
Contexts: contexts,
ImportPath: importPath,
}
var buf bytes.Buffer
if err := runnerTemplate.Execute(&buf, data); err != nil {
if err = runnerTemplate.Execute(&buf, data); err != nil {
return nil, len(contexts) > 0, err
}
return buf.Bytes(), len(contexts) > 0, nil
}
// parseImport parses the import path to deal with go module.
func parseImport(rawPath string) string {
// for module support, query the module import path
cmd := exec.Command("go", "list", "-m", "-json")
out, err := cmd.StdoutPipe()
if err != nil {
// Unable to read stdout
return rawPath
}
if cmd.Start() != nil {
// Does not using modules
return rawPath
}
var mod struct {
Dir string `json:"Dir"`
Path string `json:"Path"`
}
if json.NewDecoder(out).Decode(&mod) != nil {
// Unexpected result
return rawPath
}
if cmd.Wait() != nil {
return rawPath
}
// Concatenates the module path with the current sub-folders if needed
return mod.Path + filepath.ToSlash(strings.TrimPrefix(strings.TrimPrefix(rawPath, "_"), mod.Dir))
}
// processPackageTestFiles runs through ast of each test
// file pack and looks for godog suite contexts to register
// on run
@ -389,16 +413,13 @@ func dependencies(pkg *build.Package, visited map[string]string, vendor bool) er
if i := strings.LastIndex(name, "vendor/"); vendor && i == -1 {
continue // only interested in vendor packages
}
if _, ok := visited[name]; ok {
continue
}
next, err := locatePackage(name)
if err != nil {
return err
}
visited[name] = pkg.PkgObj
if err := dependencies(next, visited, vendor); err != nil {
return err