Skip to content

Instantly share code, notes, and snippets.

@leehinman
Last active July 6, 2023 14:24
Show Gist options
  • Save leehinman/6f9a0a75ad515d8b036e0934c6a4356a to your computer and use it in GitHub Desktop.
Save leehinman/6f9a0a75ad515d8b036e0934c6a4356a to your computer and use it in GitHub Desktop.
direnv handle .go-version with gvm

Problem Statement

We require specific go tool chain version for reproducible builds and sanity in dealing with CI. Unfortunately, versions can change frequently, which means you have to change your go tool chain frequently.

Solutions

Historically (since 90s at least) Environment Modules have been used for handling different tool chains. But it requires TCL/TK and I'm done with TCL/TK.

direnv is a golang project that handles loading and unloading environment variables depending on the current directory. So lets see if we can get that to work for us.

Demo

Requirements

  • direnv (most linux distros have package, brew has package for mac)
  • gvm by Andrew Kroh: used to download go tool chains
  • cat, grep, cut & tr

Hook direnv into your shell

Bash

Add the following to the end of ~/.bashrc

eval "$(direnv hook bash)"

zsh

Add the following at the end of ~/.zshrc

eval "$(direnv hook zsh)"

Create a direnv function

edit ~/.config/direnv/direnvrc

gvm_dot_go_version() {
    if ! has gvm; then
	return
    fi
    local path=${1:-}
    if [[ -z $path ]]; then
	path=$PWD/.go-version
    elif [[ -d $path ]]; then
	path=$path/.go-version
    fi
    watch_file "$path"
    if ! [[ -f $path ]]; then
	return
    fi
    go_root=$(gvm $(cat $path) | grep GOROOT | cut -f 2 -d " " | cut -f 2 -d "=" | tr -d '"')
    path_add GOROOT "$go_root"
    PATH_add "$go_root/bin"
}

Create .envrc file

echo "gvm_dot_go_version" >> ~/src/beats/.envrc

allow direnv

This is a security step. Because a .envrc file might be in a repo, this allows you to inspect the file before it automatically gets sourced.

cd ~/src/beats
direnv: error /Users/hinman/src/beats/.envrc is blocked. Run `direnv allow` to approve its content

direnv allow

Optional, Ignore the .envrc file

echo ".envrc" >> ~/src/beats/.git/info/exclude

Editor Integration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment