mirror of https://github.com/hashicorp/consul
337 lines
9.5 KiB
Bash
Executable File
337 lines
9.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Copyright (c) HashiCorp, Inc.
|
|
# SPDX-License-Identifier: BUSL-1.1
|
|
|
|
|
|
readonly SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})"
|
|
readonly SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
|
|
readonly SOURCE_DIR="$(dirname "$(dirname "${SCRIPT_DIR}")")"
|
|
readonly FN_DIR="$(dirname "${SCRIPT_DIR}")/functions"
|
|
|
|
source "${SCRIPT_DIR}/functions.sh"
|
|
|
|
unset CDPATH
|
|
|
|
set -euo pipefail
|
|
|
|
usage() {
|
|
cat <<-EOF
|
|
Usage: ${SCRIPT_NAME} [<options ...>]
|
|
|
|
Description:
|
|
Installs various supporting Go tools.
|
|
|
|
Options:
|
|
-protobuf Just install tools for protobuf.
|
|
-lint Just install tools for linting.
|
|
-codegen Just install tools for codegen.
|
|
-pre-commit Just install pre-commit.
|
|
-h | --help Print this help text.
|
|
EOF
|
|
}
|
|
|
|
function err_usage {
|
|
err "$1"
|
|
err ""
|
|
err "$(usage)"
|
|
}
|
|
|
|
function main {
|
|
while test $# -gt 0
|
|
do
|
|
case "$1" in
|
|
-protobuf )
|
|
proto_tools_install
|
|
return 0
|
|
;;
|
|
-lint )
|
|
lint_install
|
|
return 0
|
|
;;
|
|
-codegen )
|
|
codegen_install
|
|
return 0
|
|
;;
|
|
-pre-commit )
|
|
pre_commit_install
|
|
return 0
|
|
;;
|
|
-h | --help )
|
|
usage
|
|
return 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# ensure these tools are installed
|
|
tools_install
|
|
}
|
|
|
|
function proto_tools_install {
|
|
local protoc_gen_go_version
|
|
local protoc_gen_go_grpc_version
|
|
local buf_version
|
|
local mog_version
|
|
local protoc_go_inject_tag_version
|
|
local mockery_version
|
|
|
|
mockery_version="$(make --no-print-directory print-MOCKERY_VERSION)"
|
|
protoc_gen_go_version="$(grep google.golang.org/protobuf go.mod | awk '{print $2}')"
|
|
protoc_gen_go_grpc_version="$(make --no-print-directory print-PROTOC_GEN_GO_GRPC_VERSION)"
|
|
mog_version="$(make --no-print-directory print-MOG_VERSION)"
|
|
protoc_go_inject_tag_version="$(make --no-print-directory print-PROTOC_GO_INJECT_TAG_VERSION)"
|
|
buf_version="$(make --no-print-directory print-BUF_VERSION)"
|
|
protoc_gen_go_binary_version="$(make --no-print-directory print-PROTOC_GEN_GO_BINARY_VERSION)"
|
|
|
|
# echo "go: ${protoc_gen_go_version}"
|
|
# echo "mog: ${mog_version}"
|
|
# echo "tag: ${protoc_go_inject_tag_version}"
|
|
|
|
install_versioned_tool \
|
|
'mockery' \
|
|
'github.com/vektra/mockery/v2' \
|
|
"${mockery_version}" \
|
|
'github.com/vektra/mockery/v2'
|
|
|
|
install_versioned_tool \
|
|
'buf' \
|
|
'github.com/bufbuild/buf' \
|
|
"${buf_version}" \
|
|
'github.com/bufbuild/buf/cmd/buf'
|
|
|
|
install_versioned_tool \
|
|
'protoc-gen-go' \
|
|
'google.golang.org/protobuf' \
|
|
"${protoc_gen_go_version}" \
|
|
'google.golang.org/protobuf/cmd/protoc-gen-go'
|
|
|
|
install_versioned_tool \
|
|
'protoc-gen-go-grpc' \
|
|
'google.golang.org/grpc/cmd/protoc-gen-go-grpc' \
|
|
"${protoc_gen_go_grpc_version}" \
|
|
'google.golang.org/grpc/cmd/protoc-gen-go-grpc'
|
|
|
|
install_versioned_tool \
|
|
protoc-gen-go-binary \
|
|
'github.com/hashicorp/protoc-gen-go-binary' \
|
|
"${protoc_gen_go_binary_version}" \
|
|
'github.com/hashicorp/protoc-gen-go-binary'
|
|
|
|
install_versioned_tool \
|
|
'protoc-go-inject-tag' \
|
|
'github.com/favadi/protoc-go-inject-tag' \
|
|
"${protoc_go_inject_tag_version}" \
|
|
'github.com/favadi/protoc-go-inject-tag'
|
|
|
|
install_versioned_tool \
|
|
'mog' \
|
|
'github.com/hashicorp/mog' \
|
|
"${mog_version}" \
|
|
'github.com/hashicorp/mog'
|
|
|
|
install_local_protoc_generator "${SOURCE_DIR}/internal/tools/protoc-gen-consul-rate-limit"
|
|
|
|
install_local_protoc_generator "${SOURCE_DIR}/internal/resource/protoc-gen-resource-types"
|
|
|
|
install_local_protoc_generator "${SOURCE_DIR}/internal/resource/protoc-gen-json-shim"
|
|
|
|
install_local_protoc_generator "${SOURCE_DIR}/internal/resource/protoc-gen-deepcopy"
|
|
|
|
return 0
|
|
}
|
|
|
|
function lint_install {
|
|
local golangci_lint_version
|
|
golangci_lint_version="$(make --no-print-directory print-GOLANGCI_LINT_VERSION)"
|
|
|
|
local gci_version
|
|
gci_version="$(make --no-print-directory print-GCI_VERSION)"
|
|
|
|
install_unversioned_tool \
|
|
'lint-consul-retry' \
|
|
'github.com/hashicorp/lint-consul-retry@master'
|
|
|
|
install_unversioned_tool \
|
|
'enumcover' \
|
|
'github.com/reillywatson/enumcover/cmd/enumcover@master'
|
|
|
|
install_versioned_tool \
|
|
'golangci-lint' \
|
|
'github.com/golangci/golangci-lint' \
|
|
"${golangci_lint_version}" \
|
|
'github.com/golangci/golangci-lint/cmd/golangci-lint'
|
|
|
|
install_versioned_tool \
|
|
'gci' \
|
|
'github.com/daixiang0/gci' \
|
|
"${gci_version}" \
|
|
'github.com/daixiang0/gci'
|
|
}
|
|
|
|
function codegen_install {
|
|
deepcopy_install
|
|
copywrite_install
|
|
}
|
|
|
|
function deepcopy_install {
|
|
local deep_copy_version
|
|
deep_copy_version="$(make --no-print-directory print-DEEP_COPY_VERSION)"
|
|
|
|
install_versioned_tool \
|
|
'deep-copy' \
|
|
'github.com/globusdigital/deep-copy' \
|
|
"${deep_copy_version}" \
|
|
'github.com/globusdigital/deep-copy'
|
|
}
|
|
|
|
function copywrite_install {
|
|
local copywrite_version
|
|
copywrite_version="$(make --no-print-directory print-COPYWRITE_TOOL_VERSION)"
|
|
|
|
install_versioned_tool \
|
|
'copywrite' \
|
|
'github.com/hashicorp/copywrite' \
|
|
"${copywrite_version}" \
|
|
'github.com/hashicorp/copywrite'
|
|
}
|
|
|
|
function pre_commit_install {
|
|
# if already installed make sure the hook is also installed
|
|
if command -v "pre-commit" &>/dev/null; then
|
|
# Not to be confused with installing the tool, this installs
|
|
# the git hook locally (.git/hooks/pre-commit) which pre-commit
|
|
# uses as a vector to run checks on `git commit`. This hook is
|
|
# generated based on the local environment hence not source
|
|
# controlled.
|
|
pre-commit install
|
|
return 0
|
|
fi
|
|
|
|
# Install options based on https://pre-commit.com/#installation
|
|
if command -v "brew" &>/dev/null; then
|
|
brew install pre-commit && pre-commit install
|
|
return 0
|
|
fi
|
|
|
|
# Try python regardless of platform (mac, linux, etc)
|
|
if command -v "pip3" &>/dev/null; then
|
|
pip3 install pre-commit && pre-commit install
|
|
return 0
|
|
fi
|
|
|
|
# Can't disappoint the linux/debian folks
|
|
if command -v "apt" &>/dev/null; then
|
|
sudo apt-get install -yq pre-commit && pre-commit install
|
|
return 0
|
|
fi
|
|
|
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
echo "ERROR: Install homebrew from https://brew.sh/ so that pre-commit (https://pre-commit.com) can be installed."
|
|
return 1
|
|
fi
|
|
|
|
echo "ERROR: Install python3 and pip3 so that pre-commit (https://pre-commit.com) can be installed."
|
|
return 1
|
|
}
|
|
|
|
function tools_install {
|
|
lint_install
|
|
proto_tools_install
|
|
codegen_install
|
|
pre_commit_install
|
|
copywrite_install
|
|
|
|
return 0
|
|
}
|
|
|
|
function install_unversioned_tool {
|
|
local command="$1"
|
|
local install="$2"
|
|
|
|
if ! command -v "${command}" &>/dev/null ; then
|
|
echo "installing tool: ${install}"
|
|
go install "${install}"
|
|
else
|
|
echo "skipping tool: ${install} (installed)"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
function install_versioned_tool {
|
|
local command="$1"
|
|
local module="$2"
|
|
local version="$3"
|
|
local installbase="$4"
|
|
|
|
local should_install=
|
|
local install_reason=
|
|
local got
|
|
local vgot
|
|
local vneed
|
|
|
|
local expect="${module}@${version}"
|
|
local install="${installbase}@${version}"
|
|
|
|
if [[ -z "$version" ]]; then
|
|
err "cannot install '${command}' no version selected"
|
|
return 1
|
|
fi
|
|
|
|
if [[ "$version" = "@DEV" ]]; then
|
|
if ! command -v "${command}" &>/dev/null ; then
|
|
err "dev version of '${command}' requested but not installed"
|
|
return 1
|
|
fi
|
|
echo "skipping tool: ${installbase} (using development version)"
|
|
return 0
|
|
fi
|
|
|
|
if command -v "${command}" &>/dev/null ; then
|
|
mod_line="$(go version -m "$(which "${command}")" | grep '\smod\s')"
|
|
act_mod=$(echo "${mod_line}" | awk '{print $2}')
|
|
if [[ "$module" != "$act_mod" ]]; then
|
|
err "${command} is already installed by module \"${act_mod}\" but should be installed by module \"${module}\". Delete it and re-run to re-install."
|
|
return 1
|
|
fi
|
|
|
|
got="$(echo "${mod_line}" | grep "${module}" | awk '{print $2 "@" $3}')"
|
|
if [[ "$expect" != "$got" ]]; then
|
|
should_install=1
|
|
install_reason="upgrade"
|
|
fi
|
|
|
|
# check that they were compiled with the current version of go
|
|
set +o pipefail
|
|
vgot="$(go version -m $(which "${command}") | head -n 1 | grep -o 'go[0-9.]\+')"
|
|
vneed="$(go version | head -n 1 | awk '{print $3}')"
|
|
set -o pipefail
|
|
if [[ "$vgot" != "$vneed" ]]; then
|
|
should_install=1
|
|
install_reason="go toolchain upgrade"
|
|
fi
|
|
else
|
|
should_install=1
|
|
install_reason="install"
|
|
fi
|
|
|
|
if [[ -n $should_install ]]; then
|
|
echo "installing tool (${install_reason}): ${install}"
|
|
go install "${install}"
|
|
else
|
|
echo "skipping tool: ${install} (installed)"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function install_local_protoc_generator {
|
|
local src=$1
|
|
echo "installing tool $(basename $src) from local source"
|
|
pushd -- "$src" > /dev/null
|
|
go install
|
|
popd > /dev/null
|
|
}
|
|
|
|
main "$@"
|
|
exit $?
|