#!/usr/bin/env bash # Generate Dart bindings for the F∆I gRPC surface. # # Reads .proto files from the sibling fai_chain repo and # writes Dart code into lib/src/generated/. Run after # `dart pub global activate protoc_plugin` so that # `protoc-gen-dart` is on PATH (`$HOME/.pub-cache/bin`). # # Usage: # tools/generate.sh # # Env overrides: # PROTO_ROOT Path to fai_chain/proto/ (default: ../fai_chain/proto) # OUT_DIR Output dir (default: lib/src/generated) set -euo pipefail SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" SDK_ROOT="$( cd -- "$SCRIPT_DIR/.." && pwd )" PROTO_ROOT="${PROTO_ROOT:-$SDK_ROOT/../fai_chain/proto}" OUT_DIR="${OUT_DIR:-$SDK_ROOT/lib/src/generated}" if [[ ! -d "$PROTO_ROOT" ]]; then echo "error: PROTO_ROOT does not exist: $PROTO_ROOT" >&2 echo "Set PROTO_ROOT to the fai_chain/proto directory." >&2 exit 1 fi if ! command -v protoc >/dev/null 2>&1; then echo "error: protoc not found on PATH" >&2 echo "Install: brew install protobuf (macOS)" >&2 exit 1 fi # Make sure protoc-gen-dart is reachable. pub-cache/bin is the # canonical location after `dart pub global activate protoc_plugin`. export PATH="$HOME/.pub-cache/bin:$PATH" if ! command -v protoc-gen-dart >/dev/null 2>&1; then echo "error: protoc-gen-dart not found" >&2 echo "Install: dart pub global activate protoc_plugin" >&2 exit 1 fi mkdir -p "$OUT_DIR" # Find every proto file under the package root and pass them to # protoc with --dart_out for messages and grpc=true for services. PROTO_FILES=() while IFS= read -r -d '' file; do PROTO_FILES+=("$file") done < <(find "$PROTO_ROOT" -name '*.proto' -print0) if [[ ${#PROTO_FILES[@]} -eq 0 ]]; then echo "error: no .proto files found under $PROTO_ROOT" >&2 exit 1 fi # Locate the well-known-types include directory. Only needed # for protoc's resolver; we do NOT generate the WKT Dart files # anymore — `package:protobuf` (6.x+) ships them as # `well_known_types/google/protobuf/empty.pb.dart` etc., and # emitting our own copy creates duplicate-Empty-type errors at # the API boundary (HubAdminClient expects the packaged Empty, # our local copy is a distinct type to the analyser). WKT_INCLUDE="" for candidate in \ "/opt/homebrew/include" \ "/usr/local/include" \ "/usr/include"; do if [[ -f "$candidate/google/protobuf/empty.proto" ]]; then WKT_INCLUDE="$candidate" break fi done if [[ -z "$WKT_INCLUDE" ]]; then echo "error: google/protobuf/empty.proto not found in standard include dirs" >&2 echo "Install protobuf (brew install protobuf) so the well-known types ship alongside protoc." >&2 exit 1 fi # Wipe any stale WKT files generated by an earlier (pre- # protobuf-6) version of this script. Keeping them around # silently revives the duplicate-types breakage above on # regen. rm -rf "$OUT_DIR/google" echo "generating Dart bindings" echo " protos: ${#PROTO_FILES[@]} files under $PROTO_ROOT" echo " WKT include: $WKT_INCLUDE (protoc resolver only)" echo " output: $OUT_DIR" protoc \ --proto_path="$PROTO_ROOT" \ --proto_path="$WKT_INCLUDE" \ --dart_out=grpc:"$OUT_DIR" \ "${PROTO_FILES[@]}" echo "done. generated files:" find "$OUT_DIR" -name '*.dart' | sort