Skip to content

Commit

Permalink
cue/load: add package import cycle error
Browse files Browse the repository at this point in the history
When two or more packages import each other resulting in a cycle,
cue/load used to cause an infinite loop.
Error instead, since we explicitly don't support import cycles,
per https://cuelang.org/docs/references/spec/#import-declarations:

    It is illegal for a package to import itself, directly or indirectly

Fixes #849

Closes #2469 as merged as of commit ce73397.

Signed-off-by: Artem V. Navrotskiy <[email protected]>
Change-Id: I1928717b3df3c5e6c48eb4fa30966f26079e19c6
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1167597
TryBot-Result: CUEcueckoo <[email protected]>
Unity-Result: CUE porcuepine <[email protected]>
Reviewed-by: Roger Peppe <[email protected]>
  • Loading branch information
bozaro authored and mvdan committed Aug 21, 2023
1 parent 66ebe0f commit 220b44e
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 8 deletions.
21 changes: 13 additions & 8 deletions cue/load/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ import (
// _ anonymous files (which may be marked with _)
// * all packages
func (l *loader) importPkg(pos token.Pos, p *build.Instance) []*build.Instance {
retErr := func(errs errors.Error) []*build.Instance {
// XXX: move this loop to ReportError
for _, err := range errors.Errors(errs) {
p.ReportError(err)
}
return []*build.Instance{p}
}

for _, item := range l.stk {
if item == p.ImportPath {
return retErr(&PackageError{Message: errors.NewMessagef("package import cycle not allowed")})
}
}
l.stk.Push(p.ImportPath)
defer l.stk.Pop()

Expand All @@ -61,14 +74,6 @@ func (l *loader) importPkg(pos token.Pos, p *build.Instance) []*build.Instance {
return []*build.Instance{p}
}

retErr := func(errs errors.Error) []*build.Instance {
// XXX: move this loop to ReportError
for _, err := range errors.Errors(errs) {
p.ReportError(err)
}
return []*build.Instance{p}
}

fp := newFileProcessor(cfg, p, l.tagger)

if p.PkgName == "" {
Expand Down
17 changes: 17 additions & 0 deletions cue/load/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,23 @@ module: mod.test/test
root: $CWD/testdata/testmod
dir: $CWD/testdata/testmod/tagsbad
display:./tagsbad`,
}, {
cfg: &Config{
Dir: testdataDir,
},
args: args("./cycle"),
want: `
err: import failed: import failed: import failed: package import cycle not allowed:
$CWD/testdata/testmod/cycle/cycle.cue:3:8
$CWD/testdata/testmod/cue.mod/pkg/mod.test/cycle/bar/bar.cue:3:8
$CWD/testdata/testmod/cue.mod/pkg/mod.test/cycle/foo/foo.cue:3:8
path: mod.test/test/cycle
module: mod.test/test
root: $CWD/testdata/testmod
dir: $CWD/testdata/testmod/cycle
display:./cycle
files:
$CWD/testdata/testmod/cycle/cycle.cue`,
}}
for i, tc := range testCases {
t.Run(strconv.Itoa(i)+"/"+strings.Join(tc.args, ":"), func(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package bar

import "mod.test/cycle/foo"

#Bar1: foo.#Foo1 + 8
#Bar2: foo.#Foo2 + 16
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package foo

import "mod.test/cycle/bar"

#Foo1: 1
#Foo2: bar.#Bar1 + 2
#Foo: bar.#Bar2 + 4
5 changes: 5 additions & 0 deletions cue/load/testdata/testmod/cycle/cycle.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package cycle

import "mod.test/cycle/foo"

Foo: foo.#Foo

0 comments on commit 220b44e

Please sign in to comment.