Skip to content

Commit c974b8b

Browse files
committed
cmd/go: diagnose import cycles better
Before this CL, the import stack was a) not printed and b) overwritten later in the build, destroying the information about the cycle. This CL fixes both. I made time depend on os (os already depends on time) and with this CL the error is: /Users/r/go/src/pkg/fmt/print.go:10:2: import cycle not allowed package code.google.com/p/XXX/YYY: imports fmt imports os imports time imports os Doesn't give line numbers for the actual imports, as requested in the bug, but I don't believe that's important. Fixes #4292. R=golang-dev, adg CC=golang-dev https://golang.org/cl/13100043
1 parent a790388 commit c974b8b

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

src/cmd/go/pkg.go

+14-6
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,17 @@ func (p *Package) copyBuild(pp *build.Package) {
129129

130130
// A PackageError describes an error loading information about a package.
131131
type PackageError struct {
132-
ImportStack []string // shortest path from package named on command line to this one
133-
Pos string // position of error
134-
Err string // the error itself
132+
ImportStack []string // shortest path from package named on command line to this one
133+
Pos string // position of error
134+
Err string // the error itself
135+
isImportCycle bool // the error is an import cycle
135136
}
136137

137138
func (p *PackageError) Error() string {
139+
// Import cycles deserve special treatment.
140+
if p.isImportCycle {
141+
return fmt.Sprintf("%s: %s\npackage %s\n", p.Pos, p.Err, strings.Join(p.ImportStack, "\n\timports "))
142+
}
138143
if p.Pos != "" {
139144
// Omit import stack. The full path to the file where the error
140145
// is the most important thing.
@@ -271,13 +276,16 @@ func reusePackage(p *Package, stk *importStack) *Package {
271276
if p.imports == nil {
272277
if p.Error == nil {
273278
p.Error = &PackageError{
274-
ImportStack: stk.copy(),
275-
Err: "import cycle not allowed",
279+
ImportStack: stk.copy(),
280+
Err: "import cycle not allowed",
281+
isImportCycle: true,
276282
}
277283
}
278284
p.Incomplete = true
279285
}
280-
if p.Error != nil && stk.shorterThan(p.Error.ImportStack) {
286+
// Don't rewrite the import stack in the error if we have an import cycle.
287+
// If we do, we'll lose the path that describes the cycle.
288+
if p.Error != nil && !p.Error.isImportCycle && stk.shorterThan(p.Error.ImportStack) {
281289
p.Error.ImportStack = stk.copy()
282290
}
283291
return p

0 commit comments

Comments
 (0)