mazel Concepts¶
Following bazel’s concepts:
Workspace¶
The “Workspace” is the root of the monorepo.
Contains a WORKSPACE.toml
file, which is currently empty. Contains one or more Packages.
Package¶
“Packages” are subdirectories that contain a specific service, library, tool, etc.
If we used a multi-repo approach, these would likely align to individual projects / repositories. Contains a BUILD.toml file, which specifies the runtime as well as a Makefile.
Under the hood, we utilize well-designed Makefiles that call out to language-specific dependency and packaging tools (see Runtimes).
Sample Monorepo Structure¶
A typical monorepo may have the following structure splitting libraries and services:
WORKSPACE.toml
libs/
js/
common/
BUILD.toml
package.json
py/
common/
BUILD.toml
pyproject.toml
services/
frontend/
BUILD.toml
package.json
backend/
BUILD.toml
pyproject.toml
tools/
deployer/
BUILD.toml
go.mod
docker/
python/
BUILD.toml
In this example, there are 4 “Packages”: //libs/common
, //services/frontend
, //services/backend
, //tools/deployer
Target¶
A “Target” refers to a Makefile rule to execute.
For example if our Makefile
has a format
rule:
format:
black .
.PHONY: format
If we are inside the package (at the package’s root or a subdirectory), we can execute the this target via mazel run :format. This effectively is the same as running make format, but becomes more powerful when we can run this make command from any path in our Workspace.
See Makefile Best Practices to ensure consistent workspace-wide target names.
Labels¶
In the spirit of bazel’s labels, we can specify packages and targets using a //dir/package:target
syntax.
The //
specifies the Workspace root, dir/package
is the path to the package, and :target
indicates the target in the Makefile to execute. The syntax also supports relative paths and partial paths.
//dir/package:target # Full label
dir/package:target # Relative path label
package:target # Relative path label, if current
# directory is `dir`
:target # Target-only label, useful if
# inside `dir/package`
//dir:target # Partial path label, that would run
# `:target` in all packages under `dir`
mazel run typically requires the :target
specifier. However some commands automatically default to a target (e.g. :test for mazel test).
Examples:
mazel test //libs/py/common # Runs `make test` for the common library
mazel test # Runs tests for any packages under the current directory
mazel format //libs/py # Code formats all code under libs/py
mazel run //tools/docker/base:image # Builds the base docker image
This label syntax is designed to make it quick to run actions in the current package, while simple enough to run actions for other packages in the repo.