blob: 43f81a6b96fea39fb86952669fb796f403510f3f [file] [log] [blame]
# This example illustrates a case in which a seemingly-irrelevant requirements
# in one module fixes an incompatibility with a package in another.
#
# Two packages that do not import each other may interact via a third (mutual)
# dependency, so their module requirements must be respected even if those
# requirements do not directly correspond to package imports.
# Before discovering the import of package c, we depend on b v1.0.0.
$ go1.14rc1 list -m b
b v1.0.0 => ./b0
# When we import package c, we must update the selected version of b according
# to c's requirements, _even though_ neither package imports the other.
# Otherwise, the program will panic at run time.
$ go1.14rc1 build c
go: found c in c v1.0.0
$ go1.14rc1 list -m b
b v1.0.1 => ./b1
-- go.mod --
module main
go 1.15
require (
a v1.0.0
b v1.0.0
d v1.0.0
)
replace (
a v1.0.0 => ./a
b v1.0.0 => ./b0
b v1.0.1 => ./b1
c v1.0.0 => ./c
d v1.0.0 => ./d
)
-- main.go --
package main
import (
_ "a"
// Adding an import of c should increase the selected version of b to 1.0.1
// in order to avoid a registration collision caused by a bug in b 1.0.0.
// Module b is not otherwise relevant to package c or its containing module.
_ "c"
)
func main() {}
-- a/go.mod --
module a
go 1.15
require b v1.0.0
-- a/a.go --
package a
import _ "b"
-- b0/go.mod --
module b
go 1.15
require d v1.0.0
-- b0/b.go --
package b
import "d"
func init() { d.Register("c") } // This is a bug that breaks package c.
-- b1/go.mod --
module b
go 1.15
require d v1.0.0
-- b1/b.go --
package b
import "d"
func init() { d.Register("b") } // The bug has been fixed.
-- c/go.mod --
module c
require (
b v1.0.1
d v1.0.0
)
-- c/c.go --
package c
import "d"
func init() { d.Register("c") }
-- c/tidy/tidy.go --
// +build tidy-only
package tidy
// Maintain a false dependency on b v1.0.1, to prevent b v1.0.0
// from erroneously registering itself with our path if anything
// that imports us also imports package b.
import _ "b"
-- d/go.mod --
module d
go 1.15
-- d/d.go --
package d
var registered = map[string]bool{}
func Register(key string) {
if registered[key] {
panic("duplicate registation for " + key)
}
registered[key] = true
}