Creating a new Go Project
Introduction #
If you just want to test some code, then the Golang Playground is perfect. For anything more involved, you should create a project containing your code, configuration, and dependencies.
If you still need to install the go binary, please refer to Installing Go.
The command to create a project is:
| |
In Go, projects are called modules. Modules ideally live in a source control repository like Github, Gitlab, or Bitbucket, which are then referred to by their complete repository name.
For example, if your git repository is github.com/gerritjvv/mynewproject, the command is:
| |
This is the preferred way to create modules (projects) in Go and makes using modules as dependencies easy.
You will notice that the go command created a go.mod file for you.
Now you are ready to write your code:
Place the main.go file in the same directory as the go.mod file.
| |
Then type
| |
to see the output
| |
And that is it; you have created a Go project (module).
Anatomy of a project #
All you need to create a Go module (apart from code) is a directory and a go.mod file.
The go.mod file tells Go the module name, the minimum compiler version and any dependencies the module requires.
The go.mod file, at a minimum, contains two lines:
| |
For example, if we ran go mod init github.com/gerrrittjvv/myrepo, and your compiler version was 1.21.4, the go.mod
file would look like:
| |
Module Path (GO ROOT) #
In many programming languages, you can group your source files into packages(also called namespaces or modules). In Go, they are called packages, and modules refer to the whole library, which is made up of packages. This may be confusing if you come from Python, JavaScript, Rust, Swift, Ruby, or Haskell.
The module path or ROOT is where Go will look when one code file “imports” another one that lives in a different
package.
The root of a module, by default, is the folder where the go.mod file resides.
For versions of Go older than 1.11, you will need to set the GOPATH
and GOROOT environment variables.
Dependencies #
The preferred way to add dependencies to a module is by using the go get command.
For example, to use the gopkg.in/yaml.v3 module in our code, we need to run the below command in the root directory of
our module.
| |
This will create a require entry in our go.mod file, which will then look as below:
| |
From this moment, we can use the yaml dependency by importing it:
| |
And then refer to packages in the dependency using the last part of the path (except for any “.” suffix); here we would
use yaml.<Any function or type>.
For example:
| |
Building, Formatting Testing and Linting #
Just being able to run a project isn’t enough in most cases, and soon you would want to run tests, check for errors using linters and automate running several of these commands
Building a project is best left to either a small number of automation scripts or a proper build tool.
In the Go community, there isn’t one prevalent tool. The most common are Make files or Bash scripts.
Below, I give an overview of the commands you need and briefly explain each.
Overview of commands
Here is a list of commands to run during a complete build, excluding the linting, which is something you need to first, choose.
| |
go mod downloadThis command ensures that all the dependencies have been downloaded locally. You need to do this step before compiling.go fmtThis command runs the Go formatter on each source file and updates the file as needed.go vetThis is Go’s built-in linting tool and checks for common errors that are not compile errors.go mod tidyThis removes any dependencies that are not used.go testruns any tests in your*_test.gofiles.go buildThis command compiles and creates a single binary from your source code.
Linting #
This is the easiest and most powerful productivity hack you can add to your project. Linters come in all shapes and sizes and the best is to use a lint aggregator that runs several different linters in parallel.
I am going to show you how to setup GolangCI-Lint, but you can also look at Awesome-Go-Linters, choose the linter or linters that best fit your project needs.
GolangCI - Lint #
First, install the linter by running:
| |
Execute it by running the below command from your project root directory:
| |
Apart from your linter of choice, you would want to run Go’s default linter, which is go vet ./...; for more
information, see https://pkg.go.dev/cmd/vet.
In my projects, I run go vet and golangci-lint one after the other.
Formatting #
To avoid having style and formatting wars, the creators of Go have provided us with a tool that formats our code to what is considered idiomatic.
Running go fmt ./... in our module folder will search for each of our *.go source files and format them correctly.
It is convenient to run this command
from our IDEAs before we commit.
Testing #
Tests are in separate *_test.go files in the same folder as the code it is testing.
For example, If you want to test code in binarytree.go, you would have a file binarytree_test.go, go test ./..
will
see this file and run the tests inside it.
Building #
You can run go build ./... from the module directory to compile and build your code into a single binary.
Before building, ensure you have all the dependencies downloaded by running go mod download.
The build sequence is:
| |
Summary #
Go provides a single " go " tool to build, test, format and manage dependencies for Go projects.
Projects are called modules, and the go mod <sub> command is used to create modules and manage dependencies.
As for managing the build in a Go project, it is worthwhile to spend time on getting the project build and layout
correct.
Too many developers want to skip this part and go straight to the code, only to trip over a mess later.
The part I have yet to cover in this long blog post is using some standard build tools with Go. Please see Building Go for ready-to-use scripts and code.



