Summary
We began the unit with the excitement of starting something new. However, it's often the case that this excitement fades away quickly, if the project has not been properly cared of.
The guidelines given in this unit are only the very tip of the iceberg of preparing and maintaining a project in a healthy and consistent state. We briefly discussed techniques that apply at the highest, the project level. Project design depends on decisions made at each level. In next units, we go deeper, layer by layer, to learn more about better design choices.
Consistently following the guidelines requires an effort. At times it may seem too much to pay attention to, or too meticulous. However, it pays off in long term, and it always does. One of the best things one can do for their future self is to plan and prepare upfront such that as less as possible changes are required in places which should be set and just work. But that "just work" is, in fact, a consequence of these activities which are often invisible when done, and very noticeable when forgotten, ignored, or neglected.
At the end of the unit it is worth summarising all of the suggestions and recommendations given so far, compiled in one list:
- In general and overall, strive for a good project layout.
- For any kind of project:
- provide files required for the project
- keep the number of root elements at minimum
- keep any level clean and up to date
- don't create artificial hierarchy
- group non-code files by their purpose
- provide the Makefile
- store credentials somewhere else
- For a library:
- provide a good README file
- keep the top-level list of objects of a manageable size
- provide examples
- provide benchmarking information
- For a single application:
- use
cmddirectory for entry points (main.gofiles) - use
bindirectory for binaries
- use
- When working with a monolithic repository, bear in mind the following:
- avoid naively throwing in everything in to one repository
- service-based monorepos may work, but they are harder to maintain long-term
- similarly, entity-focused repositories are especially prone to dependency cycles
- prefer a structured monolithic repository, and ensure that:
- each package is carefully placed in the tree
- utility code is being maintained as own standard library
- there is a sandbox for code with breaking changes
- when even more flexibility is required/desired, consider:
- using nested modules within a single monorepo
- or even using multiple monolithic repositories
- some of which are "simple", single-module monorepos
- and finally, there is always the most flexible option with multiple monorepos composed of nested modules
- When versioning your Go project, remember of these:
- the main branch is usually considered to be the source of truth
- the default branch should be the same as the source of truth
- avoid the directory-based approach to versioning unless you absolutely must
- similarly, there are few reasons for using the simple branch-based approach
- use the branch-based approach with rolling main branch
- When working on code and then preparing a new version, remember to:
- write good commit messages
- use annotated tags
- maintain the changelog, keeping in mind that
- changelog is for people
- there must be a record for each version
- last version comes first in the list
- each release must include the date it's released
- changes should be grouped by the type
- the style and wording should be consistent
- and the information you add to the changelog is relevant.
An insightful reader might have already noticed that there is something common among the guidelines proposed here. The underlying principles for the suggestions in this and next units are basic and simple. Everyone knows about them, but fewer people do actually follow them in real life. As a reminder and a hint, they're listed below:
- Do what needs to be done, and don't be lazy.
- Anything you do, do it at the best level.
- Especially, when nobody is watching.
- Learn and then follow rules.
- Always do your homework.
- Never stop learning.
- Regularly update your understanding of the things you already know.
- Learn something new.
In the next unit, we take a step forward, and introduce guidelines on various aspects of package design in Go.