#!/bin/bash
# set -e: Exit immediately if a command exits with a non-zero status.
# set -u: Treat unset variables as an error.
# set -o pipefail: Return the exit status of the last command in the pipe that failed.
# For more information, see the GNU Bash manual:
# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
set -euo pipefail
##############################################
# OS & Architecture Detection
##############################################
# Detect the operating system.
UNAME_S=$(uname -s)
case "$UNAME_S" in
Linux*) GO_OS="linux" ;;
Darwin*) GO_OS="darwin" ;;
MINGW*|MSYS*|CYGWIN*) GO_OS="windows" ;;
*) echo "Unsupported OS: $UNAME_S" && exit 1 ;;
esac
# Detect system architecture.
UNAME_M=$(uname -m)
case "$UNAME_M" in
x86_64) GO_ARCH="amd64" ;;
aarch64|arm64) GO_ARCH="arm64" ;;
*) echo "Unsupported architecture: $UNAME_M" && exit 1 ;;
esac
##############################################
# Dependency Checks and Installation
##############################################
# Function to install a package on Linux with available package managers.
install_package_linux() {
PACKAGE_NAME="$1"
if command -v apt-get >/dev/null 2>&1; then
sudo apt-get update && sudo apt-get install -y "$PACKAGE_NAME"
elif command -v yum >/dev/null 2>&1; then
sudo yum install -y "$PACKAGE_NAME"
elif command -v dnf >/dev/null 2>&1; then
sudo dnf install -y "$PACKAGE_NAME"
else
echo "Error: Could not determine a suitable package manager. Please install $PACKAGE_NAME manually." && exit 1
fi
}
# Check if curl is installed; if not, attempt to install it.
if ! command -v curl >/dev/null; then
echo "curl is not installed. Attempting to install curl..."
if [ "$GO_OS" = "linux" ]; then
install_package_linux curl
elif [ "$GO_OS" = "darwin" ]; then
if command -v brew >/dev/null; then
brew install curl
else
echo "Error: Homebrew is not installed. Please install curl manually from https://curl.se/." && exit 1
fi
elif [ "$GO_OS" = "windows" ]; then
echo "Automatic installation of curl is not supported on Windows. Please install curl manually from https://curl.se/download.html." && exit 1
else
echo "Unsupported OS for automatic curl installation." && exit 1
fi
if ! command -v curl >/dev/null; then
echo "Error: curl installation failed. Please install curl manually." && exit 1
fi
fi
echo "curl is installed."
# Check if jq is installed; if not, attempt to install it.
if ! command -v jq >/dev/null; then
echo "jq is not installed. Attempting to install jq..."
if [ "$GO_OS" = "linux" ]; then
install_package_linux jq
elif [ "$GO_OS" = "darwin" ]; then
if command -v brew >/dev/null; then
brew install jq
else
echo "Error: Homebrew is not installed. Please install jq manually from https://stedolan.github.io/jq/." && exit 1
fi
elif [ "$GO_OS" = "windows" ]; then
echo "Automatic installation of jq is not supported on Windows. Please install jq manually from https://stedolan.github.io/jq/download/." && exit 1
else
echo "Unsupported OS for automatic jq installation." && exit 1
fi
if ! command -v jq >/dev/null; then
echo "Error: jq installation failed. Please install jq manually." && exit 1
fi
fi
echo "jq is installed."
##############################################
# Determine Archive Extension
##############################################
# Choose archive extension based on OS.
if [ "$GO_OS" = "windows" ]; then
EXT="zip"
else
EXT="tar.gz"
fi
##############################################
# Retrieve Latest Go Release Information
##############################################
# The Go downloads page supports different query parameter values for the "mode":
# - mode=json : Returns the release information in JSON format (what we're using here)
# - mode=html : Returns the standard HTML page
# For additional details, see: https://go.dev/dl/
echo "Fetching latest Go version..."
RELEASE_JSON=$(curl -sL "https://go.dev/dl/?mode=json")
LATEST=$(echo "$RELEASE_JSON" | jq -r '.[0].version') # e.g., "go1.20.4"
if [ -z "$LATEST" ]; then
echo "Failed to determine the latest Go version." && exit 1
fi
echo "Latest Go version: $LATEST"
##############################################
# Download and Install Go
##############################################
# Construct the file name and download URL.
FILE="${LATEST}.${GO_OS}-${GO_ARCH}.${EXT}"
URL="https://go.dev/dl/${FILE}"
# Using curl with the -O flag to download the file from the provided URL.
# The -O option saves the file with its original filename as provided by the server.
# For more details on curl's command-line options, see: https://curl.se/docs/manpage.html
echo "Downloading ${FILE} from ${URL}..."
curl -O "$URL"
# Define installation directory.
if [ "$GO_OS" = "windows" ]; then
# Assumes Git Bash on Windows; adjust this install path if necessary.
INSTALL_DIR="/c/Go"
else
INSTALL_DIR="/usr/local/go"
fi
echo "Installing Go to ${INSTALL_DIR}..."
# Remove any previous installation.
if [ "$GO_OS" = "windows" ]; then
rm -rf "$INSTALL_DIR"
else
sudo rm -rf "$INSTALL_DIR"
fi
# Extract the archive.
if [ "$EXT" = "tar.gz" ]; then
if [ "$GO_OS" = "windows" ]; then
echo "Extraction on Windows: Please use an unzip tool manually." && exit 1
else
# Using tar with the following options:
# -C /usr/local: Change to the /usr/local directory before extraction.
# -x: Extract the archive.
# -z: Uncompress the archive using gzip.
# -f "$FILE": Specify the archive file to extract.
# For more details on tar options, see: https://www.gnu.org/software/tar/manual/html_section/Standard-options.html
sudo tar -C /usr/local -xzf "$FILE"
fi
elif [ "$EXT" = "zip" ]; then
# For Windows, using unzip via Git Bash/MSYS – adjust as necessary.
unzip "$FILE" -d "$INSTALL_DIR"
fi
# Clean up the downloaded file.
rm "$FILE"
# Update PATH for Linux/macOS if necessary.
if [ "$GO_OS" != "windows" ]; then
if ! grep -q "/usr/local/go/bin" ~/.profile ; then
echo "export PATH=\$PATH:/usr/local/go/bin" >> ~/.profile
echo "Added Go to your PATH in ~/.profile. Restart your session or run 'source ~/.profile' to update your environment."
fi
fi
echo "Go installation completed."
if [ "$GO_OS" != "windows" ]; then
/usr/local/go/bin/go version
else
echo "Please add ${INSTALL_DIR}/bin to your PATH and run 'go version' to verify the installation on Windows."
fi
- company: Google
url: https://blog.google/products/development-suite/go-20-released/
- company: Microsoft
url: https://blogs.microsoft.com/developer/2020/08/25/using-go-to-build-high-performance-applications/
- company: Shopify
url: https://www.shopify.com/engineering/using-go-to-improve-performance
- company: Netflix
url: https://netflixtechblog.com/going-go-with-go-2/
- company: Zerodha
url: https://zerodha.com/tech-blog/leveraging-go-for-high-performance-trading-platform/