Search code examples
gonixnixos

Nix: go package in --pure mode still pointing to host's GOPATH


I'm trying to run a nix shell with the go package to test a go program. However, to ensure reproducability, I do not want the go in nix-shell to point back to any host related path or info. So, I was advised to use the --pure flag in the command.

My final command looks like this:

$ nix-shell --pure -p go

Once the shell is live, I run go env and I see this:

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/HOSTUSERNAME/.cache/go-build"
GOENV="/home/HOSTUSERNAME/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/HOSTUSERNAME/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/HOSTUSERNAME/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/nix/store/a7875alzpnr46z6mv4ssymfdwmvr6xbq-go-1.19.4/share/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/nix/store/a7875alzpnr46z6mv4ssymfdwmvr6xbq-go-1.19.4/share/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.19.4"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/run/user/1000/go-build3633664660=/tmp/go-build -gno-record-gcc-switches"

I was expecting to install my Go project in a reproducible way without using the host's inherited GOPATH and other related environment variables.

Is there way to completely detach the host system's dependencies by Nix's go package installed in the shell and then test the Go Project?


Solution

  • Even when the environment variables GOPATH, GOENV, GOMODCACHE, &c. are completely unset, go env and related tools synthesize default values relative to $HOME.

    Thus, if you want to test on a regular basis that your project doesn't have hidden dependencies on your home directory, you should wrap its build in a Nix derivation; assuming you're on a platform where Nix supports sandboxing, and that this feature is enabled, this will cause that build to be done in a sandbox with no access to your home directory.

    See gomod2nix and more generally the Go entry on nixos.wiki for guidance on building a derivation to wrap your program's build.


    Also, note that nix-shell --pure doesn't create shells that are pure in every sense of the world: There's still a dependency on nixpkgs coming from your local channels. If you want to control that, you'll want a shell.nix or flake.nix that pins a specific nixpkgs revision.