Skip to content

cmd/go: building requires otherwise-unused .mod files to be present  #29410

@stapelberg

Description

@stapelberg

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

$ go version
go version go1.12beta1 linux/amd64

Does this issue reproduce with the latest release?

Yes.

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

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/michael/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/tmp/gp-repro"
GOPROXY=""
GORACE=""
GOROOT="/home/michael/sdk/go1.12beta1"
GOTMPDIR=""
GOTOOLDIR="/home/michael/sdk/go1.12beta1/pkg/tool/linux_amd64"
GCCGO="/usr/bin/gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/tmp/repro/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-build500484946=/tmp/go-build -gno-record-gcc-switches"

What did you do?

% export GOPATH=/tmp/gp-repro
% mkdir /tmp/repro
% cat > repro.go <<'EOT'
package main

import (
	"fmt"

	"golang.org/x/exp/mmap"
	"gonum.org/v1/gonum/unit"
)

func main() {
	fmt.Printf("%v, %v", mmap.ReaderAt{}, unit.Meter)
}
EOT
% go mod init repro
% go build
go: finding gonum.org/v1/gonum v0.0.0-20181223131727-b545e3e77e9e
go: finding golang.org/x/exp v0.0.0-20181221233300-b68661188fbf
go: finding golang.org/x/exp v0.0.0-20180321215751-8460e604b9de
go: finding golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b
go: downloading gonum.org/v1/gonum v0.0.0-20181223131727-b545e3e77e9e
go: downloading golang.org/x/exp v0.0.0-20181221233300-b68661188fbf
go: extracting golang.org/x/exp v0.0.0-20181221233300-b68661188fbf
go: extracting gonum.org/v1/gonum v0.0.0-20181223131727-b545e3e77e9e

As you can see, two versions of golang.org/x/exp are involved here: the repro module uses the latest (v0.0.0-20181221233300-b68661188fbf), whereas the gonum.org/v1/gonum module specifies an older version (v0.0.0-20180321215751-8460e604b9de).

In the build itself, the latest version is picked:

% go list -m -json all
{
	"Path": "repro",
	"Main": true,
	"Dir": "/tmp/repro",
	"GoMod": "/tmp/repro/go.mod",
	"GoVersion": "1.12"
}
{
	"Path": "golang.org/x/exp",
	"Version": "v0.0.0-20181221233300-b68661188fbf",
	"Time": "2018-12-21T23:33:00Z",
	"Dir": "/tmp/gp-repro/pkg/mod/golang.org/x/[email protected]",
	"GoMod": "/tmp/gp-repro/pkg/mod/cache/download/golang.org/x/exp/@v/v0.0.0-20181221233300-b68661188fbf.mod"
}
{
	"Path": "golang.org/x/tools",
	"Version": "v0.0.0-20180525024113-a5b4c53f6e8b",
	"Time": "2018-05-25T02:41:13Z",
	"Indirect": true,
	"GoMod": "/tmp/gp-repro/pkg/mod/cache/download/golang.org/x/tools/@v/v0.0.0-20180525024113-a5b4c53f6e8b.mod"
}
{
	"Path": "gonum.org/v1/gonum",
	"Version": "v0.0.0-20181223131727-b545e3e77e9e",
	"Time": "2018-12-23T13:17:27Z",
	"Dir": "/tmp/gp-repro/pkg/mod/gonum.org/v1/[email protected]",
	"GoMod": "/tmp/gp-repro/pkg/mod/cache/download/gonum.org/v1/gonum/@v/v0.0.0-20181223131727-b545e3e77e9e.mod"
}

However, when preventing internet access by pointing GOPROXY to an unused port, I can see that the old version of golang.org/x/exp needs to be present for the build to succeed:

% rm repro && GOPROXY=http://localhost:1111/ go build
# works
% rm /tmp/gp-repro/pkg/mod/cache/download/golang.org/x/exp/@v/v0.0.0-20180321215751-8460e604b9de.*
% rm repro && GOPROXY=http://localhost:1111/ go build
go: finding golang.org/x/exp v0.0.0-20180321215751-8460e604b9de
go: golang.org/x/[email protected]: Get http://localhost:1111/golang.org/x/exp/@v/v0.0.0-20180321215751-8460e604b9de.info: dial tcp [::1]:1111: connect: connection refused
go: error loading module requirements
% echo 'module golang.org/x/exp' > /tmp/gp-repro/pkg/mod/cache/download/golang.org/x/exp/@v/v0.0.0-20180321215751-8460e604b9de.mod
% GOPROXY=http://localhost:1111/ go build                                                                                         
# works

This came as a surprise to me, so I wanted to check in and see if this was intentional or an oversight. Given that the .mod file only contains “module golang.org/x/exp”, it seems to me that the file could easily be synthesized?

I discovered this issue because I was experimenting with packaging Go modules in Linux distributions (e.g. Debian). It would be a significant downside if we needed to provide (and therefore maintain!) all versions that a build ever references, instead of just the versions which are selected in the end.

Thanks,

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.modules

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions