interp: support another vendoring case
This commit is contained in:
17
example/pkg/_pkg10/src/github.com/foo/pkg.go
Normal file
17
example/pkg/_pkg10/src/github.com/foo/pkg.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"guthib.com/containous/fromage"
|
||||
)
|
||||
|
||||
func Here() string {
|
||||
return "root"
|
||||
}
|
||||
|
||||
func NewSample() func() string {
|
||||
return func() string {
|
||||
return fmt.Sprintf("%s %s", Here(), fromage.Hello())
|
||||
}
|
||||
}
|
||||
7
example/pkg/_pkg10/src/github.com/foo/vendor/guthib.com/containous/fromage/fromage.go
generated
vendored
Normal file
7
example/pkg/_pkg10/src/github.com/foo/vendor/guthib.com/containous/fromage/fromage.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package fromage
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Hello() string {
|
||||
return fmt.Sprint("Fromage")
|
||||
}
|
||||
11
example/pkg/_pkg11/src/foo/foo.go
Normal file
11
example/pkg/_pkg11/src/foo/foo.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"guthib.com/containous/fromage"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Print(fromage.Hello())
|
||||
}
|
||||
7
example/pkg/_pkg11/src/foo/vendor/guthib.com/containous/fromage/fromage.go
generated
vendored
Normal file
7
example/pkg/_pkg11/src/foo/vendor/guthib.com/containous/fromage/fromage.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package fromage
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Hello() string {
|
||||
return fmt.Sprint("Fromage")
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
@@ -10,9 +15,11 @@ import (
|
||||
|
||||
func TestPackages(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
goPath string
|
||||
expected string
|
||||
desc string
|
||||
goPath string
|
||||
expected string
|
||||
topImport string
|
||||
evalFile string
|
||||
}{
|
||||
{
|
||||
desc: "vendor",
|
||||
@@ -64,6 +71,18 @@ func TestPackages(t *testing.T) {
|
||||
goPath: "./_pkg8/",
|
||||
expected: "root Fromage!",
|
||||
},
|
||||
{
|
||||
desc: "at the project root",
|
||||
goPath: "./_pkg10/",
|
||||
expected: "root Fromage",
|
||||
topImport: "github.com/foo",
|
||||
},
|
||||
{
|
||||
desc: "eval main that has vendored dep",
|
||||
goPath: "./_pkg11/",
|
||||
expected: "Fromage",
|
||||
evalFile: "./_pkg11/src/foo/foo.go",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
@@ -78,20 +97,61 @@ func TestPackages(t *testing.T) {
|
||||
i := interp.New(interp.Options{GoPath: goPath})
|
||||
i.Use(stdlib.Symbols) // Use binary standard library
|
||||
|
||||
// Load pkg from sources
|
||||
if _, err = i.Eval(`import "github.com/foo/pkg"`); err != nil {
|
||||
t.Fatal(err)
|
||||
var msg string
|
||||
if test.evalFile != "" {
|
||||
// setting i.Name as this is how it's actually done in cmd/yaegi
|
||||
i.Name = test.evalFile
|
||||
data, err := ioutil.ReadFile(test.evalFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// TODO(mpl): this is brittle if we do concurrent tests and stuff, do better later.
|
||||
stdout := os.Stdout
|
||||
defer func() { os.Stdout = stdout }()
|
||||
pr, pw, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.Stdout = pw
|
||||
|
||||
if _, err := i.Eval(string(data)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
errC := make(chan error)
|
||||
go func() {
|
||||
_, err := io.Copy(&buf, pr)
|
||||
errC <- err
|
||||
}()
|
||||
|
||||
if err := pw.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := <-errC; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
msg = buf.String()
|
||||
} else {
|
||||
// Load pkg from sources
|
||||
topImport := "github.com/foo/pkg"
|
||||
if test.topImport != "" {
|
||||
topImport = test.topImport
|
||||
}
|
||||
if _, err = i.Eval(fmt.Sprintf(`import "%s"`, topImport)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
value, err := i.Eval(`pkg.NewSample()`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fn := value.Interface().(func() string)
|
||||
|
||||
msg = fn()
|
||||
}
|
||||
|
||||
value, err := i.Eval(`pkg.NewSample()`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fn := value.Interface().(func() string)
|
||||
|
||||
msg := fn()
|
||||
|
||||
if msg != test.expected {
|
||||
t.Errorf("Got %q, want %q", msg, test.expected)
|
||||
}
|
||||
|
||||
@@ -26,8 +26,14 @@ func (interp *Interpreter) importSrc(rPath, path string) (string, error) {
|
||||
rPath = "."
|
||||
}
|
||||
dir = filepath.Join(filepath.Dir(interp.Name), rPath, path)
|
||||
} else if dir, rPath, err = pkgDir(interp.context.GOPATH, rPath, path); err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
root, err := interp.rootFromSourceLocation(rPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if dir, rPath, err = pkgDir(interp.context.GOPATH, root, path); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if interp.rdir[path] {
|
||||
@@ -138,6 +144,23 @@ func (interp *Interpreter) importSrc(rPath, path string) (string, error) {
|
||||
return pkgName, nil
|
||||
}
|
||||
|
||||
func (interp *Interpreter) rootFromSourceLocation(rPath string) (string, error) {
|
||||
sourceFile := interp.Name
|
||||
if rPath != "main" || !strings.HasSuffix(sourceFile, ".go") {
|
||||
return rPath, nil
|
||||
}
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
pkgDir := filepath.Join(wd, filepath.Dir(sourceFile))
|
||||
root := strings.TrimPrefix(pkgDir, filepath.Join(interp.context.GOPATH, "src")+"/")
|
||||
if root == wd {
|
||||
return "", fmt.Errorf("package location %s not in GOPATH", pkgDir)
|
||||
}
|
||||
return root, nil
|
||||
}
|
||||
|
||||
// pkgDir returns the absolute path in filesystem for a package given its name and
|
||||
// the root of the subtree dependencies.
|
||||
func pkgDir(goPath string, root, path string) (string, string, error) {
|
||||
|
||||
Reference in New Issue
Block a user