Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
I began my journey in Golang a few months ago when I decided that JavaScript was getting a little too unwieldy for my liking. TypeScript solved some problems but it made JavaScript as verbose as Java. Anyhow, I have been writing JavaScript for close to half a decade and I thought itâd be nice to learn a different language with a different mental model and development paradigms.
Starting out, my biggest issues I had with Golang was the lack of tooling and the by-now infamous GOPATH requirement. The latter is a matter of taste by Googleâs engineers, but something could be done about the former.
I had been searching for tools that would allow me to replicate the ease of which I could run my Golang services in development, as I could my Node.js based applications, and I found none that fit my needs, and so I decided to create one.
It runs using Docker which solves environment and version management issues, and uses Makefiles for tooling, and it comes in the form of an image that basically contains simple shell scripts which assists in:
- Bootstrapping a project
- Live-reloading of tests and applications
- Auto-updating of dependencies
- Statically linked binary compilation
- Packaging into a scratch Docker image
I call it Go Develop and you can find it at my GitHub repository at:
What follows is a short post on what I went through, and how this project solves the problems I faced while initiating myself into the world of Golang.
For reference as to the environment Iâm trying to replicate, I use the following tools with JavaScript to improve my productivity:
- NVM for managing of Node versions
- Yarn for managing dependencies
- Nodemon for live-reloading of my application and tests
- ESLint + Prettier for automatic code formatting and live-linting
- Docker multi-stage builds for packaging and deploying applications
Boostrapping a Go Project
When it comes to bootstrapping any project, it usually comes down to a few things:
- A task runnerâââAfter going through the source codes of some projects in Go, it seemed that Makefiles were the generally accepted way to go.
- A dependency managerâââPrior to Go 1.11, there was Glide, Dep and Godep. Go 1.11 introduced go mod which seems to be the way to go.
- A way to manage versionsâââIt seems like the generally accepted way to do this is via Git tags. Since go mod is kind of new, I stuck with using Git tags.
- A way to release into productionâââThe Go applications Iâve dealt with are generally cloud native, and packaging is usually done via Docker containers.
The recommended way to use Go Develop is hence via a Makefile, with an init script that provisions a directory for development and release. It also includes scripts to bump your Git tags in a semver-compliant manner.
Managing of Go Versions
In almost every modern language thereâs always the customary xVM (where x is the first letter of the language/runtime one is using). Ruby has RVM, Node has NVM, and Go has GVM. However, GVM modifies your GOPATH. While I didnât mind this at first, I soon encountered issues when working with different projects using the linkthis sub-command of GVM. Thatâs when I began researching on the issue, and⊠Itâs apparently an ongoing gripe of many:
Leave the $GOPATH alone please · Issue #189 · moovweb/gvm
Using Docker, we wonât need to even install Golang on your machine. Simply reference the version of Golang we wish to have and get started! (Go Develop begins at 1.11.2, if earlier 1.11.x versions are needed, Iâll add support for themâââdrop me an Issue on GitHub).
As a nice side-effect, this also means you no longer need to configure GOPATH on your local machine as long as itâs properly defined in the image.
Auto-Formatting of Code
Like many who work on web-related software, I call Visual Studio Code my choice of IDE, and it already had a surprisingly decent plugin, just search for âgoâ in your marketplace!
The Intellisense works wonders when the Go Language Server is turned on and the auto-formatting by gofmt gets the job done pretty well. I actually found it better than the ESLint + Prettier combinationâââbut thatâs possibly because Go itself enforces the formatting before itâll compile.
Live Reloading of Application
After using nodemon, itâs hard to go back to manual reloads. The Golang community has itâs own offerings such as Realize, which I went with for awhile in my professional work. However, it couldnât run tests together with the main service, which was cumbersome if youâd like tests to be running while you write code and break things. I still had to run go test manually.
Then go mod came about in 1.11 and it broke Realize. The live-reload wouldnât even kick in once there was a go.mod file. The issue is still ongoing (and it doesnât happen just for Windows):
Cannot do `--run` with go1.11 using go mod under windows. · Issue #217 · oxequa/realize
In Go Develop, I used inotifywait to watch for all *.go files and do a build/update deps/kill/run cycle on file changes. However, this meant that it wouldnât run on OS X or Windows, but since Docker abstracts away the operating system layer, this is a non-issue, and which is why running Go applications from a container made sense for me.
Live Reloading of Tests
Existing toolings didnât do justice to live-reloading of tests either. GoConvey sounded greatâââexcept I didnât want to have to switch to a browser to view my test results. Iâm more of a CLI person. GoConvey had a CLI mode for auto-reloading of tests, however, failures would not dump the error logs to the terminal which was annoying to me.
Go Develop uses the same inotifywait mechanism to run tests as it does with the application. More info can be found in the documentation.
Auto-Updating of Dependencies
Another issue I had with other live-reload tools was that after I did an import on something new, I had to switch my terminal and install the new package separately.
While this wasnât possible in the past because different projects used different dependency managers, the release of Go 1.11 saw the official inclusion of go mod which seems to be the way to go (ha-ha).
With Go Develop, the use of go mod is enforced which simplifies issues that other dependency managers face such as version selection. go mod also includes backward compatibility with other dependency managers which convinced me it was the choice to go with.
Binary Compilation and Production Packaging
Most applications written in Go seem to be destined for packaging as a Docker image. In my line of work, I had to do the same. So why not build something that includes a build mechanism with batteries included?
Go Develop was written with the above in mind. Running the build script inside the image results in a statically linked binary that can used in a scratch Docker image (a Docker image without a specified operating system), which reduces the size of the image dramatically.
If static linking and containerisation isnât your cup of tea, Go Develop also allows you to run builds for your own operating system by providing the GOOS and GOARCH environment variables. Check out the documentation on how to do this.
Last Words
I hope this project benefits others as it has myselfâââitâs licensed with the permissive MIT license so you can do pretty much whatever you want with it.
If it did help you in some way, do me a favour and star/watch the repository to indicate that youâve found it beneficial in your developer journey. Feedback is very much welcome too (Iâm still a newbie in Go and any improvements to the tooling Iâve done would help!)
You can find the Docker image on DockerHub at:
Thanks for reading!
Lastly, my team at work is expanding and if youâre based in Singapore and would like to work with me professionally, feel free to hit me up at joseph_goh@tech.gov.sg (:
Cheers đ
Building a Development Environment for Golang with Docker was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.