Skip to content

Instantly share code, notes, and snippets.

@mikroskeem
Last active March 31, 2025 21:34
Show Gist options
  • Save mikroskeem/268d08bda34c1cdd1293b1f4691e6890 to your computer and use it in GitHub Desktop.
Save mikroskeem/268d08bda34c1cdd1293b1f4691e6890 to your computer and use it in GitHub Desktop.
# This function helps to set proper Go version for a project, leveraging Go's recent
# GOTOOLCHAIN environment variable support. However, unlike rustup, Go does not attempt
# to download older toolchain versions automatically, and must be forced to do so.
# For example, project specifying `go 1.24` and current toolchain being `go 1.22` does
# download a new version, but not vice-versa.
# However for some projects, having older Go is mandatory, especially with dependencies like:
# - older quic-go, which was tied to a specific Go compiler version
# - other dependencies relying on Go internals
# Requires bash, curl, jq, sed
determine_go_toolchain () {
local gomod="${1:-go.mod}"
local use_toolchain_directive="${2:-1}"
local toolchain_version=""
if (( use_toolchain_directive )); then
toolchain_version="$(sed -n -E '/^toolchain/s/^\w+\s+(go.*)$/\1/p' < "${gomod}")"
fi
if [ -n "${toolchain_version}" ]; then
echo >&2 "using '${toolchain_version}' as specified by '${gomod}'"
else
local go_version
local releases
# fall back to finding a latest patch version for given minor.major
go_version="$(sed -n -E '/^go\s+/s/^go\s+(.+)/\1/p' < "${gomod}")"
echo >&2 "project specifies go version '${go_version}', finding relevant release"
releases="$(curl -s -G -d "mode=json" -d "include=all" 'https://go.dev/dl/')"
toolchain_version="$(jq -cer --arg "wanted" "${go_version}" '[.[] | select(.version | startswith("go\($wanted)")) | .version][0]' <<< "${releases}")"
echo >&2 "using '${toolchain_version}' as resolved from releases"
fi
printf -- '%s' "${toolchain_version}"
}
export GOTOOLCHAIN="$(determine_go_toolchain)"
export GOTOOLCHAIN="$(determine_go_toolchain go.mod 1)"
export GOTOOLCHAIN="$(determine_go_toolchain go.mod 0)"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment