Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: Leave pinned version as a comment when dependency is incompatible with go modules #30993

Closed
integrii opened this issue Mar 21, 2019 · 7 comments

Comments

@integrii
Copy link

integrii commented Mar 21, 2019

What version of Go are you using (go version)?

go version go1.12.1 darwin/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
GOARCH="amd64"
GOBIN="/Users/egreer200/go/bin"
GOCACHE="/Users/egreer200/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/egreer200/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.12.1/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.12.1/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/egreer200/git/kuberhealthy/pkg/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/7h/qd9xrbq10lb03g4lkqcl_cdr0000gp/T/go-build290178356=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I pinned a dependency (k8s.io/apimachinery kubernetes-1.11.7) in go.mod and ran go build.

What did you expect to see?

I expected my pinned version to be in the go.mod file.

What did you see instead?

The go.mod file left behind a unique hash that no longer shows what I asked it to pin (k8s.io/apimachinery v0.0.0-20190118094746-1525e4dadd2d). Go should at least leave a note indicating what human-readable version is pinned with the module hash format. This leads developers (at first use) to think that the program overrode their version pinning request.

I understand this is expected behavior and that the hash indicates a static version to pull in, but I would like to see some hints left behind so people know what tag it really is. For example:

What the dev inputs:

require k8s.io/apimachinery kubernetes-1.11.7

What the dev sees after' running go get:

require (
    k8s.io/apimachinery v0.0.0-20190118094746-1525e4dadd2d
)

What I would like to see (as a dev):

require (
    k8s.io/apimachinery v0.0.0-20190118094746-1525e4dadd2d // kubernetes-1.11.7
)
@integrii integrii changed the title cmd/go: Leave pinned version as a comment when incompatible with go modules cmd/go: Leave pinned version as a comment when dependency is incompatible with go modules Mar 21, 2019
@agnivade
Copy link
Contributor

@bcmills @jayconrod

@jayconrod
Copy link
Contributor

Seems reasonable. go get could also write these comments if a particular branch is requested.

Not sure if this will happen for 1.13, given how much other stuff needs to go in, but it would be nice to have.

@bcmills
Copy link
Contributor

bcmills commented Mar 27, 2019

go.mod does not “pin” dependencies: it specifies minimums.

That said, I think this is a duplicate of #25898. Please reopen if you disagree.

@bcmills bcmills closed this as completed Mar 27, 2019
@integrii
Copy link
Author

Thanks for the reply. I think that issue is different, but would accomplish the same thing.

But, if you see this thread again, can you briefly explain what you mean by go.mod not pinning dependencies?

I see a line in go.mod like this: k8s.io/apimachinery v0.0.0-20190118094746-1525e4dadd2d and commands like go get foo@e3702bed2 seem to specify an exact revision.

@bcmills
Copy link
Contributor

bcmills commented Apr 1, 2019

go.mod doesn't pin dependencies, in that the versions specified in your go.mod file are treated as minimum versions — not exact constraints — if and when your module is used as a dependency of some other module.

(If your module is always the main module when you build it, then the “minimum version” is functionally equivalent to “pinning”, but we try not to make that assumption in discussions and documentation.)

@integrii
Copy link
Author

integrii commented Apr 4, 2019

Whoa. Does this mean that an upstream dependency can release a new version that will cause my builds to fail? Does go automatically try older versions to see if one works in that case? How would one "pin" an exact upstream version if needed? Is vendoring the only option?

Thanks for the reply!

@bcmills
Copy link
Contributor

bcmills commented Apr 13, 2019

Does this mean that an upstream dependency can release a new version that will cause my builds to fail?

Nope: the version selected for a given go.mod file is stable over time — it's just not “pinned”, in the sense that if someone else uses your module as a dependency, your module's requirements will set a minimum (but not a maximum) on the versions of modules that they can require in conjunction.

(See https://research.swtch.com/vgo-mvs for details.)

Does go automatically try older versions to see if one works in that case?

The maximum of the minimum-versions explicitly listed in the module graph is always selected. The only time we try a different version is if we see an import statement that names a package that does not exist in the currently-active module versions.

How would one "pin" an exact upstream version if needed?

Generally you don't need to. You set your versions, and because the go command selects the minimum version that satisfies both your explicit requirements and those of your (transitive) dependencies, that selection remains stable over time.

@golang golang locked and limited conversation to collaborators Apr 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants