1#!/usr/bin/env bash
2
3set -e
4
5readonly PROTOC_VER="3.12.3"
6readonly PROTOC_ARCHIVE="protoc-${PROTOC_VER}-linux-$( uname -m ).zip"
7readonly PROTOC_URL="https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VER}/${PROTOC_ARCHIVE}"
8
9readonly PROTOC_GEN_GO_VER="1.25.0"
10readonly PROTOC_GEN_GO_ARCHIVE="protoc-gen-go.v${PROTOC_GEN_GO_VER}.linux.amd64.tar.gz"
11readonly PROTOC_GEN_GO_URL="https://github.com/protocolbuffers/protobuf-go/releases/download/v${PROTOC_GEN_GO_VER}/${PROTOC_GEN_GO_ARCHIVE}"
12
13readonly PROTOC_GEN_GO_GRPC_VER="v1.30.0"
14readonly PROTOC_GEN_GO_GRPC_REPO_URL="https://github.com/grpc/grpc-go"
15
16readonly GRPC_ECOSYSTEM_VER="v1.14.6"
17readonly GRPC_ECOSYSTEM_URL="https://github.com/grpc-ecosystem/grpc-gateway/releases/download/${GRPC_ECOSYSTEM_VER}"
18
19readonly PROTOC_GEN_SWAGGER_BIN="protoc-gen-swagger-${GRPC_ECOSYSTEM_VER}-linux-$( uname -m )"
20readonly PROTOC_GEN_SWAGGER_URL="${GRPC_ECOSYSTEM_URL}/${PROTOC_GEN_SWAGGER_BIN}"
21
22readonly PROTOC_GEN_GRPC_GATEWAY_BIN="protoc-gen-grpc-gateway-${GRPC_ECOSYSTEM_VER}-linux-$( uname -m )"
23readonly PROTOC_GEN_GRPC_GATEWAY_URL="${GRPC_ECOSYSTEM_URL}/${PROTOC_GEN_GRPC_GATEWAY_BIN}"
24
25readonly DEFAULT_DEST="/usr/local"
26
27get() {
28    local url="$1"
29    local dest="$2"
30
31    if [[ -w $dest ]]
32    then
33        wget --quiet "$url" -O "$dest"
34    else
35        sudo wget --quiet "$url" -O "$dest"
36    fi
37}
38
39install_bin() {
40    local dest_dir="${1}/bin"
41    local source_bin="$2"
42    local source_url="$3"
43    local target_bin="$4"
44    local auth
45
46    if [[ ! -w $dest_dir ]]
47    then
48        auth="sudo"
49    fi
50
51    [ -d "${dest_dir}" ] || $auth mkdir -p "${dest_dir}"
52
53    get "$source_url" "${dest_dir}/$source_bin"
54    $auth chmod +x "${dest_dir}/$source_bin"
55    $auth ln -s -f "${dest_dir}/${source_bin}" "${dest_dir}/$target_bin"
56
57    echo "installed $source_bin to ${dest_dir}/${target_bin}"
58}
59
60install_protoc() {
61    local dest="$1"
62    local output="${dest}/protoc-${PROTOC_VER}"
63    local tmpfile auth
64
65    tmpfile="$( mktemp )"
66    get "$PROTOC_URL" "$tmpfile"
67
68    if [[ ! -w $dest ]]
69    then
70        auth="sudo"
71    fi
72
73    $auth unzip -qq -o -d "$output" "$tmpfile"
74    rm -rf "$tmpfile"
75    [ -d "${dest}/bin" ] || $auth mkdir "${dest}/bin"
76    $auth ln -s -f "${output}/bin/protoc"  "${dest}/bin/protoc"
77
78    echo "installed protoc v$PROTOC_VER to ${dest}/bin/protoc"
79}
80
81install_protoc_gen_go() {
82    local dest="$1"
83    local tmpfile auth
84
85    tmpfile="$( mktemp )"
86    get "$PROTOC_GEN_GO_URL" "$tmpfile"
87
88    if [[ ! -w $dest ]]
89    then
90        auth="sudo"
91    fi
92
93    $auth tar -xzf "$tmpfile" -C "${dest}"
94    rm -rf "$tmpfile"
95    [ -d "${dest}/bin" ] || $auth mkdir "${dest}/bin"
96    $auth ln -s -f "${dest}/protoc-gen-go"  "${dest}/bin/protoc-gen-go"
97
98    echo "installed protoc-gen-go v${PROTOC_GEN_GO_VER} to ${dest}/bin/protoc-gen-go"
99}
100
101# TODO Switch to binary once https://github.com/grpc/grpc.io/issues/298 is resolved
102install_protoc_gen_go_grpc() {
103    local parent_dir="$( go env GOPATH )/src/github.com/grpc"
104    local checkout_dir="${parent_dir}/grpc-go"
105
106    rm -rf ${checkout_dir}
107    mkdir -p ${parent_dir}
108    cd ${parent_dir}
109    git clone --quiet -c advice.detachedHead=false -b ${PROTOC_GEN_GO_GRPC_VER} ${PROTOC_GEN_GO_GRPC_REPO_URL}
110    cd grpc-go/cmd/protoc-gen-go-grpc
111    go install .
112
113    echo "installed protoc-gen-go-grpc v$PROTOC_VER"
114}
115
116install_protoc_gen_swagger() {
117    local dest="$1"
118
119    install_bin \
120        "$dest"\
121        "$PROTOC_GEN_SWAGGER_BIN"\
122        "$PROTOC_GEN_SWAGGER_URL"\
123        "protoc-gen-swagger"
124}
125
126install_protoc_gen_grpc_gateway() {
127    local dest="$1"
128
129    install_bin \
130        "$dest"\
131        "$PROTOC_GEN_GRPC_GATEWAY_BIN"\
132        "$PROTOC_GEN_GRPC_GATEWAY_URL"\
133        "protoc-gen-grpc-gateway"
134}
135
136main() {
137    local dest="${1:-$DEFAULT_DEST}"
138
139    install_protoc "$dest"
140    install_protoc_gen_go "$dest"
141    install_protoc_gen_go_grpc
142    install_protoc_gen_swagger "$dest"
143    install_protoc_gen_grpc_gateway "$dest"
144}
145
146main "$@"