Common Project Layout, version 0
This is a tongue-in-cheek “draft” for Common Project Layout, version 0. It will probably never become any sort of adopted standard but I think it is good to share some ideas that I had while working on this.
Definition
Common Project Layout (CPL) is a set of good practices for structuring medium-to-large monorepo-like software repositories.
Benefits
CPL helps with code organization. It can be a good “framework” (in a very loose meaning of this word) to modularize product components.
It can make large repositories easier to work with and understand.
Upfront limitations
CPL is strictly designed for “hosting” software and all the non-code assets are left up to the engineers to decide their location.
For example branding assets could be put into the Branding
top-level directory, but on the other hand are we sure they will stay the same with major version?
Since we can agree that we consider documentation “producers” (not the produced artifacts) to be code we could also acknowledge that some assets could have their own versioned subproject.
Requirements
Versioning
CPL requires that the software is versioned inside directories whose names include the version. Recommended pattern is to name directories vMAJOR
where MAJOR
is either the current tagged major version or one that will be if no tags exist. It is also recommended to group the vMAJOR
directories under one common directory, for example Source
.
Subprojects
The vMAJOR
could theoretically contain all the source code mixed together but it should be grouped and organized by their purpose.
Subproject is defined as a directory inside a versioned (vMAJOR
) directory. “Versioned subproject” and “subproject” are synonymous to CPL.
To mark the purpose of a subproject, whether it is to be used as a helper or as a “container” for source that is actually exposed (or binaries created from it), it should be adequately named.
For helpers name does not matter but for source subproject it should be prefixed by project name.
For example we could have this layout:
1 2 3 4 5 6 7 8 |
Source/ └── v1/ ├── Makefile ├── VERSION ├── admin/ ├── make/ ├── my-project-app/ └── my-project-util/ |
In the above example my-project-app
and my-project-lib
are the source subproject and admin and make are subproject that are there only to help in building, managing and deploying the actual source subprojects.
At the and it is up to the engineer to choose if something is considered a source subproject. For example: If we have a helper subproject that all it does is hold Docker / Podman files for creating a development container what should we name it? As of now I had named them PROJECT-dev-container
.
Recommendations
Make and admin
I think it is a good practice for each vMAJOR
to have a Makefile, or equivalent in other build system, that will call scripts inside vMAJOR/admin
directory that each take care of some small / specific task.
For example the vMAJOR/Makefile
recipe for build
can call admin/build_my_project_app.py
and admin/build_my_project_lib.py
. Each those scripts would call the “real” build system specific to the subproject they act upon.
VERSION file
It is nice to have a VERSION
file in the vMAJOR
directory. It can be reused by build tools and also to show what was the last version worked upon inside vMAJOR
, the latest git tag can either be put on different major version or simply not be there yet.
References
See those repositories for referencing the CPL layout: