From fca9397464e9d323b78feb2c33c36eb7f943bfa9 Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Wed, 13 Sep 2023 19:54:40 -0500 Subject: [PATCH] chore(proto): Add a buf.gen.rs.yaml and corresponding script to create Rust types for Wasm Stargate messages --- .gitignore | 2 +- CHANGELOG.md | 3 +- proto/buf.gen.rs.sh | 173 ++++++++++++++++++++++++++++++++++++++++++ proto/buf.gen.rs.yaml | 32 ++++++++ 4 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 proto/buf.gen.rs.sh create mode 100644 proto/buf.gen.rs.yaml diff --git a/.gitignore b/.gitignore index aa20d4430..09a8df65f 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,4 @@ mockdata/ docs dist coverage.txt -temp \ No newline at end of file +temp diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d2c1e8a0..ef0fb6d6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#1558](https://github.com/NibiruChain/nibiru/pull/1558) - feat(perp): paginated query to read the position store * [#1554](https://github.com/NibiruChain/nibiru/pull/1554) - refactor: runs gofumpt formatter, which has nice conventions: go install mvdan.cc/gofumpt@latest * [#1574](https://github.com/NibiruChain/nibiru/pull/1574) - chore(goreleaser): update wasmvm to v1.4.0 +* [#xxx](https://github.com/NibiruChain/nibiru/pull/xxx) - chore(proto): Add a buf.gen.rs.yaml and corresponding script to create Rust types for Wasm Stargate messages ### Features @@ -645,4 +646,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Testing * [#695](https://github.com/NibiruChain/nibiru/pull/695) Add `OpenPosition` integration tests. -* [#692](https://github.com/NibiruChain/nibiru/pull/692) Add test coverage for Perp MsgServer methods. \ No newline at end of file +* [#692](https://github.com/NibiruChain/nibiru/pull/692) Add test coverage for Perp MsgServer methods. diff --git a/proto/buf.gen.rs.sh b/proto/buf.gen.rs.sh new file mode 100644 index 000000000..c330829a4 --- /dev/null +++ b/proto/buf.gen.rs.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash + +# buf.gen.rs.sh: Generates Rust protobuf types based on NibiruChain/nibiru/proto. + +set -eo pipefail + +move_to_dir_with_protos() { + # Get the name of the current directory + local start_path=$(pwd) + local start_dir_name=$(basename $start_path) + + # Check if 'start_dir_name' is "nibiru" (the repo). + # Or if the immediate parent is "nibiru", move to it. + if [ "$start_dir_name" != "nibiru" ]; then + if [ -d "../nibiru" ]; then + cd ../nibiru + else + echo "Not in 'nibiru' directory or its immediate child. Exiting." + return 1 + fi + fi + + # Check if nibiru/go.mod exists + if [ ! -f "go.mod" ]; then + echo "start_path: $start_path" + echo "go.mod not found in 'nibiru' directory. Exiting." + return 1 + fi + + go mod tidy + + # Check if the nibiru/proto directory exists + if [ ! -d "proto" ]; then + echo "start_path: $start_path" + echo "'proto' directory not found in 'nibiru'. Exiting." + return 1 + fi + + NIBIRU_REPO_PATH=$(pwd) + echo "NIBIRU_REPO_PATH: $NIBIRU_REPO_PATH" +} + +init_globals() { + proto_dir="proto" # nibiru/proto + out_dir="dist" # nibiru/dist + + cosmos_sdk_gh_path=$(go list -f '{{ .Dir }}' -m github.com/cosmos/cosmos-sdk) + # cosmos_sdk_gh_path is parsed from the go.mod and will be a string like: + # $HOME/go/pkg/mod/github.com/cosmos/cosmos-sdk@v0.47.4 + + nibiru_cosmos_sdk_version=$(echo $cosmos_sdk_gh_path | awk -F'@' '{print $2}') + # Example: v0.47.4 + + # OUT_PATH: Path to the generated protobuf types. + OUT_PATH="${NIBIRU_REPO_PATH:-.}/$out_dir" + echo "OUT_PATH: $OUT_PATH" +} + + +ensure_nibiru_cosmos_sdk_version() { + # Ensure nibiru_cosmos_sdk_version has a value before proceeding + if [ -z "$nibiru_cosmos_sdk_version" ]; then + echo "nibiru_cosmos_sdk_version is empty. Exiting." + return 1 + fi +} + +go_get_cosmos_protos() { + echo "Grabbing cosmos-sdk proto file locations from disk" + if ! grep "github.com/gogo/protobuf => github.com/regen-network/protobuf" go.mod &>/dev/null; then + echo -e "\tPlease run this command from somewhere inside the cosmos-sdk folder." + return 1 + fi + + ensure_nibiru_cosmos_sdk_version + + # get protos for: cosmos-sdk, cosmos-proto + go get github.com/cosmos/cosmos-sdk@$nibiru_cosmos_sdk_version + go get github.com/cosmos/cosmos-proto +} + +buf_gen() { + # Called by proto_gen + local proto_dir="$1" + + if [ ! buf ]; then + echo "Please install buf to generate protos." + exit 1 + fi + + local buf_dir="$NIBIRU_REPO_PATH/proto" + + buf generate $proto_dir \ + --template $buf_dir/buf.gen.rs.yaml \ + -o $OUT_PATH \ + --config $proto_dir/buf.yaml +} + +proto_clone_sdk() { + move_to_dir_with_protos + local start_dir=$(pwd) # nibiru + cd .. + + # degit copies a GitHub repo without downloading the entire git history, + # which is much faster than a full git clone. + # npx degit "cosmos/cosmos-sdk#$nibiru_cosmos_sdk_version" cosmos-sdk --force + DIR_COSMOS_SDK="$(pwd)/cosmos-sdk" + cd $start_dir +} + +proto_gen() { + + go_get_cosmos_protos + proto_clone_sdk + + printf "\nProto Directories: \n" + cd $NIBIRU_REPO_PATH/.. + proto_dirs=() + proto_dirs+=("$DIR_COSMOS_SDK/proto") + proto_dirs+=("nibiru/proto") + echo "$proto_dirs" + + echo "Generating protobuf types for each proto_dir" + for proto_dir in "${proto_dirs[@]}"; do + string=$proto_dir + # Remove prefix + prefix=$HOME/go/pkg/mod/github.com/ + prefix_removed_string=${string/#$prefix/} + # Remove prefix + # prefix=$(dirname $(pwd)) + prefix=$(pwd)/ + prefix_removed_string=${prefix_removed_string/#$prefix/} + echo "------------ generating $prefix_removed_string ------------" + mkdir -p $OUT_PATH/${proto_dir} + + buf_gen $proto_dir + done + + echo "Completed - proto_gen() to path: $OUT_PATH" +} + +clean() { + # clean: the Rust buf generator we're using leaves some garbage. + # This function clears that way after a successful build. + + # Guarantee that OUT_PATH is defined + if [ -z "$OUT_PATH" ]; then + echo "skipped clean() since NIBIRU_REPO_PATH is not defined." + return 0 + fi + + # Guarantee that OUT_PATH is defined again just to be extra safe. + OUT_PATH="${OUT_PATH:-.}" + rm -rf $OUT_PATH/home + rm -rf $OUT_PATH/nibiru +} + +# ------------------------------------------------ +# main : Start of script execution +# ------------------------------------------------ + +main () { + move_to_dir_with_protos + init_globals + proto_gen + clean +} + +if main; then + echo "🔥 Generated Rust proto types successfully. " +else + echo "❌ Generation failed." +fi diff --git a/proto/buf.gen.rs.yaml b/proto/buf.gen.rs.yaml new file mode 100644 index 000000000..1a051ff22 --- /dev/null +++ b/proto/buf.gen.rs.yaml @@ -0,0 +1,32 @@ +# buf.gen.rs.yaml +# +# Run with: +# ```bash +# proto_dir="proto" +# out_dir="gen_rust" +# buf generate $proto_dir --template proto/buf.gen.rs.yaml \ +# -o $out_dir \ +# --config proto/buf.yaml \ +# --include-imports +# ``` +version: v1 +managed: + enabled: true +plugins: + # protoc-gen-prost is the main code generation plugin + # https://github.com/neoeinstein/protoc-gen-prost/blob/main/protoc-gen-prost/README.md + - plugin: buf.build/community/neoeinstein-prost:v0.2.3 + out: proto-rs + opt: + - bytes=. + # - file_descriptor_set + # - compile_well_known_types + # - extern_path=.google.protobuf=::pbjson_types + + + # TODO(Unique-Divine): investigate whether JSON serialization trait + # implementations are needed for Rust protobufs used on Wasm::StargateMsg. + # protoc-gen-prost-serde: Canonical JSON serialization of protobuf types + # https://github.com/neoeinstein/protoc-gen-prost/blob/main/protoc-gen-prost-serde/README.md + # - plugin: buf.build/community/neoeinstein-prost-serde:v0.2.3 + # out: proto-rs