简体   繁体   English

找到模块 XXX,但不包含 package XXX

[英]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.gofile_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:您的选择是:

  1. Copy the output from protoc directly into your project folder and change the package declarations to match your package.将 output 从protoc直接复制到您的项目文件夹中,并更改package声明以匹配您的 package。 If you do this there is no need for any imports.如果您这样做,则不需要任何导入。
  2. Copy (or set go_out argument to protoc ) the output from protoc into a subfolder of your project.将 protoc 中的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所在文件夹的路径(这就是您所做的)。
  3. Store the files in a repo (on github or somewhere else).将文件存储在存储库中(在 github 或其他地方)。 This does not need to be the same repo as your .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.

相关问题 go:找到模块但不包含 package - go: module found but does not contain package 找不到模块:包路径。 不从包中导出 - Module not found: Package path . is not exported from package Firebase 错误:找不到模块:错误:包路径。 不从包中导出 - Firebase Error : Module not found: Error: Package path . is not exported from package AWS Glue 作业有时无法解析给定输入列的“xxx” - AWS Glue Job sometimes cannot resolve '`xxx`' given input columns `Firebase` package 已成功找到。 但是,这个 package 本身指定了一个无法解析的“主”模块字段 - `Firebase` package was successfully found. However, this package itself specifies a `main` module field that could not be resolved Firebase Auth:来自此 Android 客户端应用程序 com.xxx 的请求被阻止 - Firebase Auth: Requests from this Android client application com.xxx are blocked 找不到 Notifee 本机模块 - Notifee native module not found 为什么将 --package-path 设置为本地目录会在 gcloud 中出现 python not found 错误? - Why does setting --package-path to a local directory give python not found error in gcloud? “UnityWebRequest”不包含“结果”的定义 - 'UnityWebRequest' does not contain a definition for 'result' 我可以使用 GCP VM (xxx-compute@developer.gserviceaccount.com) 的服务帐户而不是 SA json 文件来使用 python 进行 api 调用吗? - Can I use the service account of a GCP VM (xxx-compute@developer.gserviceaccount.com) instead of SA json file to make api calls using python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM