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: document why go mod tidy adds entries beyond those added by go build #27633

Open
opennota opened this Issue Sep 12, 2018 · 2 comments

Comments

Projects
None yet
4 participants
@opennota

opennota commented Sep 12, 2018

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

go1.11 linux/amd64

Does this issue reproduce with the latest release?

Yes.

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

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/opennota/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/opennota/gocode"
GOPROXY=""
GORACE=""
GOROOT="/home/opennota/go"
GOTMPDIR=""
GOTOOLDIR="/home/opennota/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/opennota/a/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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build705714475=/tmp/go-build -gno-record-gcc-switches"

What did you do?

$ mkdir a && cd a

$ cat <<EOF > x.go
package main
import _ "github.com/boltdb/bolt"
func main() {}
EOF

$ cat <<EOF > go.mod
module example.com/x/y
EOF

$ GO111MODULE=on go build
go: finding github.com/boltdb/bolt v1.3.1
go: downloading github.com/boltdb/bolt v1.3.1

$ cat go.mod
module example.com/x/y

require github.com/boltdb/bolt v1.3.1

$ GO111MODULE=on go mod tidy
go: finding golang.org/x/sys/unix latest
go: finding golang.org/x/sys latest
go: downloading golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e

$ cat go.mod
module example.com/x/y

require (
        github.com/boltdb/bolt v1.3.1
        golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e // indirect
)

What did you expect to see?

go mod tidy doesn't add any new entries to go.mod.

What did you see instead?

An indirect dependency was added: golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e // indirect

@myitcv

This comment has been minimized.

Member

myitcv commented Sep 12, 2018

You can use go mod why -m golang.org/x/sys to answer the question on why this (indirect) dependency is present:

export GOPATH=$(mktemp -d)
cd $(mktemp -d)
mkdir hello
cd hello
go mod init example.com/hello
cat <<EOF > x.go
package main
import _ "github.com/boltdb/bolt"
func main() {}
EOF
go mod tidy
go mod why -m golang.org/x/sys

gives:

# golang.org/x/sys
example.com/hello
github.com/boltdb/bolt
golang.org/x/sys/unix

The reason is that go mod tidy is agnostic of GOOS/GOARCH or build tags; go build is lazy and only does the minimal amount of work required for the current GOOS/GOARCH and build tags.

cc @bcmills - I wonder whether we should update the documentation for go mod tidy to include some note about this operation being agnostic of GOOS/GOARCH and build tags:

usage: go mod tidy [-v]

Tidy makes sure go.mod matches the source code in the module.
It adds any missing modules necessary to build the current module's
packages and dependencies, and it removes unused modules that
don't provide any relevant packages. It also adds any missing entries
to go.sum and removes any unnecessary ones.

The -v flag causes tidy to print information about removed modules
to standard error.

Because one reading of the documentation is that go build and go mod tidy should leave go.mod in the same state.

@thepudds

This comment has been minimized.

thepudds commented Sep 12, 2018

@myitcv @bcmills related to the documentation comment from @myitcv above, there is also this slightly older issue:

#26571 "cmd/go: clarify doc that go commands like 'go build' are not always sufficient to update go.mod and 'go mod -sync' is sometimes required to handle variability due to GOOS/GOARCH/build tags"

...which tries to highlight a few different places where the documentation seems to leave the impression with at least some readers that commands like go build are sufficient, e.g., this quote from the tip documentation:

Once the go.mod file exists, no additional steps are required: go commands like 'go build', 'go test', or even 'go list' will automatically add new dependencies as needed to satisfy imports.

That issue #26571 also cites the help for go mod -sync (which was how go mod tidy was spelled at the time) as missing any statement about GOOS/GOARCH.

And it is not that the doc is entirely missing the information, e.g., the "Maintaining module requirements" section says:

Any go command can determine that a module requirement is missing and must be added, even when considering only a single package from the module. On the other hand, determining that a module requirement is no longer necessary and can be deleted requires a full view of all packages in the module, across all possible build configurations (architectures, operating systems, build tags, and so on). The 'go mod tidy' command builds that view and then adds any missing module requirements and removes unnecessary ones.

But there are other pieces of the doc in other sections that seem to imply go build is just as comprehensive as go tidy at adding requirements (or at least it seems it can be read that way by some).

In short, I agree with @myitcv there is opportunity to clarify the documentation a bit on this topic.

@bcmills bcmills added this to the Go1.12 milestone Sep 12, 2018

@bcmills bcmills changed the title from cmd/go: go mod tidy adds an entry not added by go build to cmd/go: document why go mod tidy adds entries beyond those added by go build Sep 12, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment