golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.31k stars 17.58k forks source link

cmd/go: go mod init accepts dotless module paths #36774

Open perillo opened 4 years ago

perillo commented 4 years ago

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

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

Does this issue reproduce with the latest release?

go1.14beta1 is the latest release

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

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN="/home/manlio/.local/bin"
GOCACHE="/home/manlio/.cache/go-build"
GOENV="/home/manlio/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY="github.com/perillo"
GONOSUMDB="github.com/perillo"
GOOS="linux"
GOPATH="/home/manlio/.local/lib/go:/home/manlio/src/go"
GOPRIVATE="github.com/perillo"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/manlio/sdk/go1.14beta1"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/manlio/sdk/go1.14beta1/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/manlio/src/go/src/mperillo/bar/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-build515447885=/tmp/go-build -gno-record-gcc-switches"
GOROOT/bin/go version: go version go1.14beta1 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.14beta1
uname -sr: Linux 5.4.13-arch1-1
/usr/lib/libc.so.6: GNU C Library (GNU libc) stable release version 2.30.
gdb --version: GNU gdb (GDB) 8.3.1

What did you do?

go mod init mperillo/test

What did you expect to see?

go: malformed module path "mperillo/test": missing dot in first path element

What did you see instead?

go: creating new go.mod: module mperillo/test

The problem is that go build will report an error if another module add as requirement mperillo/test.

In this case, is there a reason to allow go mod init to accept such module path?

jayconrod commented 4 years ago

cc @matloob @bcmills

Module paths without a dot in the first path element are allowed, but they cannot be downloaded using that name. That means they cannot appear in a require directive unless there's also a replace directive that provides an alternative location. So module paths like this really only useful for top-level modules not required by anything.

I don't think this documented anywhere. CL 214377 covers this.

perillo commented 4 years ago

I think this will cause the term module path to be no more consistent.

What is the definition of the term module path? Some commands say that is a file path, with the first path segment having a dot. Other commands say that is just a file path.

bcmills commented 4 years ago

A module path is an import-path suffix of the packages contained within a module.

It may or may not contain a dot. We should update the “malformed module path” error message to be clearer about what, exactly, is wrong. (The problem is not that the module path is malformed per se, but rather that paths of that form cannot be fetched to the module cache.)

perillo commented 4 years ago

The problem is that it is not entirely true that a module path without a dot in the first path segment can not be fetched. It depends on the resolver.

Consider an import path like localhost/test. I suspect that the go tool would be able to fetch it, if not for the explicit check for the dot.

bcmills commented 4 years ago

No, it would not. Dotless import paths are in general reserved for the standard library: if they are not in the standard library, and not supplied via a replace directive, then they will not be fetched even if the hostname can be resolved.

(Otherwise the meaning of an import path could become nondeterministic based on the set of hostnames on the network, which seems way too subtle.)

perillo commented 4 years ago

I tried with a module path localhost.localdomain/a.git but go is not able to fetch it:

build localhost.localdomain/b.git: cannot load localhost.localdomain/a.git: git ls-remote -q git://localhost.localdomain/a in /home/manlio/.local/lib/go/pkg/mod/cache/vcs/05929cb418a01ea28941e79c19cd8cf77a461495799d14636e9011e6b0d72a4a: exit status 128:
    fatal: unable to connect to localhost.localdomain:
    localhost.localdomain[0: ::1]: errno=Connection refused
    localhost.localdomain[1: 127.0.0.1]: errno=Connection refused

So I guess the term remote module path, similar to https://golang.org/pkg/cmd/go/#hdr-Remote_import_paths, is more easy to understand.