[英]Module XXX found, but does not contain package XXX
Not so familiar with Golang, it's probably a stupid mistake I made... But still, I can't for the life of me figure it out.对Golang不太熟悉,这可能是我犯的一个愚蠢的错误......但是,我仍然无法弄清楚。
So, I got a proto3 file (let's call it file.proto
), whose header is as follows:所以,我得到了一个 proto3 文件(我们称之为
file.proto
),其 header 如下:
syntax = "proto3";
package [package_name];
option go_package = "github.com/[user]/[repository]";
And I use protoc
:我使用
protoc
:
protoc --go_out=$GOPATH/src --go-grpc_out=$GOPATH/src file.proto
So far so good, I end up with two generated files ( file.pb.go
and file_grpc.pb.go
) inside /go/src/github.com/[user]/[repository]/
, and they are defined inside the package [package_name]
.到目前为止一切顺利,我最终在
/go/src/github.com/[user]/[repository]/
中生成了两个生成文件( file.pb.go
和file_grpc.pb.go
),它们在package [package_name]
。
Then, the code I'm trying to build has the following import:然后,我正在尝试构建的代码具有以下导入:
import (
"github.com/[user]/[repository]/[package_name]"
)
And I naively thought it would work.我天真地认为它会起作用。 However, it produces the following error when running
go mod tidy
:但是,在运行
go mod tidy
时会产生以下错误:
go: downloading github.com/[user]/[repository] v0.0.0-20211105185458-d7aab96b7629
go: finding module for package github.com/[user]/[repository]/[package_name]
example/xxx imports
github.com/[user]/[repository]/[package_name]: module github.com/[user]/[repository]@latest found (v0.0.0-20211105185458-d7aab96b7629), but does not contain package github.com/[user]/[repository]/[package_name]
Any idea what I'm doing wrong here?知道我在这里做错了什么吗? Go version is
go1.19 linux/amd64
within Docker ( golang:1.19-alpine
). Go 版本是
go1.19 linux/amd64
内 Docker ( golang:1.19-alpine
)。
Note: I also tried to only import github.com/[user]/[repository]
, same issue obviously.注意:我也尝试只导入
github.com/[user]/[repository]
,显然同样的问题。
UPDATE :更新:
OK so what I do is that I get the proto file from the git repository that only contains the proto file:好的,我要做的是从仅包含 proto 文件的 git 存储库中获取 proto 文件:
wget https://raw.githubusercontent.com/[user]/[repository]/file.proto
Then I generate go files from that file with protoc
:然后我使用 protoc 从该文件生成
protoc
文件:
RUN protoc --go_out=. --go-grpc_out=. file.proto
Right now, in current directory, it looks like:现在,在当前目录中,它看起来像:
- directory
| - process.go
| - file.proto
| - github.com
| - [user]
| - [repository]
| - file.pb.go
| - file_grpc.pb.go
In that same directory, I run:在同一个目录中,我运行:
go mod init xxx
go mod tidy
CGO_ENABLED=0 go build process.go
The import directive in process.go
is as follows: process.go
中的导入指令如下:
import (
"xxx/github.com/[user]/[repository]"
)
Now it looks like it finds it , but still getting a gRPC error, which is weird because nothing changed.现在看起来它找到了它
,但仍然收到 gRPC 错误,这很奇怪,因为没有任何改变。 I still have to figure out if it comes from the issue above or not .我仍然必须弄清楚它是否来自上述问题。 Thanks!谢谢!
Your question is really a number of questions in one;您的问题实际上是多个问题合而为一; I'll try to provide some info that will help.
我会尽力提供一些有用的信息。 The initial issue you had was because
你最初遇到的问题是因为
At least one file with the.go extension must be present in a directory for it to be considered a package.
目录中必须至少存在一个扩展名为 .go 的文件,才能将其视为 package。
This makes sense because importing github.com/[user]/[repository]
would be fairly pointless if that repository does not contain any .go
files (ie the go compiler could not really do anything with the files).这是有道理的,因为如果该存储库不包含任何
.go
文件(即 Z34D1F91FB2E514B8576FAB1A75A 文件),编译器实际上无法对文件执行任何操作,那么导入github.com/[user]/[repository]
将毫无意义。
Your options are:您的选择是:
protoc
directly into your project folder and change the package
declarations to match your package.protoc
直接复制到您的项目文件夹中,并更改package
声明以匹配您的 package。 If you do this there is no need for any imports.go_out
argument to protoc
) the output from protoc
into a subfolder of your project.protoc
复制(或将go_out
参数设置为protoc
)到项目的子文件夹中。 The import path will then be the value of the module
declaration in your go.mod
plus the path from the folder that the go.mod
is in (this is what you have done).go.mod
中的module
声明的值加上go.mod
所在文件夹的路径(这就是您所做的)。.proto
files if you "want it to be agnostic" (note that 2 & 3 can be combined if the generated files will only be used within one code base or the repo is accessible to all users)..proto
文件相同的存储库(请注意,如果生成的文件将仅在一个代码库中使用或存储库可访问,则可以组合 2 和 3所有用户)。 Option 1 is simple but its often beneficial to keep the generated code separate (makes it clear what you should not edit and improves editor autocomplete etc).选项 1 很简单,但通常有利于将生成的代码分开(明确不应该编辑的内容并改进编辑器自动完成等)。
Option 2 is OK (especially if protoc
writes the files directly and you set go_package
appropriately).选项 2 是可以的(特别是如果
protoc
直接写入文件并且您设置go_package
适当)。 However issues may arise when the generated files will be used in multiple modules (eg as part of your customers code) and your repo is private.但是,当生成的文件将用于多个模块(例如,作为客户代码的一部分)并且您的存储库是私有的时,可能会出现问题。 They will need to change
go_package
before running protoc
(or search/replace the package
declarations) and importing other .proto
files may not work well.他们需要在运行
protoc
之前更改go_package
(或搜索/替换package
声明)并且导入其他.proto
文件可能无法正常工作。
Option 3 is probably the best approach in most situations because this works with the go tooling.在大多数情况下,选项 3 可能是最好的方法,因为它适用于 go 工具。 You can create
github.com/[user]/goproto
(or similar) and put all of your generated code in there.您可以创建
github.com/[user]/goproto
(或类似的)并将所有生成的代码放在那里。 To use this your customers just need to import github.com/[user]/goproto
(no need to run protoc
etc).要使用它,您的客户只需
import github.com/[user]/goproto
[user]/goproto(无需运行protoc
等)。
Go Modules/package intro Go 模块/封装介绍
The go spec does not detail the format of import paths, leaving it up to the implementation: go 规范没有详细说明导入路径的格式,由实现决定:
The interpretation of the ImportPath is implementation-dependent but it is typically a substring of the full file name of the compiled package and may be relative to a repository of installed packages.
ImportPath 的解释取决于实现,但它通常是已编译 package 的完整文件名的 substring,并且可能与已安装软件包的存储库相关。
As you are using go modules (pretty much the default now) the implementations rules for resolving package paths (synonym of import path) can be summarised as :当您使用go 模块(现在几乎是默认值)时,解析 package 路径(导入路径的同义词)的实现规则可以总结为:
Each package within a module is a collection of source files in the same directory that are compiled together.
模块中的每个 package 都是同一目录中编译在一起的源文件的集合。 A package path is the module path joined with the subdirectory containing the package (relative to the module root).
package 路径是与包含 package(相对于模块根目录)的子目录连接的模块路径。 For example, the module "golang.org/x/net" contains a package in the directory "html".
例如,模块“golang.org/x/net”在“html”目录中包含一个 package。 That package's path is "golang.org/x/net/html".
该包的路径是“golang.org/x/net/html”。
So if your "module path" (generally the top line in a go.mod
) is set to xxx
( go mod init xxx
) then you would import the package in subfolder github.com/[user]/[repository]
with import xxx/github.com/[user]/[repository]
(as you have found). So if your "module path" (generally the top line in a
go.mod
) is set to xxx
( go mod init xxx
) then you would import the package in subfolder github.com/[user]/[repository]
with import xxx/github.com/[user]/[repository]
/[repository](如您所见)。 If you got rid of the intervening folders and put the files into the [repository]
subfolder (directly off your main folder) then it would be import xxx/[repository]
如果您摆脱了中间文件夹并将文件放入
[repository]
子文件夹(直接从您的主文件夹中),那么它将是import xxx/[repository]
You will note in the examples above that the module
names I used are paths to repo (as opposed to the xxx
you used in go mod init xxx
).您将在上面的示例中注意到,我使用的
module
名称是 repo 的路径(与您在go mod init xxx
中使用的xxx
相反)。 This is intentional because it allows the go tooling to find the package when you import it from a different module.这是有意的,因为它允许 go 工具在您从其他模块导入 package 时找到它。 For example if you had used
go mod init github.com/[user]/[repository]
and option go_package = "github.com/[user]/[repository]/myproto";"
then the generated files should go into the myproto
folder in your project and you import them with import github.com/[user]/[repository]/myproto
. For example if you had used
go mod init github.com/[user]/[repository]
and option go_package = "github.com/[user]/[repository]/myproto";"
then the generated files should go into the myproto
项目中的文件夹,然后使用import github.com/[user]/[repository]/myproto
导入它们。
While you do not have to follow this approach I'd highly recommend it (it will save you from a lot of pain.), It can take a while to understand the go way of doing this, but once you do.虽然您不必遵循这种方法,但我强烈推荐它(它会让您免于很多痛苦。),了解 go 执行此操作的方式可能需要一段时间,但一旦您这样做了。 it works well and makes it very clear where a package is hosted.
它运行良好,并且非常清楚 package 的托管位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.