Last active
January 22, 2026 09:00
-
-
Save mdsohelmia/fa42d8052f581a3d521a3a811b3f4ddd to your computer and use it in GitHub Desktop.
install-go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| msg() { printf '%s\n' "$*"; } | |
| warn() { printf 'β οΈ %s\n' "$*" >&2; } | |
| die() { | |
| printf 'β %s\n' "$*" >&2 | |
| exit 1 | |
| } | |
| # -------- Colors -------- | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' | |
| # -------- Linux only -------- | |
| OS="$(uname -s | tr '[:upper:]' '[:lower:]')" | |
| [ "$OS" = "linux" ] || die "Linux only. Detected: $(uname -s)" | |
| # -------- sudo/root handling -------- | |
| if command -v sudo >/dev/null 2>&1; then | |
| SUDO="sudo" | |
| else | |
| SUDO="" | |
| fi | |
| if [ "$(id -u)" -ne 0 ] && [ -z "$SUDO" ]; then | |
| die "Need root or sudo to auto-install missing commands and install Go to /usr/local." | |
| fi | |
| # -------- detect package manager -------- | |
| detect_pm() { | |
| if command -v apt-get >/dev/null 2>&1; then | |
| echo "apt" | |
| return | |
| fi | |
| if command -v dnf >/dev/null 2>&1; then | |
| echo "dnf" | |
| return | |
| fi | |
| if command -v yum >/dev/null 2>&1; then | |
| echo "yum" | |
| return | |
| fi | |
| if command -v pacman >/dev/null 2>&1; then | |
| echo "pacman" | |
| return | |
| fi | |
| if command -v apk >/dev/null 2>&1; then | |
| echo "apk" | |
| return | |
| fi | |
| if command -v zypper >/dev/null 2>&1; then | |
| echo "zypper" | |
| return | |
| fi | |
| echo "unknown" | |
| } | |
| PM="$(detect_pm)" | |
| [ "$PM" != "unknown" ] || die "No supported package manager found (apt/dnf/yum/pacman/apk/zypper). Install dependencies manually: curl tar awk" | |
| install_pkgs() { | |
| # shellcheck disable=SC2086 | |
| case "$PM" in | |
| apt) | |
| $SUDO apt-get update -y | |
| $SUDO apt-get install -y "$@" | |
| ;; | |
| dnf) | |
| $SUDO dnf install -y "$@" | |
| ;; | |
| yum) | |
| $SUDO yum install -y "$@" | |
| ;; | |
| pacman) | |
| $SUDO pacman -Sy --noconfirm "$@" | |
| ;; | |
| apk) | |
| $SUDO apk add --no-cache "$@" | |
| ;; | |
| zypper) | |
| $SUDO zypper --non-interactive install "$@" | |
| ;; | |
| esac | |
| } | |
| # Map command -> package name(s) per distro family | |
| ensure_cmd() { | |
| local cmd="$1" | |
| if command -v "$cmd" >/dev/null 2>&1; then | |
| return 0 | |
| fi | |
| msg "π§ Missing '$cmd' β installingβ¦" | |
| case "$cmd" in | |
| curl) | |
| case "$PM" in | |
| apt | dnf | yum | pacman | apk | zypper) install_pkgs curl ;; | |
| esac | |
| ;; | |
| tar) | |
| case "$PM" in | |
| apt | dnf | yum | pacman | apk | zypper) install_pkgs tar ;; | |
| esac | |
| ;; | |
| awk) | |
| # awk is usually in gawk (or mawk) depending on distro | |
| case "$PM" in | |
| apt) install_pkgs gawk ;; | |
| dnf | yum) install_pkgs gawk ;; | |
| pacman) install_pkgs gawk ;; | |
| apk) install_pkgs gawk ;; | |
| zypper) install_pkgs gawk ;; | |
| esac | |
| ;; | |
| *) | |
| die "Don't know how to install missing command: $cmd" | |
| ;; | |
| esac | |
| command -v "$cmd" >/dev/null 2>&1 || die "Failed to install '$cmd'. Please install it manually." | |
| } | |
| # -------- ensure prerequisites (auto-install) -------- | |
| ensure_cmd curl | |
| ensure_cmd tar | |
| ensure_cmd awk | |
| # -------- architecture -------- | |
| M="$(uname -m)" | |
| case "$M" in | |
| x86_64 | amd64) ARCH="amd64" ;; | |
| aarch64 | arm64) ARCH="arm64" ;; | |
| i386 | i686) ARCH="386" ;; | |
| *) die "Unsupported architecture: $M" ;; | |
| esac | |
| # -------- shell rc -------- | |
| detect_shell_rc() { | |
| # Check current shell | |
| case "$SHELL" in | |
| */zsh) echo "$HOME/.zshrc" ;; | |
| */fish) echo "$HOME/.config/fish/config.fish" ;; | |
| *) echo "$HOME/.bashrc" ;; | |
| esac | |
| } | |
| SHELL_RC="$(detect_shell_rc)" | |
| INSTALL_DIR="/usr/local" | |
| GO_BIN="$INSTALL_DIR/go/bin" | |
| # -------- latest Go version -------- | |
| msg "π Fetching latest Go version..." | |
| GO_VERSION_FULL="$(curl -fsSL 'https://go.dev/VERSION?m=text' | awk 'NR==1{print; exit}')" | |
| [ -n "$GO_VERSION_FULL" ] || die "Could not determine latest Go version." | |
| # -------- check if already installed -------- | |
| if [ -x "$GO_BIN/go" ]; then | |
| CURRENT_VERSION="$("$GO_BIN/go" version 2>/dev/null | awk '{print $3}')" || CURRENT_VERSION="" | |
| if [ "$CURRENT_VERSION" = "$GO_VERSION_FULL" ]; then | |
| msg "β Go $GO_VERSION_FULL is already installed and up to date" | |
| "$GO_BIN/go" version | |
| exit 0 | |
| fi | |
| msg "π Upgrading from $CURRENT_VERSION to $GO_VERSION_FULL" | |
| else | |
| msg "π¦ Installing Go $GO_VERSION_FULL" | |
| fi | |
| GO_TAR="${GO_VERSION_FULL}.linux-${ARCH}.tar.gz" | |
| URL="https://go.dev/dl/${GO_TAR}" | |
| CHECKSUM_URL="https://go.dev/dl/?mode=json" | |
| msg "" | |
| msg "πΉ OS: linux" | |
| msg "πΉ ARCH: $ARCH" | |
| msg "πΉ Go: $GO_VERSION_FULL" | |
| msg "πΉ URL: $URL" | |
| msg "πΉ RC file: $SHELL_RC" | |
| msg "" | |
| # -------- download & install -------- | |
| TMPDIR="$(mktemp -d)" | |
| trap 'rm -rf "$TMPDIR"' EXIT | |
| cd "$TMPDIR" | |
| msg "β¬οΈ Downloading Go..." | |
| curl -fL --retry 3 --progress-bar -O "$URL" | |
| # -------- checksum verification -------- | |
| msg "π Verifying checksum..." | |
| EXPECTED_SHA256="$(curl -fsSL "$CHECKSUM_URL" | | |
| awk -v fname="$GO_TAR" ' | |
| BEGIN { RS="[{},]"; FS=":" } | |
| /"filename"/ { gsub(/[" ]/, "", $2); file=$2 } | |
| /"sha256"/ { gsub(/[" ]/, "", $2); sha=$2 } | |
| file == fname && sha { print sha; exit } | |
| ')" | |
| if [ -n "$EXPECTED_SHA256" ]; then | |
| ACTUAL_SHA256="$(sha256sum "$GO_TAR" | awk '{print $1}')" | |
| if [ "$EXPECTED_SHA256" = "$ACTUAL_SHA256" ]; then | |
| msg "β Checksum verified" | |
| else | |
| die "Checksum mismatch! Expected: $EXPECTED_SHA256, Got: $ACTUAL_SHA256" | |
| fi | |
| else | |
| warn "Could not fetch checksum, skipping verification" | |
| fi | |
| # -------- verify archive -------- | |
| msg "π Verifying archive..." | |
| tar -tzf "$GO_TAR" >/dev/null || die "Archive verification failed" | |
| # -------- install -------- | |
| msg "π₯ Installing to $INSTALL_DIR..." | |
| $SUDO rm -rf "$INSTALL_DIR/go" | |
| $SUDO tar -C "$INSTALL_DIR" -xzf "$GO_TAR" | |
| # -------- PATH and environment update (idempotent) -------- | |
| msg "π§ Configuring environment..." | |
| setup_shell_env() { | |
| local rc_file="$1" | |
| local is_fish=false | |
| [[ "$rc_file" == *"fish"* ]] && is_fish=true | |
| touch "$rc_file" | |
| if [ "$is_fish" = true ]; then | |
| # Fish shell syntax | |
| local go_path_entry="set -gx PATH $GO_BIN \$PATH" | |
| local gopath_entry='set -gx GOPATH $HOME/go' | |
| local gobin_entry='set -gx PATH $GOPATH/bin $PATH' | |
| if ! grep -q "set -gx PATH $GO_BIN" "$rc_file" 2>/dev/null; then | |
| printf '\n# Go installation\n%s\n%s\n%s\n' "$go_path_entry" "$gopath_entry" "$gobin_entry" >>"$rc_file" | |
| msg "β Environment updated in $rc_file" | |
| else | |
| msg "πΉ Environment already configured in $rc_file" | |
| fi | |
| else | |
| # Bash/Zsh syntax | |
| local go_path_entry="export PATH=\"${GO_BIN}:\$PATH\"" | |
| local gopath_entry='export GOPATH="$HOME/go"' | |
| local gobin_entry='export PATH="$GOPATH/bin:$PATH"' | |
| if ! grep -q "export PATH=\"${GO_BIN}" "$rc_file" 2>/dev/null; then | |
| printf '\n# Go installation\n%s\n%s\n%s\n' "$go_path_entry" "$gopath_entry" "$gobin_entry" >>"$rc_file" | |
| msg "β Environment updated in $rc_file" | |
| else | |
| msg "πΉ Environment already configured in $rc_file" | |
| fi | |
| fi | |
| } | |
| setup_shell_env "$SHELL_RC" | |
| # -------- create GOPATH directory -------- | |
| mkdir -p "$HOME/go/bin" "$HOME/go/src" "$HOME/go/pkg" | |
| # -------- verify installation -------- | |
| msg "" | |
| msg "==================================================" | |
| msg " Go Installation Complete" | |
| msg "==================================================" | |
| msg "" | |
| "$GO_BIN/go" version | |
| msg "" | |
| msg "π Go binary: $GO_BIN/go" | |
| msg "π GOPATH: \$HOME/go" | |
| msg "π Shell RC: $SHELL_RC" | |
| msg "" | |
| msg "βΉοΈ Restart your shell or run:" | |
| msg " source \"$SHELL_RC\"" | |
| msg "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment