The recipes

This walk is one of several through the project. The website of the first, cheesecracker, lists them all.

We follow the justfile of cheesecracker, the API server of the Cheese App.

just is a command runner. A project keeps its commands in a file named justfile, and gives each one a short name. Each named command is a recipe. just NAME runs a recipe, just alone lists them, and just --show NAME prints one.

A recipe can take more words after its name, as in just test tests/unit, and it can run several lines of commands. The program just is small, and its authors wrote it in Rust. Older projects often use a program named make for the same job.

The recipes keep the long commands of the project in one place. Everyone on the project runs them by the same short names. Later, the project also runs in Docker, which runs a program in a container, a sealed copy of a small Linux system. The dev image of the project holds just and the other tools, so Docker runs the same recipes. This tutorial takes the recipes out of the whole tutorial of cheesecracker, one at a time, as each one comes in. Every recipe here is in the justfile of the project cheesecracker, in the folder of its code.

The code is in the repository rahuldave/cheesecracker on GitHub. When the project is done, the server's code is in src/api-service/api/, and its tests are in tests/unit/, tests/integration/ and tests/system/. pyproject.toml and uv.lock list the Python packages that the project needs. justfile holds its recipes, short names for the commands of the project. Dockerfile holds the instructions that build its two Docker images, the run image of the server and the dev image with every tool.

The repository keeps every saved version of the project, in the order of the whole tutorial of cheesecracker. That tutorial has many parts, and this tutorial follows some of them.

On the website, each page covers one part of the tutorial. The top of the page links to the code as it is when the part starts. The bottom links to the code as it is when the part ends.

We make the project in moves. A move is one small change, made by one patch or by one command. You make each move, and the page checks your files against it.

Some changes of the whole tutorial are not in this one. After such a gap, the next section says what those changes did, and starts from the code that they left. It first runs just setup, which installs the packages of that code.

How the walk is cut

Each page is one part, a stage of the project. At the end of every part, the project works. It runs, and its checks pass. A tutorial cuts each part into moves, one small change each, and a move is a section of its page. Between two moves, the code can be broken on purpose. For example, a move adds a test that fails, and the next move makes it pass. A part never ends broken.

Working is not the same as right. A part can end with code that runs and passes its checks. That code can still be wrong for the problem, such as a mask that leaves out the wrong rows. Such a mistake is part of the story, and a later part finds it and fixes it.

The code where a part starts and where it ends has a tag on GitHub, such as step-00, or is a commit between two tags. The top of each page says where its part starts, and the bottom says where it ends, each with a link to that code.

There are two ways to read this tutorial. Both have the same parts, in the same order.

Each part ends with a section called What changed. It lists every file that the part changes, with a link to the file, and then the whole diff of each file, folded. A lockfile and a binary file have a link alone. The text above it explains the change. In Build it yourself, What changed is what you check your files against.

In Build it yourself, a file that a command makes says which command. A diff that is open is a patch. Apply it with the command in the text, or make the same change in your editor.

Read the tutorial

Each change explained, with the code to look at.

Build it yourself

Every command to run and every change to make by hand, to make the project yourself.

Get the project

You build the project in a clone of your own, on a branch mine that starts where this walk starts. Run the commands of these pages in its top folder.

git clone https://github.com/rahuldave/cheesecracker
cd cheesecracker
git switch -c mine cf50a6ef5045

Then add the command git check, which compares your files with the project's after each move, and leaves what git add has staged as it was.

git config alias.check '!f() { i="$(git rev-parse --git-path check-index)" && { cp -p "$(git rev-parse --git-path index)" "$i" 2>/dev/null || rm -f "$i"; } && export GIT_INDEX_FILE="$i" && git add -A && git diff --cached --stat "$1"; }; f'

The parts