最近接手了一个19年的老项目, 项目里的 protobuf 版本老而且编译是基于本地环境, 多人开发时就因为各自的protoc版本不同, 导致生成的文件也是乱七八糟的, 所以决定使用 buf 来迁移项目, 但是遇到了一些问题, 记录一下

安装 buf

1
brew install buf

buf.gen.yaml 配置文档: https://buf.build/docs/configuration/v2/buf-gen-yaml/

buf 文档地址 https://buf.build/docs/

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 1. 初始化buf 配置文件  buf.yaml
buf init

# 2. 自己编辑生成 buf.gen.yaml 文件

# 3. 执行命令生成 buf.lock 文件, 这一步是把构建时用到的依赖都下载下来
buf dep update

# 4. 编译 protobuf 文件, 输出到 api 中
buf generate

报错: google/protobuf/wrappers.proto:122:9:symbol “google.protobuf.BytesValue.value” already defined at github.com/gogo_bak/protobuf@v1.3.2/protobuf/google/protobuf/wrappers.proto:122:9

原因是protoc_path 重复引入了, 或者引入的路径是 protoc_path=A/B/C;B/C 这种存在包含关系的路径, 也会报错

在buf 中的检查项:

检查 buf.gen.yaml 中的 input 配置

buf input配置描述官方文档: https://buf.build/docs/reference/inputs/

1
2
3
4
# buf.gen.yaml
inputs:
  - directory: proto
#  - directory: /Users/gpf/go/pkg/mod   # 这么写就是把 /Users/gpf/go/pkg/mod 放到 proto_path 中

问题: import “github.com/mwitkow/go-proto-validators/validator.proto”: file does not exist

这个包在 buf里面好像是没对应的plugins, 而且包作者好久没维护了, 个人还是建议还是把它替换成 buf.build/bufbuild/validate-go:v1.1.0 起码有一个组织在一直维护它

老项目里迁移到 buf 时, 如果业务代码里没用到validate, 又懒得改, 就这么办:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 1. 在 buf.yaml 里dep 新增配置, 如下

deps:   
  - buf.build/torq/go-proto-validators  # 引入这个包后, 构建时, 不会因为 github.com/mwitkow 报错

# 2. 在 buf.gen.yaml 里添加配置:

managed:
  enabled: true
  override:
    - file_option: go_package_prefix   # 标记包前缀为 xxx
      value: xxx
  disable:
    - module: buf.build/torq/go-proto-validators  # 在这里禁用掉, 这样生成的文件不会出现类似 import xxx/github.com/mwitkow/go-proto-validators/validator  这种代码

这种只是一个折中的办法, 一劳永逸的还是换包, 换 validator 的配置写法

贴一下当前用的配置信息

buf.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml
version: v2
lint: # 标记 lint 配置标准, 通常不用变
  use:
    - STANDARD
modules:   # 标记 proto 文件所在目录
  - path: proto
deps:   # 标记依赖
  - buf.build/envoyproxy/protoc-gen-validate
  - buf.build/torq/go-proto-validators
breaking:  # 生成的文件按 proto 下目录进行分组
  use:
    - FILE

buf.gen.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
version: v2
managed:
  enabled: true
  override:
    - file_option: go_package_prefix   # 标记包前缀为 map_data_train_rpc/api
      value: map_data_train_rpc/api
  disable:
    - module: buf.build/torq/go-proto-validators
    - module: buf.build/envoyproxy/protoc-gen-validate  # 标记与这个 dep 相关的包不被覆盖包前缀
inputs: # 编译时会引入到 protoc_path 的目录
  - directory: proto
#  - directory: /go/pkg/mod   # 这么写就是把 /go/pkg/mod 放到 proto_path 中
plugins:
  - remote: buf.build/grpc/go:v1.2.0
    out: api
    opt:
    - paths=source_relative,require_unimplemented_servers=false
  # dependencies 扩展依赖
  - remote: buf.build/protocolbuffers/go:v1.28.1
    out: api
    opt:
      - paths=source_relative
  - remote: buf.build/bufbuild/validate-go:v1.1.0
    out: api
    opt:
      - paths=source_relative