Skip to content

go mod attempts to download packages when it detects a VCS, even if a replace directive would override the package #28258

@jeffjsc

Description

@jeffjsc

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

go version go1.11.1 darwin/amd64

Does this issue reproduce with the latest release?

Yes

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

GOARCH="amd64"
GOBIN="/Users/jeffrey.johnson2/xxx/Dev/go/bin/"
GOCACHE="/Users/jeffrey.johnson2/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/jeffrey.johnson2/xxx/Dev/go/"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.11.1/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.11.1/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/jeffrey.johnson2/xxx/Dev/go/src/vgotest.com/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/g_/zq5mxm_j0b77gqntfvptq3m80000gp/T/go-build324185808=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I tried creating a local override for a non-existent remote git repository, using go mod's replace directive. Go mod attempts to fetch the remote before the replace is applied, which does not work because the remote does not exist. Go mod decides that the package is a git repository because the package name matches the regex here:

re: `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?(/~?[A-Za-z0-9_.\-]+)+?)\.(?P<vcs>bzr|fossil|git|hg|svn))(/~?[A-Za-z0-9_.\-]+)*$`,

Here's a script to set up test input.

cd $GOPATH/src
mkdir modtest.com
cd modtest.com

# create program main
mkdir program
echo -e "package main\n\nimport \"example.com/baz.git/mypackage\"\n\nfunc main() {\n\tmypackage.Do()\n}" > program/main.go

# create library package in vendor directory
mkdir -p vendor/example.com/baz.git/mypackage/
echo -e "package mypackage\n\nimport \"fmt\"\n\nfunc Do() {\n\tfmt.Println(\"hello\")\n}" > vendor/example.com/baz.git/mypackage/code.go
echo "module example.com/baz.git" > vendor/example.com/baz.git/go.mod

# create mod file with replace
echo -e "module vgotest.com\nrequire example.com/baz.git v0.0.0\nreplace example.com/baz.git => ./vendor/example.com/baz.git" > go.mod

Now run:
vgo run program/main.go

The same issue is exercised by:
go mod install

What did you expect to see?

I expected no download attempt and to see this printed to the console:
hello

What did you see instead?

Go hangs as it attempts to fetch the non-existent remote example.com/baz.git repository using ssh.

Note that if you omit .git from the library path, this works. For example:

cd $GOPATH/src
mkdir modtest-works.com
cd modtest-works.com

# create program main
mkdir program
echo -e "package main\n\nimport \"example.com/baz/mypackage\"\n\nfunc main() {\n\tmypackage.Do()\n}" > program/main.go

# create library package in vendor directory
mkdir -p vendor/example.com/baz/mypackage/
echo -e "package mypackage\n\nimport \"fmt\"\n\nfunc Do() {\n\tfmt.Println(\"hello\")\n}" > vendor/example.com/baz/mypackage/code.go
echo "module example.com/baz" > vendor/example.com/baz/go.mod

# create mod file with replace
echo -e "module vgotest.com\nrequire example.com/baz v0.0.0\nreplace example.com/baz => ./vendor/example.com/baz" > go.mod

vgo run program/main.go

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