Recently I have been learning Go and wanted to write this guide to help other JavaScript/Node developers who want to learn Go save some headache. Basically in this article we are going to learn the equivalents of npm
, nvm
, npm install -g
, npm install package -S
, and npm install
.
TL;DR
goenv
: similar tonvm
, used to manage installed Go versionsgovendor
: similar tonpm
, used to manage dependencies for projectsgovendor fetch <package>
: similar tonpm install <package> -S
, used to install a package for a projectgovendor sync
: similar tonpm install
, used to install all the packages defined in thevendor.json
filegovendor init
: similar tonpm init -y
, used to create thevendor
andvendor/vendor.json
file.vendor/vendor.json
: similar topackage.json
, used to specify the dependencies for a projectgo get <package>
: similar tonpm i <package> -g
go install .
: similar tonpm i -g
, used to compile a project and add a binary globally accessible
Overview
In this article we are going to do the following:
- Install
goenv
to manage Go versions - Set up a Go Workspace
- Set up PATHS
- Make a simple project and use
govendor
to manage dependencies
Installing goenv
goenv
is similar to nvm
in that it allows you to install different versions of Go. The best way to install goenv
is to clone it from the repo into ~/.goenv
:
git clone https://github.com/syndbg/goenv.git ~/.goenv
After cloning the repo, add the following to your ~/.bash_profile
file to set up goenv
:
export GOENV_ROOT="$HOME/.goenv"
export PATH="$GOENV_ROOT/bin:$PATH"
export PATH="$HOME/.goenv/shims:$PATH"
# keep this line empty (1) we will fill this in the next section
# keep this line empty (2) we will fill this in the next section
eval "$(goenv init -)"
Then, restart your terminal window, or open a new terminal window and run the following:
goenv install --list
If goenv
is setup properly, you should see an output with all the Go versions available. As of the time of writing this article, Go 1.9.4 is the latest version available, so we are going to install that:
goenv install 1.9.4
After the installation is complete, run the following to set 1.9.4 as the global version
goenv global 1.9.4
goenv rehash
Then run the following to make sure that Go is set up properly:
go env
go version
In the output, make sure that the GOROOT
is set properly:
GOROOT="~/.goenv/versions/1.9.4"
The GOROOT
should be set to ~/.goenv/versions/<current-version-using/
Set up Workspace
Go projects follow a certain folder structure and convention which are collectively referred to as a Workspace. By default the Workspace is set to ~/go
but we are going to set it to a custom path ~/mygo
. So go ahead and create that folder:
mkdir ~/mygo
Now, we have to add two entries to our ~/.bash_profile
to set GOPATH
and add GOPATH/bin
to the list global system binaries:
export GOPATH="$HOME/mygo" # <-- (1) SET GOPATH to our workspace in ~/mygo
export PATH=$PATH:$(go env GOPATH)/bin # <-- (2) Add ~/mygo/bin to the path resolved globally
Now the bottom of your ~/.bash_profile
should look like the following:
export GOENV_ROOT="$HOME/.goenv"
export PATH="$GOENV_ROOT/bin:$PATH"
export PATH="$HOME/.goenv/shims:$PATH"
export GOPATH="$HOME/mygo" # <-- (1) SET GOPATH to our workspace in ~/mygo
export PATH=$PATH:$(go env GOPATH)/bin # <-- (2) Add ~/mygo/bin to the path resolved globally
eval "$(goenv init -)"
Now that we have configured our Workspace we are ready to play with some code.
Making a Simple Go Project
Install govendor
First we are going to install the govendor
package to help us manage our dependencies:
go get -u github.com/kardianos/govendor
After running that you should see the following folders created in your Workspace:
├── bin
│ ├── govendor
├── pkg
│ └── darwin_amd64
│ ├── github.com
└── src
├── github.com
├── kardianos
└── pkg
Now if you run govendor -version
you should see an output telling you the version of govendor
that's installed. If you see an output you should be good to go to the next section.
Create a Hello World Project
Our Hello World project is going to make an http call to a public endpoint and log the results to the console. Run the following to set up the project and the necessary files:
mkdir -p ~/mygo/src/github/myusername/hello-go && cd $_
govendor init
touch .gitignore .go-version app.go
After running the above commands one after the other, you should have a folder structure like the following:
~/mygo/src/github/myusername/hello-go
├── .gitignore
├── .go-version
├── app.go
└── vendor
└── vendor.json
Open the .go-version
and add the following line:
1.9.4
This will indicate that this project will be using Go version 1.9.4. Then open your .gitignore
file and add the following to ignore the vendor folder except the vendor.json
file:
.gitignore
vendor/*
!vendor/vendor.json
Next, we are going to use govendor
to "install" gorequest
. Gorequest is an http client that simplifies calling API endpoints that speak JSON:
govendor fetch github.com/parnurzeal/gorequest
After running the above, you should see that the dependencies have been added to the vendor/vendor.json
file and the packages have been added to the vendor
folder. After installing gorequest
, we are going to update the app.go
to make a GET request and show the results in the console:
app.go
package main
import(
"fmt"
"github.com/parnurzeal/gorequest"
)
func main() {
request := gorequest.New()
url := "https://jsonplaceholder.typicode.com/posts/1"
resp, _, errs := request.Get(url).End()
fmt.Println(resp, errs)
}
Then run go run app.go
and you should see the result of the GET request in the console. And if you want the binary to be added to your $GOPATH/bin
folder, run go install
. After running that you should be able to run hello-go
anywhere on your system by simply invoking the binary hello-go
.
Conclusion
When I started playing with Go I was assuming that the setup would take me 10 minutes, but I wanted a setup similar to Node's nvm and npm. I could have simply installed the Go binary and not worried about anything, but I wanted to learn how to set up a project that could potentially be deployed to production with proper dependency and Go version management. Installing goenv
and a global version of Go with goenv
was pretty easy but I got confused with the way that goenv
handles GOPATH and GOROOT variables. I assumed that once I use goenv
I don't have to worry about the GOPATH
values. But even if you use goenv
you should still manage your GOPATH
and your Go workspace by yourself. I'm still exploring goenv
and I'm curious to know how you can do something similar to npm
and nvm
where you switch your Node version and all the globally installed packages would respect that change.