go/loader: normalize cycle to remove flake

Fixes golang/go#31279

Change-Id: Idd1eead3b1e9a90ba39d04019ef32200deb4c983
Reviewed-on: https://go-review.googlesource.com/c/tools/+/185984
Run-TryBot: Michael Matloob <matloob@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/go/loader/loader.go b/go/loader/loader.go
index de34b80..bc12ca3 100644
--- a/go/loader/loader.go
+++ b/go/loader/loader.go
@@ -811,7 +811,15 @@
 	// Import of incomplete package: this indicates a cycle.
 	fromPath := from.Pkg.Path()
 	if cycle := imp.findPath(path, fromPath); cycle != nil {
-		cycle = append([]string{fromPath}, cycle...)
+		// Normalize cycle: start from alphabetically largest node.
+		pos, start := -1, ""
+		for i, s := range cycle {
+			if pos < 0 || s > start {
+				pos, start = i, s
+			}
+		}
+		cycle = append(cycle, cycle[:pos]...)[pos:] // rotate cycle to start from largest
+		cycle = append(cycle, cycle[0])             // add start node to end to show cycliness
 		return nil, fmt.Errorf("import cycle: %s", strings.Join(cycle, " -> "))
 	}