Правильный формат protoc go_package?

У меня есть существующий проект в Go, где я использую буферы протокола / gRPC. До недавнего времени опция go_package была необязательной, и результирующее имя пакета Go совпадало бы с именем прото-пакета.

Этот файл находится в корне проекта. Сгенерированный файл кода (authenticator.pb.go) находится в том же месте. Прото файл:

syntax = "proto3";

package authenticator;

service Authenticator {...}

Команда генерации указывает, что я хочу выводить в том же каталоге:

protoc --go_out=plugins=grpc:. authenticator.proto

Сегодня вытащил новую версию компилятора буферов протоколов и github.com/golang/protobuf/protoc-gen-go. При первом запуске появилось предупреждение:

WARNING: Missing 'go_package' option in "authenticator.proto",
please specify it with the full Go package path as
a future release of protoc-gen-go will require this be specified.
See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.

Предложенная ссылка более-менее бесполезна. Но в руководстве более подробное описание:

Параметр go_package определяет путь импорта пакета, который будет содержать весь сгенерированный код для этого файла. Имя пакета Go будет последним компонентом пути импорта. Например, в нашем примере будет использоваться имя пакета «tutorialpb».

option go_package = "github.com/protocolbuffers/protobuf/examples/go/tutorialpb";

После добавления этой опции в прото-файл и повторного выполнения команды выходные данные попадают в этот путь относительно корня проекта. Что-то вроде:

$GOPATH/src/github.com/<org>/authenticator/github.com/<org>/authenticator/authenticator.pb.go

Я пробовал использовать следующие go_package имена:

  • .
  • authenticator

Генерация произошла в правильном месте, но я получил предупреждение:

WARNING: Deprecated use of 'go_package' option without a full import path...

Так как же правильно не нарушить макет проекта?


person Tim    schedule 07.05.2020    source источник


Ответы (9)


Для чистых прототипов поколений вы можете сделать следующее

protoc --go_out=paths=source_relative:./gen -I. authenticator.proto

или для генерации для grpc можно использовать следующее

protoc --go_out=plugins=grpc:./gen --go_opt=paths=source_relative authenticator.proto

Если это не удается, у вас, вероятно, есть более новая версия protoc, и вместо этого вам нужно использовать следующую команду.

protoc --go-grpc_out=./gen --go-grpc_opt=paths=source_relative authenticator.proto

Это просто Google, снова принимающий отдельные решения о том, как вам следует писать и управлять своим кодом. Однако, если вы рассмотрите достаточно проблем с людьми, имеющими похожие проблемы, я обнаружил, что приведенная выше команда может теперь можно использовать. В дополнение к добавлению полного пути импорта, как показано в другом ответе

option go_package = "github.com/example/path/gen;gen";

Следуя приведенному выше пакету и команде protoc, вы получите свой прото-файл в корне проекта с именем модуля github.com/example/path. Затем ваш код будет помещен в папку gen, за создание которой вы будете отвечать.

Возможно, вам придется настроить выходное местоположение source_relative для вашего использования, но, по крайней мере, вы не получите дублирование путей или необходимость снова помещать свой код в GOPATH.

В дальнейшем это может не сработать из-за дополнительных изменений, обнаруженных в этом билете. К сожалению, двоичное имя точно такое же, поэтому, если вы столкнетесь с проблемами, прочтите этот билет и попробуйте переключить версию, которую вы установили, до тех пор, пока новый protoc-gen-go не будет готов для prod.

person eatingthenight    schedule 23.06.2020
comment
Есть ли способ изменить путь к модулю через протокол? Я хочу сгенерировать код Go как для клиента, так и для сервера, которые являются частью разных модулей, я пробовал использовать go_opt=module, но он не работает с source_relative. - person Walton; 09.02.2021
comment
Похоже, что часть плагинов в --go_out=plugins=grpc больше не поддерживается. Для получения аналогичного результата мне удалось выполнить следующее: protoc --go-grpc_out=./gen --go-grpc_opt=paths=source_relative authenticator.proto - person ymbcKxSw; 24.05.2021

