-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
What version of Go are you using (go version)?
$ go version go version go1.16.3 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
MacOS, Linux (see reproduction steps below)
What did you do?
The containerd project has a circular dependency on itself through "plugins"
that are built in-tree, but maintained in separate repositories. Circular
dependencies can be a pain, and one can "go in circles" (literally) to deal
with transitional dependencies.
In an attempt to reduce the effects of these circular dependencies (from a
modules / dependency tree perspective), I was considering adding a "replace"
rule to the project's go.mod to make the local version of containerd the
"canonical" version:
replace github.com/containerd/containerd => ./
This appeared to work well, but then I discovered that, as a result of this
replace rule, go.mod became "unstable": repeatedly calling go mod tidy
resulted in the addition and removal of an indirect dependency.
I created a branch on my fork of containerd to reproduce the issue. Reproduction
steps are below.
Reproduction steps
-
Check out the reproduction branch from github
$ mkdir gomod_flip_flop && cd gomod_flip_flop $ git clone --single-branch --branch gomod_flip_flop https://github.com/thaJeztah/containerd.git $ cd containerd
-
Run
go mod tidy, and observe an indirect dependency being added:$ go mod tidy && git diff go: finding module for package github.com/satori/go.uuid go: found github.com/satori/go.uuid in github.com/satori/go.uuid v1.2.0
diff --git a/go.mod b/go.mod index a0d3f7a2c..b63b125d2 100644 --- a/go.mod +++ b/go.mod @@ -45,6 +45,7 @@ require ( github.com/pelletier/go-toml v1.8.1 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.7.1 + github.com/satori/go.uuid v1.2.0 // indirect github.com/sirupsen/logrus v1.7.0 github.com/stretchr/testify v1.6.1 github.com/tchap/go-patricia v2.2.6+incompatible
-
Run
go mod tidyagain, and observe that the indirect is removed:$ go mod tidy && git diff # (no output)
-
Repeat 2. and 3. and see the result repeat itself
Reproducing on other versions
Does not reproduce on:
go version go1.13.15 linux/amd64go version go1.14.15 linux/amd64(but see notes below)go version go1.15.11 linux/amd64(but see notes below)
Reproduces on:
go version go1.16beta1 linux/amd64(and up), including:go version go1.16.3 linux/amd64, andgo version go1.16.3 darwin/amd64
To make sure I started with a clean state for each version, I used docker to
run the reproducer in a container:
for ver in 1.13.15 1.14.15 1.15.11 1.16.3; do \
git reset --quiet --hard HEAD \
&& docker run --rm -v $(pwd):/containerd -w /containerd golang:$ver \
sh -xc 'go version; go env; go mod tidy; git diff; go mod tidy; git diff'; \
donego1.13.15
In a fresh golang:1.13.15 container, the issue does not reproduce:
$ go mod tidy
go: downloading github.com/containerd/ttrpc v1.0.2
# (...)
go: finding github.com/satori/go.uuid v1.2.0
go: downloading github.com/satori/go.uuid v1.2.0
# (...)
go: extracting github.com/satori/go.uuid v1.2.0
# (...)
$ git diff
# (no output)Repeating the above produces no output, and does not result in a diff:
$ go mod tidy
# (no output)
$ git diff
# (no output)go1.14.15, go1.15.11
On go1.14.15, and go1.15.11, go.mod is not modified, but the behavior somewhat
reproduces, as the dependency is re-resolved on each iteration:
In a fresh golang:1.14.15 or golang:1.15.11 container:
$ go mod tidy
go: downloading github.com/gogo/protobuf v1.3.2
# (...)
go: finding module for package github.com/satori/go.uuid
# (...)
go: downloading github.com/satori/go.uuid v1.2.0
# (...)
go: found github.com/satori/go.uuid in github.com/satori/go.uuid v1.2.0
$ git diff
# (no output)Every time after that, the dependency is resolved again, but go.mod is not modified:
$ go mod tidy
go: finding module for package github.com/satori/go.uuid
go: found github.com/satori/go.uuid in github.com/satori/go.uuid v1.2.0
$ git diff
# (no output)What did you expect to see?
The same behavior as Go 1.13: go.mod file to not be updated with each go mod tidy
What did you see instead?
The go.mod file being updated with each iteration.