feature: detect import cycle

This commit is contained in:
Marc Vertes
2019-09-17 01:32:03 +02:00
committed by Traefiker Bot
parent 400b625153
commit e03016b6d7
6 changed files with 33 additions and 0 deletions

5
_test/c1/c1.go Normal file
View File

@@ -0,0 +1,5 @@
package c1
import "github.com/containous/yaegi/_test/c2"
var C1 = c2.C2 + "x"

5
_test/c2/c2.go Normal file
View File

@@ -0,0 +1,5 @@
package c2
import "github.com/containous/yaegi/_test/c1"
var C2 = c1.C1 + "Y"

11
_test/import6.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import "github.com/containous/yaegi/_test/c1"
func main() {
println(c1.C1)
}
// Error:
// import cycle not allowed
// imports github.com/containous/yaegi/_test/c1

View File

@@ -79,6 +79,7 @@ type Interpreter struct {
scopes map[string]*scope // package level scopes, indexed by package name
binPkg Exports // binary packages used in interpreter, indexed by path
srcPkg imports // source packages used in interpreter, indexed by path
rdir map[string]bool // for src import cycle detection
}
const (
@@ -137,6 +138,7 @@ func New(options Options) *Interpreter {
scopes: map[string]*scope{},
binPkg: Exports{"": map[string]reflect.Value{"_error": reflect.ValueOf((*_error)(nil))}},
srcPkg: imports{},
rdir: map[string]bool{},
}
i.opt.context.GOPATH = options.GoPath

View File

@@ -35,6 +35,7 @@ func TestInterpConsistencyBuild(t *testing.T) {
file.Name() == "bad0.go" || // expect error
file.Name() == "export1.go" || // non-main package
file.Name() == "export0.go" || // non-main package
file.Name() == "import6.go" || // expect error
file.Name() == "io0.go" || // use random number
file.Name() == "op1.go" || // expect error
file.Name() == "bltn0.go" || // expect error
@@ -144,6 +145,11 @@ func TestInterpErrorConsistency(t *testing.T) {
fileName: "bltn0.go",
expectedInterp: "4:7: use of builtin println not in function call",
},
{
fileName: "import6.go",
expectedInterp: "import cycle not allowed",
expectedExec: "import cycle not allowed",
},
{
fileName: "switch8.go",
expectedInterp: "5:2: fallthrough statement out of place",

View File

@@ -29,6 +29,10 @@ func (interp *Interpreter) importSrc(rPath, path, alias string) error {
} else if dir, rPath, err = pkgDir(interp.context.GOPATH, rPath, path); err != nil {
return err
}
if interp.rdir[path] {
return fmt.Errorf("import cycle not allowed\n\timports %s", path)
}
interp.rdir[path] = true
files, err := ioutil.ReadDir(dir)
if err != nil {