xref: /spdk/scripts/gen_sma_goapi.sh (revision 2f2c95ec8838c28abc931526d6789a2995557cf2)
1#!/usr/bin/env bash
2#  SPDX-License-Identifier: BSD-3-Clause
3#  Copyright (C) 2018 Intel Corporation
4#  All rights reserved.
5#
6set -e
7
8rootdir=$(readlink -f $(dirname "$0")/..)
9scriptfile=$(basename "$0")
10
11sma_goapi_dir=""                 # destination directory of generated go api
12sma_goapi_ver=""                 # example: v1alpha1, parse from sma.proto go_package
13sma_goapi_mod=""                 # example: github.com/spdk/sma-goapi, parse from sma.proto go_package
14sma_proto_dir="${rootdir}/proto" # location of sma proto files
15
16function usage() {
17	echo "Usage: $0 -o SMA_GOAPI_DIR [-p PROTO_DIR]"
18	echo
19	echo "Generate SMA Go gRPC API from proto files."
20	echo
21	echo "SMA_GOAPI_DIR - target location for generating go.mod"
22	echo "PROTO_DIR     - the location of sma.proto, the default is ${sma_proto_dir}"
23	exit 0
24}
25
26function error() {
27	echo "${scriptfile}:" "$@" >&2
28	exit 1
29}
30
31function require() {
32	local tool="$1"
33	command -v "$tool" > /dev/null || error "missing $tool, make sure it is in PATH. (If installed with pkgdep.sh, source /etc/opt/spdk-pkgdep/paths/export.sh)"
34}
35
36function validate-inputs() {
37	local go_package
38	require go
39	require protoc
40	require protoc-gen-go
41
42	[[ -n "${sma_goapi_dir}" ]] || error "missing -o SMA_GOAPI_DIR"
43
44	[[ -f "${sma_proto_dir}/sma.proto" ]] || error "missing ${sma_proto_dir}/sma.proto"
45
46	go_package=$(awk -F '"' '/option +go_package *=/{print $2}' < "${sma_proto_dir}/sma.proto")
47	[[ -n "${go_package}" ]] || error "missing go_package in ${sma_proto_dir}/sma.proto"
48	sma_goapi_ver="${go_package##*/}"
49	sma_goapi_mod="${go_package%/*}"
50
51	[[ "${sma_goapi_ver}" == v* ]] || error "invalid version in ${sma_proto_dir}/sma.proto, expecting vX[(alpha|beta)Y]"
52
53	for src_proto in "${sma_proto_dir}"/*.proto; do
54		grep -q "go_package.*=.*${sma_goapi_mod}/${sma_goapi_ver}" "${src_proto}" \
55			|| error "expected go package ${sma_goapi_mod}/${sma_goapi_ver} in ${src_proto}"
56	done
57}
58
59function generate() {
60	local ver_dir="${sma_goapi_dir}/${sma_goapi_ver}"
61	local dst_protos=()
62	local dst_proto
63
64	mkdir -p "${ver_dir}" || error "failed to create directory SMA_GOAPI_DIR/SMA_GOAPI_VER: ${ver_dir}"
65
66	for src_proto in "${sma_proto_dir}"/*.proto; do
67		dst_proto="${ver_dir}/$(basename "$src_proto")"
68		cp "$src_proto" "$dst_proto" || error "failed to copy '${src_proto}' to '${dst_proto}'"
69		dst_protos+=("${dst_proto}")
70	done
71
72	for dst_proto in "${dst_protos[@]}"; do
73		protoc --go_out="${ver_dir}" \
74			--go_opt=module="${sma_goapi_mod}/${sma_goapi_ver}" \
75			--go-grpc_out="${ver_dir}" \
76			--go-grpc_opt=module="${sma_goapi_mod}/${sma_goapi_ver}" \
77			--proto_path="${ver_dir}" \
78			"${dst_proto}"
79	done
80
81	(
82		cd "${sma_goapi_dir}" || error "cannot change directory to ${sma_goapi_dir}"
83		rm -f go.mod go.sum
84		go mod init "${sma_goapi_mod}" || error "go mod init ${sma_goapi_mod} failed in ${sma_goapi_dir}"
85		go mod tidy || error "go mod tidy failed in ${sma_goapi_dir}"
86	)
87}
88
89while getopts 'ho:p:-:' optchar; do
90	case "$optchar" in
91		-)
92			case "$OPTARG" in
93				help) usage ;;
94				*) error "invalid argument '$OPTARG'" ;;
95			esac
96			;;
97		h) usage ;;
98		o) sma_goapi_dir=$OPTARG ;;
99		p) sma_proto_dir=$OPTARG ;;
100		*) error "invalid argument '$OPTARG'" ;;
101	esac
102done
103
104validate-inputs
105generate
106