亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從 GitHub 存儲庫導入 protobuf 文件

從 GitHub 存儲庫導入 protobuf 文件

Go
神不在的星期二 2023-03-07 16:40:23
我目前有兩個 protobuf 回購協議:api 和timestamp:時間戳回購:- README.md- timestamp.proto- timestamp.pb.go- go.mod- go.sumapi回購:- README.md- protos/  - dto1.proto  - dto2.proto目前,timestamp包含對我想在其中使用的時間戳對象的引用api,但我不確定導入應該如何工作或者我應該如何修改編譯過程來處理這個問題。使這個過程復雜化的是,apirepo 被編譯為一個單獨的、下游的 Go 的 repo,名為api-go.例如,考慮dto1.proto:syntax = "proto3";package api.data;import "<WHAT GOES HERE?>";option go_package = "github.com/my-user/api/data"; // golangmessage DTO1 {    string id = 1;    Timestamp timestamp = 2;}我的編譯命令是這樣的:find $GEN_PROTO_DIR -type f -name "*.proto" -exec protoc \    --go_out=$GEN_OUT_DIR --go_opt=module=github.com/my-user/api-go \    --go-grpc_out=$GEN_OUT_DIR --go-grpc_opt=module=github.com/my-user/api-go \    --grpc-gateway_out=$GEN_OUT_DIR --grpc-gateway_opt logtostderr=true \    --grpc-gateway_opt paths=source_relative --grpc-gateway_opt     generate_unbound_methods=true \{} \;timestamp假設我對要編譯成的每種編程語言都有一個定義api,我將如何將其導入到.proto文件中,我應該怎么做才能確保導入不會在我的下游存儲庫中中斷?
查看完整描述

1 回答

?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

protobuf 沒有遠程導入路徑的本機概念。因此導入路徑必須相對于某些指定的本地文件系統基本路徑(通過-I/指定--proto_path)。


選項1

通常,最簡單的方法是為您的組織擁有一個包含 protobuf 定義的存儲庫——例如,一個名為acme-contract


.

└── protos

    └── acme

        ├── api

        │   └── data

        │       ├── dto1.proto

        │       └── dto2.proto

        └── timestamp

            └── timestamp.proto

你的 dto1.proto 看起來像:


syntax = "proto3";


package acme.api.data;


import "acme/timestamp/timestamp.proto";


message DTO1 {

  string id = 1;

  acme.timestamp.Timestamp timestamp = 2;

}

只要您生成與protos/此存儲庫目錄相關的代碼,就不會有問題。


選項 2

有多種選擇,您可以繼續將定義拆分到不同的存儲庫,但您無法真正逃避導入是文件系統相關的事實。


從歷史上看,這可以通過手動克隆各種存儲庫和安排目錄來處理,這樣路徑是相對的,或者通過使用-I指向可能有意或偶然包含原型文件的各種位置(例如在 $GOPATH 中)。這些策略最終往往會變得相當混亂且難以維護。


buf現在讓事情變得更容易了。如果你有你的timestamp回購協議:


.

├── buf.gen.yaml

├── buf.work.yaml

├── gen

│   └── acme

│       └── timestamp

│           └── timestamp.pb.go

├── go.mod

├── go.sum

└── protos

    ├── acme

    │   └── timestamp

    │       └── timestamp.proto

    ├── buf.lock

    └── buf.yaml

timestamp.proto看起來像:


syntax = "proto3";


package acme.timestamp;


option go_package = "github.com/my-user/timestamp/gen/acme/timestamp";


message Timestamp {

  int64 unix = 1;

}

buf.gen.yaml看起來像:


version: v1

plugins:

  - name: go

    out: gen

    opt: paths=source_relative

  - name: go-grpc

    out: gen

    opt:

      - paths=source_relative

      - require_unimplemented_servers=false

  - name: grpc-gateway

    out: gen

    opt:

      - paths=source_relative

      - generate_unbound_methods=true

