当缺失的包可能在主模块中时,"package not found"错误比GOPATH的错误更少有用,

fjaof16o  于 6个月前  发布在  Go
关注(0)|答案(5)|浏览(53)

给定以下设置:

-- gopath/src/example.com/go.mod --
module example.com

go 1.14
-- gopath/src/example.com/main.go --
package main

import (
        "fmt"

        "example.com/mypkg"
)

func main() {
        fmt.Println(mypkg.Message)
}
-- gopath/src/example.com/mypackage/doc.go --
package mypackage

const Message = "sup"

然后运行:

$ export GOPATH=$PWD/gopath
$ cd gopath/src/example.com
$ GO111MODULE=off go run main.go
main.go:6:2: cannot find package "example.com/mypkg" in any of:
	.../go/src/example.com/mypkg (from $GOROOT)
	../gopath/src/example.com/mypkg (from $GOPATH)

这是明确且可操作的:有两个目录可能包含该软件包,但都没有。你可以列出这两个目录,将路径与文件系统进行比较等。
在模块模式下:

$ GO111MODULE=on gotip run main.go
go: finding module for package example.com/mypkg
main.go:6:2: cannot find module providing package example.com/mypkg: unrecognized import path "example.com/mypkg": reading https://example.com/mypkg?go-get=1: 404 Not Found

这就不太可操作了。为什么它要去互联网上寻找一个本应存在于本地文件系统的软件包?它是否先查找过其他地方?如果example.com是一个GitHub URL,错误会有所不同,但在这里讨论私有仓库并没有太大帮助。
显然,问题是个拼写错误:软件包名为mypackage,而不是mypkg。我认为GOPATH错误给了新用户一个发现错误的机会;而模块错误至少需要对包到模块解析以及嵌套模块(!)有一个基本的理解才能讲得通。
具体来说,我希望看到模块模式的错误更像GOPATH错误:

main.go:6:2: cannot find package "example.com/mypkg" in any of:
   	.../go/src/example.com/mypkg (standard library)
	../gopath/src/example.com/mypkg (module example.com)
       https://example.com/mypkg (module example.com/mypkg): unrecognized import path "example.com/mypkg": reading https://example.com/mypkg?go-get=1: 404 Not Found

@bcmills@jayconrod

luaexgnf

luaexgnf1#

main.go:6:2: cannot find package "example.com/mypkg" in any of:
.../go/src/example.com/mypkg (standard library)

这行代码可能会误导人:我们甚至不会检查那个目录,因为缺失的导入路径的第一个组件包含一个点。

../gopath/src/example.com/mypkg (module example.com)

我们或许可以修复这个问题(与#33568(评论)进行比较)。
如果一开始我们没有任何候选模块可供检查,我们会生成一条错误信息,如下所示:

package example.com/mypkg is not in the main module (example.com)

(这条信息来自这里。)
请注意,如果 example.com 是除了主模块之外的某个现有模块,我们可能会生成类似以下的信息:

module example.com@latest found (v1.2.3), but does not contain package example.com/mypkg

因此,我们可能需要以某种形式在这里提及主模块。但是我们需要小心地描述文件路径,因为完全有可能 ../gopath/src/example.com/mypkg 确实存在,但它位于一个具有自己 go.mod 文件的未发布的嵌套模块中(而不是主模块)。

ui7jx7zq

ui7jx7zq2#

当然,我并不是想指定任何特定的细节。我是在主张一种错误报告的哲学:对于每个查找到的位置,应该有一种未找到错误的各种形式,如果最终解析失败,那么产生的信息应该详细说明搜索过的位置以及为什么没有成功。所以对于你评论末尾的情况,我希望得到类似 ../gopath/src/example.com/mypkg (module example.com): is hidden by nested module example.com/mypkg 的结果。当然,我在这里假设了代码的结构。

w41d8nur

w41d8nur3#

此外,我也希望替换目标能看到同样的内容,而不仅仅是主模块。

5kgi1eie

5kgi1eie4#

https://golang.org/cl/185345提到了这个问题:cmd/go: rationalize errors in internal/load and internal/modload

goqiplq2

goqiplq25#

消息似乎现在符合预期:

>gotip version
go version devel go1.17-aa4e0f528e Fri Jul 16 02:43:48 2021 +0000 windows/amd64

>gotip run main.go
main.go:6:9: no required module provides package example.com/mypkg; to add it:
        go get example.com/mypkg

相关问题