Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Makeover

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.

Add Makeover to a project

Copy the script into your project and make it executable:

cp /path/to/makeover/makeover ./makeover
chmod +x ./makeover
git add makeover

The 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 build

Run the first declared target:

./makeover

You can also name one or more targets:

./makeover clean test

How Buildfile discovery works

Unless 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.

Command line

./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.

Buildfile reference

Variables

Variable names may contain letters, digits, and underscores. They cannot start with a digit:

PYTHON = python3
SOURCE_DIR = src
ENTRYPOINT = $(SOURCE_DIR)/main.py

Reference 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.

Targets and prerequisites

Declare a target and its prerequisites with target: prerequisite ...:

build/app: src/main.c src/app.h
    cc src/main.c -o build/app

Before 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 clean

Each name in .PHONY must also have a target declaration. Target and prerequisite names cannot contain whitespace, colons, or equals signs.

Recipes

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
    pwd

By 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-fail

Any 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.

Documentation and groups

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/app

Targets without a group appear under General.

Limits

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.

Update a vendored copy

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.

About

A GNU Make alternative designed to be user-friendly and have simple syntax

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages