go: cmd/go: suppress errors for 'go get' of package paths that contain only tests

A Go module path is not necessarily a valid Go package path: for example, golang.org/x/tools is a valid module path, but since there are no .go files in the repo root it is not an importable package.

go get in GOPATH mode returns a non-zero exit code if that happens, but today in module mode we explicitly suppress that error: https://github.com/golang/go/blob/dbd323bb880ff27fa9b4bdfebf3e5d4828b09678/src/cmd/go/internal/modget/get.go#L532-L536

On the other hand, if the user intends to pass a module path (rather than a package path), they can indicate that explicitly using the -m flag.

Should we change the error-suppressing path to instead produce a non-zero exit code? We could still make the error explicit about the fact that the requested path is a module but not a package.

(CC @rsc @hyangah @myitcv @thepudds @jayconrod )

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 3
  • Comments: 15 (11 by maintainers)

Most upvoted comments

Here is another neat example, from a conversation with @lopezator. The root of google.golang.org/genproto contains .go source files tagged with // +build ignore. Since the directory contains a Go source file, go get treats it as a package location; however, it cannot be built because the current configuration excludes that source file.

The message is not cannot find module providing, so go get decides to report an error. (The behavior with go1.11.4 is even worse: it reports no install location for directory, even when GOBIN is set!)

$ go mod init golang.org/issue/scratch
go: creating new go.mod: module golang.org/issue/scratch

$ export GOBIN=$GOPATH/bin

$ go1.12beta2 env | egrep 'GOBIN|GOPATH|GOMOD'
GOBIN="/tmp/tmp.WuuV1dnHy0/_gopath/bin"
GOPATH="/tmp/tmp.WuuV1dnHy0/_gopath"
GOMOD="/tmp/tmp.WuuV1dnHy0/go.mod"

$ go1.12beta2 get google.golang.org/genproto@db91494
go: finding google.golang.org/genproto db91494
package google.golang.org/genproto: build constraints exclude all Go files in /tmp/tmp.WuuV1dnHy0/_gopath/pkg/mod/google.golang.org/genproto@v0.0.0-20190111180523-db91494dd46c

$ go1.11.4 get google.golang.org/genproto@db91494
go: finding google.golang.org/genproto db91494
go get: /tmp/tmp.WuuV1dnHy0/_gopath/pkg/mod/google.golang.org/genproto@v0.0.0-20190111180523-db91494dd46c outside GOPATH
        For more details see: 'go help gopath'

One comment on the current implementation: it seems a repo root that only has a *_test.go file (but no other *.go files) does trigger an error in 1.11.

k8s.io/api is an example repo that only has a test file roundtrip_test.go file in its repo root, which triggers an error if you do go get k8s.io/api@master:

GO111MODULE=on go get k8s.io/api@master
go: finding k8s.io/api master
go: downloading k8s.io/api v0.0.0-20181130031204-d04500c8c3dd
go build k8s.io/api: no non-test Go files in .../go/pkg/mod/k8s.io/api@v0.0.0-20181130031204-d04500c8c3dd

go get k8s.io/apimachinery@master on the other hand works (where that repo root has no *.go files).

CC @bhcleek