... 并且下面的所有內容gen/都是通過生成的buf generate。


然后在您的api存儲庫中:


.

├── buf.gen.yaml

├── buf.work.yaml

├── gen

│   └── acme

│       └── api

│           └── data

│               ├── dto1.pb.go

│               └── dto2.pb.go

└── protos

    ├── acme

    │   └── api

    │       └── data

    │           ├── dto1.proto

    │           └── dto2.proto

    ├── buf.lock

    └── buf.yaml

看起來buf.yaml像:


version: v1

name: buf.build/your-user/api

deps:

  - buf.build/your-user/timestamp

breaking:

  use:

    - FILE

lint:

  use:

    - DEFAULT

dto1.proto看起來像:


syntax = "proto3";


package acme.api.data;


import "acme/timestamp/timestamp.proto";


option go_package = "github.com/your-user/api/gen/acme/api/data";


message DTO1 {

  string id = 1;

  acme.timestamp.Timestamp timestamp = 2;

}

和回購buf.gen.yaml中的一樣timestamp。


通過生成的代碼buf generate將取決于timestamp通過 Go 模塊的存儲庫:


// Code generated by protoc-gen-go. DO NOT EDIT.

// versions:

//  protoc-gen-go v1.28.1

//  protoc        (unknown)

// source: acme/api/data/dto1.proto


package data


import (

    timestamp "github.com/your-user/timestamp/gen/acme/timestamp"

    protoreflect "google.golang.org/protobuf/reflect/protoreflect"

    protoimpl "google.golang.org/protobuf/runtime/protoimpl"

    reflect "reflect"

    sync "sync"

)


// <snip>

請注意,如果對依賴項進行了更改,您需要確保 buf 和 Go 模塊保持相對同步。


選項 3

如果您不想利用 Go 模塊來導入生成的 pb 代碼,您也可以使用與 類似的設置Option 2,而是將所有代碼生成到一個單獨的存儲庫中(聽起來與您現在所做的類似) . 這最容易通過使用buf托管模式來實現,這將本質上使其不需要 + 忽略任何go_modules指令。


在api-go:


.

├── buf.gen.yaml

├── go.mod

└── go.sum

含有buf.gen.yaml:


version: v1

managed:

  enabled: true

  go_package_prefix:

    default: github.com/your-user/api-go/gen

plugins:

  - name: go

    out: gen

    opt: paths=source_relative

  - name: go-grpc

    out: gen

    opt:

      - paths=source_relative

      - require_unimplemented_servers=false

  - name: grpc-gateway

    out: gen

    opt:

      - paths=source_relative

      - generate_unbound_methods=true

然后,您需要為每個相應的回購生成代碼(傳送到 BSR):


$ buf generate buf.build/your-user/api

$ buf generate buf.build/your-user/timestamp

之后你應該為兩者生成一些代碼:


.

├── buf.gen.yaml

├── gen

│   └── acme

│       ├── api

│       │   └── data

│       │       ├── dto1.pb.go

│       │       └── dto2.pb.go

│       └── timestamp

│           └── timestamp.pb.go

├── go.mod

└── go.sum

并且導入將相對于當前模塊:


// Code generated by protoc-gen-go. DO NOT EDIT.

// versions:

//  protoc-gen-go v1.28.1

//  protoc        (unknown)

// source: acme/api/data/dto1.proto


package data


import (

    timestamp "github.com/your-user/api-go/gen/acme/timestamp"

    protoreflect "google.golang.org/protobuf/reflect/protoreflect"

    protoimpl "google.golang.org/protobuf/runtime/protoimpl"

    reflect "reflect"

    sync "sync"

)


// <snip>

總而言之,我推薦選項 1——將你的 protobuf 定義整合到一個單一的存儲庫中(包括 vendoring 3rd party 定義)——除非有特別強烈的理由不這樣做。


查看完整回答
反對 回復 2023-03-07
  • 1 回答
  • 0 關注
  • 195 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號