Skip to content

Commit cf6739c

Browse files
author
Bryan C. Mills
committed
cmd/go: add a regression test for package import cycles guarded by build tags
I've been thinking about the relationship between the package import graph and the module import graph, and realized that the package import graph is not always acyclic. (The package import graph must be acyclic given a specific set of build tags, but the 'mod' subcommands intentionally ignore build tags.) I'm not sure whether we have any existing regression tests that cover this sort of cycle, so I'm adding one now. Thankfully, it passes! Updates #36460 Change-Id: I7679320994ee169855241efa51cd45f71315f7f5 Reviewed-on: https://go-review.googlesource.com/c/go/+/217557 Run-TryBot: Bryan C. Mills <[email protected]> Reviewed-by: Jay Conrod <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 8c09e8a commit cf6739c

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Because 'go mod' subcommands ignore build constraints, they can encounter
2+
# package-import cycles that are not possible in an ordinary build. This test
3+
# verifies that such cycles are handled even when they cross module boundaries.
4+
5+
# First, verify that the import graph depends on build tags as expected.
6+
go list -deps example.com/left
7+
stdout '^example.com/right$'
8+
go list -deps example.com/right
9+
! stdout left
10+
11+
env GOFLAGS=-tags=mirror
12+
go list -deps example.com/left
13+
! stdout right
14+
go list -deps example.com/right
15+
stdout '^example.com/left$'
16+
env GOFLAGS=''
17+
18+
# 'go mod why' should be agnostic to build tags.
19+
go mod why example.com/left
20+
stdout '^example.com/chiral$\n^example.com/left$'
21+
go mod why example.com/right
22+
stdout '^example.com/chiral$\n^example.com/right$'
23+
24+
env GOFLAGS='-tags=mirror'
25+
go mod why example.com/left
26+
stdout '^example.com/chiral$\n^example.com/left$'
27+
go mod why example.com/right
28+
stdout '^example.com/chiral$\n^example.com/right$'
29+
env GOFLAGS=''
30+
31+
# 'go mod tidy' should successfully handle the cycle.
32+
env GOFLAGS=-mod=readonly
33+
go mod tidy
34+
35+
# 'go mod vendor' should copy in both packages without crashing.
36+
go mod vendor
37+
exists vendor/example.com/left/default.go
38+
exists vendor/example.com/left/mirror.go
39+
exists vendor/example.com/right/default.go
40+
exists vendor/example.com/right/mirror.go
41+
42+
-- go.mod --
43+
module example.com/chiral
44+
45+
go 1.14
46+
47+
require (
48+
example.com/left v0.1.0
49+
example.com/right v0.1.0
50+
)
51+
52+
replace (
53+
example.com/left => ./left
54+
example.com/right => ./right
55+
)
56+
-- chiral.go --
57+
// Package chiral imports packages in an order that depends on build tags.
58+
package chiral
59+
-- default.go --
60+
// +build !mirror
61+
62+
package chiral
63+
64+
import _ "example.com/left"
65+
-- mirror.go --
66+
// +build mirror
67+
68+
package chiral
69+
70+
import _ "example.com/right"
71+
-- left/go.mod --
72+
module example.com/left
73+
74+
go 1.14
75+
76+
require example.com/right v0.1.0
77+
78+
replace example.com/right v0.1.0 => ../right
79+
-- left/default.go --
80+
// +build !mirror
81+
82+
package left
83+
84+
import _ "example.com/right"
85+
-- left/mirror.go --
86+
// +build mirror
87+
88+
package left
89+
-- right/go.mod --
90+
module example.com/right
91+
92+
go 1.14
93+
94+
require example.com/left v0.1.0
95+
96+
replace example.com/left v0.1.0 => ../left
97+
-- right/default.go --
98+
// +build !mirror
99+
100+
package right
101+
-- right/mirror.go --
102+
// +build mirror
103+
104+
package right
105+
106+
import _ "example.com/left"

0 commit comments

Comments
 (0)