我的应用程序无法在不将更改推送到远程仓库的情况下导入另一个本地包

My app failed to import another local package without pushing changes to remote repo

环境

GO111MODULE=on
golang:1.15.2-alpine

我想做什么

我在本地项目中实现了一些功能,我想在推送之前确认行为 对远程仓库的更改。
但是我的项目无法访问新包。

错误文本

当 docker-compose 运行 'go build' 我得到了他的错误。
'github.com/Asuha-a/URLShortener/api/pb/url' 和 'github.com/Asuha-a/URLShortener/api/utility' 都不存在于远程仓库中,因为它还没有推送。

main.go:10:2: module github.com/Asuha-a/URLShortener/api@latest found (v0.0.0-20201114002535-3dac2ebd322a), but does not contain package github.com/Asuha-a/URLShortener/api/pb/url
main.go:12:2: module github.com/Asuha-a/URLShortener/api@latest found (v0.0.0-20201114002535-3dac2ebd322a), but does not contain package github.com/Asuha-a/URLShortener/api/utility

项目架构

我删除了一些看起来与此问题无关的文件。

$ tree                                                                                               
.                                                                                                    
├── api                                                                                                                                                                               
│   ├── Dockerfile                                                                                   
│   ├── go.mod                                                                                       
│   ├── go.sum
│   ├── main.go
│   ├── pb
│   │   ├── url // new package
│   │       ├── url_grpc.pb.go
│   │       ├── url.pb.go
│   │       └── url.proto
│   ├── services
│   │   ├── url
│   │   │   ├── db
│   │   │   │   ├── settings.go
│   │   │   │   └── url.go
│   │   │   ├── Dockerfile
│   │   │   ├── go.mod
│   │   │   ├── go.sum
│   │   │   └── main.go // failed building
│   └── utility // new package
│       ├── jwt.go
│       └── url.go
├── docker-compose.yml

我试过的

我发现了这个问题。
Importing local changes of a package without pushing code in Go
也就是说我可以通过添加 'replace MODULE_URL => /PATH/TO/MODULE/DIR'.

来访问本地包

我这样编辑 'api/services/url/go.mod'。

module github.com/Asuha-a/URLShortener/api/services/url

go 1.15

replace github.com/Asuha-a/URLShortener/api => ../../.
require (
    github.com/jackc/pgx/v4 v4.9.2 // indirect
    github.com/satori/go.uuid v1.2.0
    golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 // indirect
    golang.org/x/text v0.3.4 // indirect
    golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
    google.golang.org/grpc v1.33.2
    gorm.io/datatypes v1.0.0
    gorm.io/driver/postgres v1.0.5
    gorm.io/gorm v1.20.6
)

但是我得到了这个错误:

main.go:10:2: module github.com/Asuha-a/URLShortener/api@latest found (v0.0.0-20201114002535-3dac2ebd322a, replaced by ../../.), but does not contain package github.com/Asuha-a/URLShortener/api/pb/url
main.go:12:2: module github.com/Asuha-a/URLShortener/api@latest found (v0.0.0-20201114002535-3dac2ebd322a, replaced by ../../.), but does not contain package github.com/Asuha-a/URLShortener/api/utility

然后我尝试了完整路径 '/home/asuha/go/src/github.com/Asuha-a/URLShortener/api'.

但是我得到了这个错误:

main.go:10:2: github.com/Asuha-a/URLShortener/api@v0.0.0-00010101000000-000000000000: replacement directory /home/asuha/go/src/github.com/Asuha-a/URLShortener/api does not exist
main.go:12:2: github.com/Asuha-a/URLShortener/api@v0.0.0-00010101000000-000000000000: replacement directory /home/asuha/go/src/github.com/Asuha-a/URLShortener/api does not exist

我想知道

如何解决这个错误?

先了解一些基础知识:

  • 一个模块是一组一起版本化的包。
  • 模块的名称在 go.mod 中声明,例如github.com/anyone/someproject
  • 一个包是通过它的导入路径导入的(导入路径基本上就是包标识)。
  • 属于模块的包必须有一个以模块名称开头的导入路径。在上面的示例中,属于模块 github.com/anyone/someproject 的任何包都必须具有导入路径,例如github.com/anyone/someproject/whatever/hierarchy/pkgname
  • 您永远不需要 replace 来自同一模块的包。 replace 用于替换 其他 个模块。

您声明了模块

 module github.com/Asuha-a/URLShortener/api/services/url

这使得你的模块名称为“github.com/Asuha-a/URLShortener/api/services/url”并且只有导入路径如模块“github.com/Asuha-a/URLShortener/api/services/url/I/really/ like/deeply/nested/stuff”属于那个包。

显然你 utility 包(顺便说一句。不要 做这样的包,这是基本的代码味道!)不属于你的模块:你可能尝试将其导入为“github.com/Asuha-a/URLShortener/api/utiliyt”,但这不是模块“github.com/Asuha-a/URLShortener/api/services/url”.

的一部分

文件夹 utility 位于文件系统中 go.mod 文件“下方”这一事实并不能否定您的模块在其第一行声明的事实:“我的所有包都已导入以 github.com/Asuha-a/URLShortener/api/services/url 开头的路径!其他任何东西都不属于我!"

您可能应该至少为您的模块命名 module github.com/Asuha-a/URLShortener/api(如果不是 module github.com/Asuha-a/URLShortener)。

我强烈建议您(重新)阅读“如何编写 Go 代码”并坚持

要点: 模块实际上只是一组具有相同导入路径前缀(模块名称)的包。