Makeover is a small build runner that you commit to your repository. Its Buildfile syntax borrows the useful basics from Make, but it does not try to be compatible with every Make feature.
The whole program is one executable Python script: makeover. It
has no third-party dependencies, does not use the network, and does not need a
global install. Keeping the script in your repository means that developers and
CI run the same build tool.
Makeover runs on macOS and Linux. It expects a python3 interpreter and sends
recipe commands to /bin/sh.
Copy the script into your project and make it executable:
cp /path/to/makeover/makeover ./makeover
chmod +x ./makeover
git add makeoverThe script can live in a subdirectory too:
your-project/
├── Buildfile
└── scripts/
└── makeover
In this layout, you can run ./scripts/makeover from the project root or
./makeover from the scripts directory. Either command finds the Buildfile at
the root.
Add a Buildfile:
PYTHON = python3
.PHONY: all test clean
[group: Checks]
# Run all project checks
all: test
# Run the test suite
test:
$(PYTHON) -m unittest discover -s tests -v
[group: Utilities]
# Remove generated files
clean:
rm -rf buildRun the first declared target:
./makeoverYou can also name one or more targets:
./makeover clean testUnless you pass -f or --file, Makeover searches for the nearest Buildfile.
It starts in the current directory and walks up through its parents. If that
does not find one, it repeats the search from the directory that contains the
makeover script. Recipes run from the directory where the selected Buildfile
lives.
The filename is case-insensitive, and separators do not matter. Makeover strips
non-alphanumeric characters and converts the result to lowercase. If the result
is buildfile, the file matches. These names all work:
Buildfile
buildfile
build-file
bUildfile
b_u_i_l_d_f_i_l_e
If the same directory has more than one match, Makeover stops and lists the conflicting files.
./makeover [target ...]
./makeover -f path/to/file [target ...]
./makeover --file path/to/file [target ...]
./makeover -l | --list
./makeover -v | --verbose [target ...]
./makeover -h | --help
The first target in the Buildfile is the default. If you name several targets, they run from left to right. A shared prerequisite runs only once during that invocation.
--list prints the available targets, their documentation, and their groups. It
does not run any recipes.
Build and up-to-date messages prefixed with [Makeover] are hidden by default.
Pass -v or --verbose to show them. This flag does not affect recipe commands,
warnings, or errors.
Use -f PATH or --file PATH to select an exact file and skip discovery. The
filename does not have to resemble Buildfile. A relative path starts from the
directory where you invoked Makeover, but recipes still run from the directory
that contains the chosen file. --file=PATH works as well.
There is no global configuration, command-line variable override, self-update command, or version command.
Variable names may contain letters, digits, and underscores. They cannot start with a digit:
PYTHON = python3
SOURCE_DIR = src
ENTRYPOINT = $(SOURCE_DIR)/main.pyReference a Makeover variable with $(NAME). Expansion is recursive, so a value
may refer to another variable declared later in the file. Values from the
Buildfile take precedence over environment variables. If the Buildfile does not
define a name, Makeover checks the environment. An undefined variable or a
reference cycle is an error.
Regular shell variables pass through unchanged:
show-home:
echo $HOME
echo ${HOME}Write $$ to pass a literal dollar sign to the shell. For example, shell
command substitution is written as $$(command) in a recipe.
Declare a target and its prerequisites with target: prerequisite ...:
build/app: src/main.c src/app.h
cc src/main.c -o build/appBefore running a recipe, Makeover walks the prerequisite graph. A prerequisite that is not another target must exist as a file. Missing files, duplicate targets, dependency cycles, and malformed declarations stop the build.
A regular target runs when its file is missing, a prerequisite is newer, or it depends on a phony or non-file target. Otherwise the target is up to date. That status is printed only in verbose mode.
Declare workflow targets as phony so that a file with the same name cannot stop them from running:
.PHONY: test cleanEach name in .PHONY must also have a target declaration. Target and
prerequisite names cannot contain whitespace, colons, or equals signs.
Indent recipe lines with spaces or a tab. Each line gets a fresh /bin/sh -c
process, so cd, exported variables, and other shell state do not carry to the
next line:
.PHONY: example
example:
cd subdirectory
pwdBy default, Makeover prints each command before running it. Prefix a line with
@ to hide the command, or with - to continue if it fails. You can combine
the two prefixes in either order:
quiet:
@echo "only the command output is shown"
-rm optional-file
@-command-that-may-failAny other command failure stops the build. Recipes can use three automatic variables:
| Variable | Value |
|---|---|
$@ |
Current target |
$< |
First prerequisite, or an empty string |
$^ |
All prerequisites separated by spaces |
Makeover inserts these values directly into the shell command. Quote them where needed.
Comments directly above a target become its description in
./makeover --list. Put related targets into a named group with
[group: Name]:
[group: Release]
# Build the distributable archive
package: build/app
tar -czf app.tar.gz build/appTargets without a group appear under General.
Makeover does not support pattern or implicit rules, includes, conditionals, Make functions, parallel jobs, persistent recipe shells, task arguments, Windows commands, or full Makefile compatibility.
There is no published minimum Python version. Compatibility is best effort, and the script sticks to the standard library while avoiding newer syntax where practical.
Copy the latest makeover script over the one in your project, review the diff,
and commit it. The script has no embedded release number, so your project's Git
history records when the vendored copy changed.
Makeover is licensed under the MIT License.