Вам просто нужно добавить опцию Go, которая сообщит, что нужно добавить файл относительно файла proto.

protoc --go_out=. --go_opt=paths=source_relative your_file.proto 

Это сделает your_file.pb.go в том же каталоге, что и your_file.proto

person Vaibhav Grover    schedule 15.07.2020
comment
--go_opt=paths=source_relative, безусловно, путь к успеху. Я исключил другой ответ, поскольку он содержал больше информации по проблеме. - person Tim; 29.07.2020

Вышеупомянутая ошибка исчезла, когда я добавил

option go_package = "github.com/monkrus/grpc-from0;grpc_from0";, как показано ниже:

chat.proto

person monkrus    schedule 23.05.2020
comment
Это исправляет ошибку, но по-прежнему оставляет вам более чем нежелательное размещение файлов для существующих проектов. - person eatingthenight; 23.06.2020
comment
option go_package уже упоминался в вопросе. - person Tim; 29.07.2020

Если вы используете syntax = proto3;. Эта проблема обязательно возникнет после изменения обработки генерации кода grpc.

шаг 1: вставьте эту строку в свой your_file_with.proto

 option go_package = "pb;gen";
   

Шаг 2: Предположим, вы хотите сгенерировать все файлы в папке pb, замените pb своим именем, затем запустите cmd в окне терминала. В моем случае весь мой протофайл находится в папке proto в каталоге проекта

 protoc -I=proto --go_out=. proto/*.proto
person sourav pandit    schedule 17.01.2021
comment
Простое решение. Это сработало. Спасибо - person pravin; 20.02.2021

Хотя документация не отображается, я заставил ее работать, установив для выходного каталога значение GOPATH/src.

protoc --go_out=plugins=grpc:$(go env GOPATH)/src authenticator.proto 

Надеюсь, это сэкономит время кому-нибудь еще.

person Tim    schedule 07.05.2020
comment
Это просто похоже на взлом, когда вы снова вынуждены поместить весь свой код Go в специальное место. - person eatingthenight; 23.06.2020
comment
@mschuett; да, это действительно был взлом. Скорее обходной путь, чтобы продолжить работу, пока кто-нибудь не найдет лучшее решение. - person Tim; 29.07.2020

За тестирование в проекте go-grpc-http-rest-microservice-tutorial https://medium.com/@amsokol.com/tutorial-how-to-develop-go-grpc-microservice-with-http-rest-endpoint-middleware-kubernetes-af1fff81aeb2.

и исходный код https://github.com/amsokol/go-grpc-http-rest-microservice-tutorial/tree/part2

Пытался сгенерировать протобуфы, но команда продолжала терпеть неудачу. Выполнение команды само по себе может вызвать сбой команды без уведомления, или если я попытаюсь запустить команду с префиксом sudo, я могу получить ошибку:

Укажите программу, используя абсолютный путь, или убедитесь, что программа доступна в системной переменной PATH --go_out: protoc-gen-go: Ошибка плагина с кодом состояния 1.

Я знал, что путь не является проблемой, я мог повторить $ PATH и увидеть, что пути GOBIN и GOROOT находятся в пути (хотя я явно не экспортирую ни одну из этих переменных напрямую), то есть в нижней части .bashrc

# export GOPATH=$HOME/go
# export GOBIN=$HOME/go/bin
# export GOROOT=/usr/local/go/bin
# export PATH=$PATH:$GOBIN:$GOROOT
export PATH=$PATH:$HOME/go/bin:/usr/local/go/bin


$ echo $PATH
/home/tngai/.local/bin:/usr/local/lib/npm/bin:/usr/local/sbin:/usr/local/bin:/usr        /sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/include:/home/tngai/go/bin:/usr/local/go/bin

и если я наберу protoc-gen-go, это не будет ошибкой (но, похоже, приведет меня к другой командной строке, из которой я ctrl + c для выхода), так что это не было проблемой

Короче говоря, я заметил, что два параметра используются для определения выходного пути к сгенерированным файлам, а также что если вы сделаете путь слишком длинным, он может автоматически выдать ошибку.

Вот он работает: команда для генерации, где первые два - это просто пути к файлу для поиска файла прототипа и его файлов прототипа зависимостей, а go_out - путь префикса для выходного файла (ов):

//cmd to run to generate protobuf and add it to the output directory
protoc --proto_path=api/proto/v1 --proto_path=third_party --go_out=plugins=grpc:./output todo-service.proto

// or below to add it under the pkg directory
protoc --proto_path=api/proto/v1 --proto_path=third_party --go_out=plugins=grpc:./ todo-service.proto

при объединении с путем, указанным в самом прото-файле, из требуемой опции go_package, которая является следующей частью выходного пути.

//todo-service.proto file
syntax = "proto3";
package v1; //name of the folder this is in
 
import "google/protobuf/timestamp.proto";
import "google/api/annotations.proto"; 
//import "protoc-gen-swagger/options/annotations.proto";

//new required line I had to add, and which also determines output path of gen file(s)
option go_package = "./pkg/api/v1";

//...commented out the swagger generation per testing just the protobuf generation...

// Task we have to do
message ToDo {
// Unique integer identifier of the todo task
int64 id = 1;
// ...

введите описание изображения здесь

person DeltaPng    schedule 14.09.2020

Если имя вашего пакета - user_service

user_service.proto такое определение:

syntax = "proto3";

package user_service;

service UserService {
}

just add option go_package = "./;user_service"; under package user_service; like this :

syntax = "proto3";

package user_service;

option go_package = "./;user_service";

service UserService {
}

Выполните следующее: protoc *.proto --go_out=plugins=grpc:./ в каталоге user_serivce. Это должно сработать.

person liwei song    schedule 01.03.2021

Вы можете просто определить свой необязательный путь импорта следующим образом

option go_package = ".;<Your_Import_path>";

Например, мы можем принять путь к пакету как / pub, поэтому утверждение будет следующим.

option go_package = ".;pub";

Затем вы можете просто выполнить команду protoc для создания файла pb.go.

protoc -I=<ABS_PATH_OUTPUT_DIR> --go_out=<ABS_PATH_PROTO_FILE>
person Isuru Kariyawasam    schedule 24.05.2021

Здравствуйте, я объясню шаг за шагом, как я его сгенерировал, прочитав документацию

Создать папку grpcgo

mkdir grpcgo && cd grpcgo

Создать проект

go mod init projectxxx
## Download and install dependencies
go get google.golang.org/protobuf/cmd/protoc-gen-go
go get github.com/golang/protobuf

Создайте файл .proto

wishlist.proto

syntax = "proto3";

package grpcgo; #Folder

option go_package = "pb;gen"; <-- Add 

message Item {
    enum ItemPriority {
        LOW = 0;
        MID = 50;
        HIGH = 100;
    }

    enum ItemStatus {
        INACTIVE = 0;
        ACTIVE = 1;
    }

    string id = 1;
    string wishListId = 2;
    string name = 3; 
    string link = 4;
    double price = 5;

    ItemPriority priority = 6;
    ItemStatus status = 7;

}

message WishList {
    enum WishListStatus {
        INACTIVE = 0;
        ACTIVE = 1;
    }

    string id = 1;
    string name = 2;
    WishListStatus status = 3;

}

Компиляция прото

protoc -I=$PWD --go_out=$PWD $PWD/proto/*.proto

Документация:

https://developers.google.com/protocol-buffers/docs/gotutorial

https://blog.friendsofgo.tech/posts/introduccion-a-grpc/ < / а>

Версия:

github.com/golang/protobuf v1.5.2

google.golang.org/protobuf v1.26.0

go версия go1.16.5 linux / amd64

обнять из Аргентины

person Nelson Javier Avila    schedule 20.06.2021