Development Environment for Go Lang

Tsuyoshi Ushio
6 min readOct 28, 2019
ghq with peco

After coming back to the Go Lang programming after long break, I encounter a lot of issues like IntelliSense, debug, code navigation doesn’t work. The lining result is different with CI and my local machine. So I re-think about the development environment for Go Lang with my mac.

Go Versioning

The root cause of the weird behaviors were the version of go lang and tools. I’d like to choose the version depend on the project. In this case, we have some cool tools.


anyenv helps us to install **env implementation. I can install goenv directory, however, if you want to use others like rubyenv , anyenv might handy.

$ brew install anyenv
$ anyenv init
$ anyenv install --init
$ anyenv install goenv
$ exec $SHELL -l


If you want to switch the version of the Go, you can user goenv . You can switch and install any go versions.

$ goenv install 1.12.12
$ echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.zshenv
$ echo 'export PATH="$GOENV_ROOT/bin:$PATH"' >> ~/.zshenv
$ exec $SHELL -l
$ goenv versions
goenv versions
* 1.13.1 (set by /Users/ushio/.anyenv/envs/goenv/version)
$ goenv local 1.12.12 // the command creates .go-version on current dir. You can use global for global settings.
$ go version
go version go1.12.12 darwin/amd64

Directory Structure

Go directory structure has very deep directory structure under $GOPATH . My current directory structure is


$GOPATH is /Users/ushio/dev/go . In my .zshrc

export GOPATH="/Users/ushio/dev/go"
export PATH="$GOPATH/bin:$PATH"


Sometimes, you might feel that it is painful to go to the ohter go project directory. In this case, ghq is useful.

$ brew install ghq

Before cloning target project, you can go to the directory.

$ cd /Users/ushio/dev/go/src/
$ ghq get

Set the source directory that is managed by ghq.

git config --global ghq.root /Users/ushio/dev/go/src

This tool manage the go projects of yours.

$ ghq list

To clone a different directory, you just go to the target directory and clone it by git clone This is the example for clone fork repository (TsuyoshiUshio/terraform-provider-azuredevops), but want to clone under (microsoft/terraform-provider-azuredevops). ghq can detect this project.

$ cd /Users/ushio/dev/go/src/
$ git clone


Peco is an interactive filtering tool. With ghq it is very useful to move other projects.

$ brew install peco

Add this script to your .zshrc . This script is taken from a cool blog post.

Hit control + ] You can select the target project, then it goes to the target directory from anywhere.

ghq and peco integration

Enable Debugging for Unit/Acceptance Testing, and binary

I assume you are using VSCode. You need to install Go extension. For more details. See here.

VSCode with Go extension

Go to the target directory then open VSCode.

$ code . 

Go to the VSCode, then type Command + Shift + p select Go install /update tools Select all tools to update. All tools installed to the target $GOPATH/bin directory. Old version’s tool causing a lot of problem. Be careful if you are using the same versions with others and CI.

Update all tools


If you want to use the same version for go tools and using Go Module, you can use tools.go strategy. You can refer this page for more details. This is an example for manage stringer. You can add others.


Now you can have the IntelliSense, code navigation, and document so on. Old version could cause a problem. Double check the version. (I did. )


Unit/Acceptance Test with Debugging

Add .vscode/launch.json on your project.

NOTE: The launch.json doen’t paste correctly. I add the gist link in here.

Also, write .vscode/private.env for setting Environment Variables for testing.


Debug works.


You might see `could not launch process: decoding dwarf section info at offset 0x0: too short`. In my case, after update the all go tools above, restart of VSCode is required. Then it has gone. I also see it when it uses old version.

Binary Debugging

You might want to debug actual binary. In this case, Configure settings.json like this below. You can attach the debugger to a process.

Then modify code. We need time to attach debugger, so you can add some code to wait for a while in somewhere in your code.

time.Sleep(60 * time.Second())

When you compile add this flag. This flag means do not optimize code when compile it. It required to attach the debugger.

$ go build -gcflags="all=-N -l"

Then run the app.

$ ./foo 

Then at the another terminal, see the process number.

$ ps
481 ttys000 0:00.16 /Applications/ --server login -fp ushio
486 ttys000 0:03.26 -zsh
87235 ttys000 0:00.01 ./foo
73543 ttys002 0:06.97 /bin/zsh -l
24077 ttys004 0:00.60 -zsh
86796 ttys005 0:00.54 /bin/zsh -l

then modify the launch.json with change the processId as the target process. This case is 87235 . Then start debug on your VSCode.

Environment Variables for integrated terminal

I wanted to add Environment Variables for VSCode terminal. It depends on a project. Go to Preferences > Settings then click Workspace and search terminal.integrated.env You will find Edit in settings.json link. You can configure this settings both on global (User) and local on your workspace (Workspace). In case of workspace, you will see .vscode/settings.json in your workspace.

integrated terminal settings

Click the link. You will see the .vscode/settings.json Add Environment Variables section like this.

Environment Variables for integrated terminal settings.


Now, I’m satisfy the development environment settings for me. Enjoy coding with Go Lang.

Special Thanks

Thank you for sharing a lot of insights. My master sensei. He is super cool developer.

Also team lead Nick shared a lot of tips for me. Thank you Nick!


Sample usage of peco with ghq

Japanese resources