Development Environment for Go Lang
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
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
goenv
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
system
1.12.12
* 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
/Users/ushio/dev/go/src/github.com/microsoft/<project_name>
$GOPATH
is /Users/ushio/dev/go
. In my .zshrc
export GOPATH="/Users/ushio/dev/go"
export PATH="$GOPATH/bin:$PATH"
ghq
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/github.com/microsoft
$ ghq get git@github.com:microsoft/terraform-provider-azuredevops.git
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
github.com/microsoft/terraform-provider-azuredevops
:
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/github.com/microsoft
$ git clone git@github.com:TsuyoshiUshio/terraform-provider-azuredevops.git
peco
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.
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.
tools.go
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.
Tip
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" github.com/TsuyoshiUshio/foo/cmd/foo
Then run the app.
$ ./foo
Then at the another terminal, see the process number.
$ ps
PID TTY TIME CMD
481 ttys000 0:00.16 /Applications/iTerm.app/Contents/MacOS/iTerm2 --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.
Click the link. You will see the .vscode/settings.json
Add Environment Variables section like this.
Conclusion
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!
Resources
Sample usage of peco with ghq