Go mandates code to be organized on the filesystem in a certain way—the organization has to be at the highest level in terms of a workspace. While there are general recommendations to have one workspace for all projects, in practical situations, I have found it much more scalable to have one workspace per project; for example, consider the situation of two projects using a common dependency, with a different version (more on that in the next section, third-party dependencies.
Here is the recommended high-level structure for the code:
- bin: This directory contains the executables; that is, the output of the compiler.
- pkg: This folder is for the package objects.
- <package>: A folder for each of the top-level packages that make the components of the project.
- vendor: This folder hosts third-party dependencies. There will be more on this in the following section, third-party libraries.
- Makefile: This makes it easier to organize various tasks such as compilation, linting, tests, and also stage code. This again is described in more detail in the next section, third- party libraries.
- scripts: Various scripts including DB provisioning/migrations.
- Main driver: The main file(s) that drive the components and control the life cycle of top-level objects.
This is how a typical Golang workspace looks:
├── Makefile ├── README.md ├── api ├── bin ├── db ├── lib ├── scheduler ├── scrapper.go ├── tests └── vendor ├── pkg └── src ├── github.com │ ├── fatih │ │ └── structs │ ├── influxdata │ │ └── influxdb │ ├── jasonlvhit │ │ └── gocron │ ├── magiconair │ │ └── properties │ ├── mattn │ │ └── go-isatty │ ├── mitchellh │ │ └── mapstructure │ ├── olivere │ │ └── elastic │ ├── pkg │ │ └── errors │ ├── sirupsen │ │ └── logrus │ ├── spf13 │ │ ├── afero │ │ ├── cast │ │ ├── jwalterweatherman │ │ ├── pflag │ │ └── viper │ ├── uber-go │ │ └── atomic
The GOPATH environment variable specifies the location of your workspace. It defaults to a directory named go inside your home directory. If you would like to work in a different location, you will need to set GOPATH to the path to that directory with a fallback to the Go home directory. The following section shows you how to do this in detail.