在每个目录上编译 .proto 文件

Compile .proto files on every directory

我有这样的目录结构:

Makefile
README.md
go.mod
google/
  -> Protobuf dependencies (ignore)
gopb/
  -> Compiled Go protobuf files (ignore)
protoc-gen-openapiv2/
  -> Protobuf OpenAPI depdencies (ignore)
providers/
  - polygon/
    - tickers.proto
    - query.proto

我想设置一个命令,它可以找到所有包含 .proto 文件(上面指出的除外)和 运行 protoc 的目录,输出到gopb 目录下的同名目录。到目前为止,我已经能够创建一个 find 命令 returns 目录名称:

$ find -not \( -path "*.git*" -or -path "*google*" -or -path "*protoc*" -or -path . -or -path "*gopb*" \) -type d -print

./providers
./providers/polygon

显然,这并不完全准确,我想解决这个问题,但主要问题是,当我使用 -exec 标志调用协议时:

$ find -not \( -path "*.git*" -or -path "*google*" -or -path "*protoc*" -or -path . -or -path "*gopb*" \) -type d \
> -exec protoc --go_out=./gopb/ --go_opt=paths=source_relative {}/*.proto \;

这会打印出两个错误:

Could not make proto path relative: ./providers/*.proto: No such file or directory
Could not make proto path relative: ./providers/polygon/*.proto: No such file or directory

我不确定我在这里做错了什么,因为如果我调用 protoc --go_out=./gopb/ --go_opt=paths=source_relative ./providers/polygon/*.proto,它会按预期创建文件。我在这里做错了什么?

有多种方法可以解决该问题,但要将 *.proto 视为一个 glob,您需要将其解释为 shell。

以下是使用 findbash 的方法:

find . -not \( ...paths... \) \
       -type d \
       -exec bash -c '
           shopt -s nullglob
           for d
           do
               f=( "$d"/*.proto )
               (( ${#f[@]} > 0 )) || continue
               protoc --go_out=./gopb/ --go_opt=paths=source_relative "${f[@]}"
           done
' _ {} +

在@Fravadona 的帮助下,我意识到我用来编译 .proto 文件的方法行不通。因此,我将所有要编译的 protobuf 文件移动到一个名为 protos 的新目录中,这将我的目录结构修改为:

Makefile
README.md
go.mod
google/
  -> Protobuf dependencies (ignore)
gopb/
  -> Compiled Go protobuf files (ignore)
protoc-gen-openapiv2/
  -> Protobuf OpenAPI depdencies (ignore)
protos/
  - providers/
    - polygon/
      - tickers.proto
      - query.proto

然后我将命令修改为:

find ./protos -type f -name "*.proto" -exec protoc --go_out=../../../ {} \;

这个新命令在 /protos 目录中查找所有 .proto 文件并在每个文件上调用 protoc。我删除了 source-relative 选项,这也需要在我的导入中进行一些代码更改。但是,这适合我的需要。请注意,我必须使用 ../../../ 作为我的输出目录,因为我的 protobuf 存储库存在于 github.com/myrepo/protobuf 中,我希望将文件写入 github.com/myrepo/protobuf/gopb.