Files
waf-platform/EdgeCommon/build/check-proto-sync.sh
2026-03-22 17:37:40 +08:00

107 lines
3.6 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
#
# check-proto-sync.sh — 检查 .proto 和 .pb.go 的 rawDesc 是否一致
#
# 工作原理:从 .proto 文件提取字段数量,从 .pb.go 的 Go struct 提取字段数量,
# 如果 struct 的字段比 proto 的字段多(说明手动添加了字段没有重新生成),则报错。
#
# 用法:
# ./check-proto-sync.sh # 检查所有 proto 文件
# ./check-proto-sync.sh --fix # 如果有 protoc自动重新生成
set -e
ROOT=$(dirname "$0")/..
PROTO_DIR="$ROOT/pkg/rpc/protos"
PB_DIR="$ROOT/pkg/rpc/pb"
ERRORS=0
echo "Checking proto <-> pb.go sync ..."
# 对每个 .proto 文件,检查 message 中的字段数量是否和 .pb.go 一致
for proto_file in "$PROTO_DIR"/*.proto "$PROTO_DIR"/models/*.proto; do
[ -f "$proto_file" ] || continue
base=$(basename "$proto_file" .proto)
pb_file="$PB_DIR/${base}.pb.go"
[ -f "$pb_file" ] || continue
# 从 .proto 提取每个 message 的字段数(格式: "MessageName:N"
# 只计算顶层 message 的直接字段(= N 格式的行)
current_msg=""
declare -A proto_fields
while IFS= read -r line; do
# 匹配 message 声明
if [[ "$line" =~ ^[[:space:]]*message[[:space:]]+([A-Za-z0-9_]+) ]]; then
current_msg="${BASH_REMATCH[1]}"
proto_fields["$current_msg"]=0
fi
# 匹配字段声明type name = N;
if [ -n "$current_msg" ] && [[ "$line" =~ =[[:space:]]*[0-9]+\; ]]; then
proto_fields["$current_msg"]=$(( ${proto_fields["$current_msg"]} + 1 ))
fi
# message 结束
if [ -n "$current_msg" ] && [[ "$line" =~ ^[[:space:]]*\} ]]; then
current_msg=""
fi
done < "$proto_file"
# 从 .pb.go 提取每个 struct 的 protobuf 字段数
declare -A pbgo_fields
current_struct=""
while IFS= read -r line; do
if [[ "$line" =~ ^type[[:space:]]+([A-Za-z0-9_]+)[[:space:]]+struct ]]; then
current_struct="${BASH_REMATCH[1]}"
pbgo_fields["$current_struct"]=0
fi
if [ -n "$current_struct" ] && [[ "$line" =~ protobuf:\" ]]; then
pbgo_fields["$current_struct"]=$(( ${pbgo_fields["$current_struct"]} + 1 ))
fi
if [ -n "$current_struct" ] && [[ "$line" =~ ^\} ]]; then
current_struct=""
fi
done < "$pb_file"
# 比较
for msg in "${!proto_fields[@]}"; do
proto_count=${proto_fields["$msg"]}
pbgo_count=${pbgo_fields["$msg"]:-0}
if [ "$pbgo_count" -gt "$proto_count" ] 2>/dev/null; then
echo " [WARN] $base: struct '$msg' has $pbgo_count fields in .pb.go but only $proto_count in .proto (hand-edited?)"
ERRORS=$((ERRORS + 1))
elif [ "$pbgo_count" -lt "$proto_count" ] 2>/dev/null; then
echo " [WARN] $base: struct '$msg' has $pbgo_count fields in .pb.go but $proto_count in .proto (needs regeneration)"
ERRORS=$((ERRORS + 1))
fi
done
unset proto_fields
unset pbgo_fields
declare -A proto_fields
declare -A pbgo_fields
done
if [ "$ERRORS" -gt 0 ]; then
echo ""
echo "Found $ERRORS proto sync issue(s)."
echo "Fix: install protoc and run 'cd EdgeCommon/build && ./build.sh'"
if [ "$1" = "--fix" ]; then
if command -v protoc &>/dev/null; then
echo "Regenerating ..."
cd "$(dirname "$0")"
./build.sh
echo "Done. Please review and commit the changes."
else
echo "protoc not found, cannot auto-fix."
exit 1
fi
else
exit 1
fi
else
echo "All proto files are in sync. OK"
fi