Skip to content

Commit

Permalink
chore(proto): Add a buf.gen.rs.yaml and corresponding script to creat…
Browse files Browse the repository at this point in the history
…e Rust types for Wasm Stargate messages
  • Loading branch information
Unique-Divine committed Sep 14, 2023
1 parent 0f2169e commit fca9397
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ mockdata/
docs
dist
coverage.txt
temp
temp
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
* [#692](https://github.com/NibiruChain/nibiru/pull/692) Add test coverage for Perp MsgServer methods.
173 changes: 173 additions & 0 deletions proto/buf.gen.rs.sh
Original file line number Diff line number Diff line change
@@ -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/[email protected]

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
32 changes: 32 additions & 0 deletions proto/buf.gen.rs.yaml
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit fca9397

Please sign in to comment.