Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Unlock the full potential of your Makefiles.

makefile2doc is a CLI tool that turns your raw Makefiles into clear, categorized, and visual documentation.

The Problem

Makefiles are powerful, but they often become “Black Boxes” as projects grow:

  • The “Bus Factor”: Often, only the author knows all the available commands.
  • Partial Onboarding: New developers usually learn just the 2 or 3 commands needed to start, missing out on powerful utility scripts.
  • Cryptic Syntax: Reading a raw Makefile requires mentally parsing bash syntax, which is inefficient.

The Solution

Treat your Makefile as the Single Source of Truth. By adding simple comments (The Convention), you generate a MAKEFILE.md that is always up-to-date with your code.

Why use it?

  • 🧠 Kill the “Makefile Anxiety”: No more scrolling through 300 lines of obscure Bash at 2 AM just to find the right deploy command.
  • 🚀 Instant Onboarding: Give new developers a “Cheat Sheet” that actually makes sense, letting them use the project before they fully understand its internals.
  • 🤖 AI Optimization: Provides clean context for LLMs, saving tokens and preventing hallucinations (see AI Context).

Why NOT use it?

  • 🦀 You don’t like Rust for some reason.
  • 😨 You are afraid to re-open your Makefile because it currently works and you don’t want to jinx it.

Real-World Example

The best way to understand makefile2doc is to see it in action. Below is the Result (the generated Markdown) and the Input (the raw Makefile) from our internal test suite.

Makefile Documentation

Auto-generated by makefile2doc

Cheat Sheet

CommandCategoryDescription
make upDevelopment EnvironnementStart the full development environment (Docker)
make downDevelopment EnvironnementStop all containers
make logsDevelopment EnvironnementShow live logs for all services
make shell-backDevelopment EnvironnementOpen a shell inside the PHP container (Laravel)
make shell-frontDevelopment EnvironnementOpen a shell inside the Node.js container
make shell-dbDevelopment EnvironnementOpen a shell inside the PostgreSQL container
make install-backSetup & InitializationInstall backend (Composer)
make install-frontSetup & InitializationInstall frontend (NPM) dependencies
make installSetup & InitializationRun both backend and frontend installations
make migrateDatabaseRun database migrations
make seedDatabaseReset the DB and run seeds (Test data)
Warning: This deletes all data!
make test-backCode QualityRun unit tests (Pest/PHPUnit)
make lint-frontCode QualityLint frontend code (ESLint)
make lint-backCode QualityLint backend code (PHP-CS-Fixer dry-run)
make fix-frontCode QualityFix frontend code style and format
make fix-backCode QualityFix backend code style
make lintCode QualityRun all linters (front & back)
make fixCode QualityFix all code style issues (front & back)
make build-frontDeploymentCompile Frontend assets (Vite/Mix)
make deployDeploymentDeploy to Production
1. Build frontend assets
2. Optimize Laravel cache
3. Run migrations force

Workflow Graph

flowchart LR
    subgraph Development_Environnement[Development Environnement]
        up(up)
        down(down)
        logs(logs)
        shell-back(shell-back)
        shell-front(shell-front)
        shell-db(shell-db)
    end
    style Development_Environnement fill:transparent,stroke-dasharray: 5 5
    classDef cat0 fill:#E1F5FE,stroke:#01579B,stroke-width:2px,color:#000;
    class up cat0
    class down cat0
    class logs cat0
    class shell-back cat0
    class shell-front cat0
    class shell-db cat0
    subgraph Setup_&_Initialization[Setup & Initialization]
        install-back(install-back)
        install-front(install-front)
        install(install)
    end
    style Setup_&_Initialization fill:transparent,stroke-dasharray: 5 5
    classDef cat1 fill:#E8F5E9,stroke:#1B5E20,stroke-width:2px,color:#000;
    class install-back cat1
    class install-front cat1
    class install cat1
    subgraph Database[Database]
        migrate(migrate)
        seed(seed)
    end
    style Database fill:transparent,stroke-dasharray: 5 5
    classDef cat2 fill:#FFF3E0,stroke:#E65100,stroke-width:2px,color:#000;
    class migrate cat2
    class seed cat2
    subgraph Code_Quality[Code Quality]
        test-back(test-back)
        lint-front(lint-front)
        lint-back(lint-back)
        fix-front(fix-front)
        fix-back(fix-back)
        lint(lint)
        fix(fix)
    end
    style Code_Quality fill:transparent,stroke-dasharray: 5 5
    classDef cat3 fill:#F3E5F5,stroke:#4A148C,stroke-width:2px,color:#000;
    class test-back cat3
    class lint-front cat3
    class lint-back cat3
    class fix-front cat3
    class fix-back cat3
    class lint cat3
    class fix cat3
    subgraph Deployment[Deployment]
        build-front(build-front)
        deploy(deploy)
    end
    style Deployment fill:transparent,stroke-dasharray: 5 5
    classDef cat4 fill:#FFEBEE,stroke:#B71C1C,stroke-width:2px,color:#000;
    class build-front cat4
    class deploy cat4

    logs --> up
    shell-back --> up
    shell-front --> up
    shell-db --> up
    install --> install-back
    install --> install-front
    migrate --> up
    migrate --> install
    seed --> migrate
    test-back --> install
    lint-front --> install-front
    lint-back --> install-back
    fix-front --> install-front
    fix-back --> install-back
    lint --> lint-front
    lint --> lint-back
    fix --> fix-front
    fix --> fix-back
    build-front --> install
    deploy --> build-front
    deploy --> migrate

Section Details

Development Environnement

CommandDescriptionDependenciesRequired Variables
make upStart the full development environment (Docker)-PORT
make downStop all containers--
make logsShow live logs for all servicesup-
make shell-backOpen a shell inside the PHP container (Laravel)up-
make shell-frontOpen a shell inside the Node.js containerup-
make shell-dbOpen a shell inside the PostgreSQL containerup-

Setup & Initialization

CommandDescriptionDependenciesRequired Variables
make install-backInstall backend (Composer)--
make install-frontInstall frontend (NPM) dependencies--
make installRun both backend and frontend installationsinstall-back, install-front-

Database

CommandDescriptionDependenciesRequired Variables
make migrateRun database migrationsup, install-
make seedReset the DB and run seeds (Test data)
Warning: This deletes all data!
migrateSEED_CLASS

Code Quality

CommandDescriptionDependenciesRequired Variables
make test-backRun unit tests (Pest/PHPUnit)install-
make lint-frontLint frontend code (ESLint)install-front-
make lint-backLint backend code (PHP-CS-Fixer dry-run)install-back-
make fix-frontFix frontend code style and formatinstall-front-
make fix-backFix backend code styleinstall-back-
make lintRun all linters (front & back)lint-front, lint-back-
make fixFix all code style issues (front & back)fix-front, fix-back-

Deployment

CommandDescriptionDependenciesRequired Variables
make build-frontCompile Frontend assets (Vite/Mix)install-
make deployDeploy to Production
1. Build frontend assets
2. Optimize Laravel cache
3. Run migrations force
build-front, migrateAPP_KEY, SSH_USER

2. The Input (Makefile)

This is the source Makefile using The Convention.

Pro Tip: We recommend using visual separators (like the # === lines below) to clearly delimit your categories. This keeps the raw file readable for humans, while the parser simply ignores them.

# ==============================================================================
## @category Development Environnement
# ==============================================================================

## @description Start the full development environment (Docker)
## @env PORT
up:
	# docker compose up -d

## @description Stop all containers
down:
	# docker compose down

## @description Show live logs for all services
## @depends up
logs:
	# docker compose logs -f

## @description Open a shell inside the PHP container (Laravel)
## @depends up
shell-back:
	# docker compose exec app bash

## @description Open a shell inside the Node.js container
## @depends up
shell-front:
	# docker compose exec app bash

## @description Open a shell inside the PostgreSQL container
## @depends up
shell-db:
	# docker compose exec app bash

# ==============================================================================
## @category Setup & Initialization
# ==============================================================================

## @description Install backend (Composer)
install-back:
	# docker compose run --rm app composer install

## @description Install frontend (NPM) dependencies
install-front:
	# docker compose run --rm app npm install

## @description Run both backend and frontend installations
## @depends install-back, install-front
install: install-back install-front

# ==============================================================================
## @category Database
# ==============================================================================

## @description Run database migrations
## @depends up, install
migrate:
	# docker compose exec app php artisan migrate

## @description Reset the DB and run seeds (Test data) \n Warning: This deletes all data!
## @depends migrate
## @env SEED_CLASS
seed:
	# docker compose exec app php artisan migrate:refresh --seed

# ==============================================================================
## @category Code Quality
# ==============================================================================

## @description Run unit tests (Pest/PHPUnit)
## @depends install
test-back:
	# docker-compose exec app php artisan test

## @description Lint frontend code (ESLint)
## @depends install-front
lint-front:
	# docker compose exec app npm run lint

## @description Lint backend code (PHP-CS-Fixer dry-run)
## @depends install-back
lint-back:
	# docker compose exec app php-cs-fixer

## @description Fix frontend code style and format
## @depends install-front
fix-front:
	# docker compose exec app npm run lint-fix && npm run format

## @description Fix backend code style
## @depends install-back
fix-back:
	# docker compose exec app php-cs-fixer --fix

## @description Run all linters (front & back)
## @depends lint-front, lint-back
lint: lint-front lint-back

## @description Fix all code style issues (front & back)
## @depends fix-front, fix-back
fix: fix-front fix-back

# ==============================================================================
## @category Deployment
# ==============================================================================

## @description Compile Frontend assets (Vite/Mix)
## @depends install
build-front:
	# npm run build

## @description Deploy to Production \n 1. Build frontend assets \n 2. Optimize Laravel cache \n 3. Run migrations force
## @depends build-front, migrate
## @env APP_KEY, SSH_USER
deploy:
	# git pull
	# docker compose exec app php artisan config:cache
	# docker compose exec app php artisan migrate --force

Installation

The easiest way to install makefile2doc is to download the latest executable for your operating system.

  1. Go to the GitHub Releases page.
  2. Download the file matching your OS and architecture (e.g., makefile2doc-linux-amd64).
  3. Follow the setup instructions below for your operating system.

2. Setup

Linux & macOS

To use the command globally, make it executable and move it to a folder in your system $PATH.

Assuming you are in the folder where you downloaded the file:

# 1. Give execution permissions
chmod +x makefile2doc-*

# Note: Ensure you only have one version of the file in the folder to avoid errors.
sudo mv makefile2doc-* /usr/local/bin/makefile2doc

Windows

  1. Create a folder for your CLI tools (e.g., C:\Tools)
  2. Move the downloaded file (e.g., makefile2doc-windows-amd64.exe) into this folder.
  3. Rename the file to makefile2doc.exe.
  4. Add this folder to your PATH environment variable:
    • Search “Env” in the Start Menu
    • Open Edit the system environment variables
    • Select PathEditNew
    • Paste the path to your folder

3. Verify Installation

Open a new terminal and verify that the tool is correctly installed:

makefile2doc --help

If you see the help menu, you are ready to use it!

4. Developer Installation (via Cargo)

If you already have Rust and Cargo installed on your machine, you can install the tool directly from the source code.

cargo install --git https://github.com/Merlin-Clos/makefile2doc --locked

This will compile the project and place the binary in your ~/.cargo/bin folder.

Usage

1. The Command Line Interface

The tool is designed to be smart about paths. You don’t always need to specify arguments.

Basic Usage

Run the command in the folder containing your Makefile:

makefile2doc
  • Input: Looks for Makefile in the current directory.
  • Output: Generates MAKEFILE.md in the same directory.

Custom Input (-i)

If your Makefile is in a subfolder:

makefile2doc -i backend/Makefile
  • Input: Reads backend/Makefile.
  • Output: Automatically targets backend/MAKEFILE.md.

Custom Output (-o)

If you want to save the documentation somewhere specific:

makefile2doc -i Makefile -o docs/development.md
  • Input: Reads Makefile from the current directory.
  • Output: Generates the documentation in docs/development.md.

2. Important Note: Output is Empty?

makefile2doc only documents targets that have a ## @description tag. If your Makefile doesn’t follow The Convention, the generated file will be empty.

Try adding a description to one of your targets and run the tool again:

## @description A simple hello world
hello:
	echo "hello"

The Convention

To generate documentation, makefile2doc parses specific comments in your Makefile. We call this “The Convention”.

It is designed to be unobtrusive and readable, even without the tool.

Core Rules

  1. Description is Mandatory: Any target without a description is considered private and is ignored.
  2. Stateful Categories: A category tag applies to all subsequent commands until a new one is defined.

Supported Tags

## @description (Required)

Describes what the command does.

  • Usage: Must be placed immediately before the target.
  • Effect: Adds the command to the documentation.
  • Multi-line support: You can use \n or the <br> tag to force a line break in the generated Markdown tables.
## @description Starts the server \n Warning: check your .env first!
start:
    ...

## @category (Optional)

Groups commands into a section.

  • Usage: Can be placed anywhere. It acts as a switch.
  • Default: If omitted, commands go into a “General” category.
## @category Database
# ... all commands below are now in "Database" ...

## @depends (Optional)

Lists the dependencies of a command (what must run before).

  • Usage: Comma-separated list of other make targets.
  • Effect: Draws arrows in the generated Workflow Graph and lists them in the “Dependencies” column of the detailed tables.
## @description Run database migrations
## @depends up, install
migrate:
    ...

## @env (Optional)

Documents required environment variables.

  • Usage: Comma-separated list of variables.
  • Effect: Adds a “Required Variables” column in the details table.
## @description Starts the server
## @env PORT, NODE_ENV
start:
    ...

Automation & CI/CD

Documentation is misleading if it is not up-to-date.

Instead of remembering to run makefile2doc manually after every change, you should let your CI pipeline handle it. The logic is simple: if Makefile is modified, regenerate MAKEFILE.md and commit the result.

GitHub Actions Example

Here is a ready-to-use workflow using checkout and the git-auto-commit Action (check links for latest versions).

Create .github/workflows/update-docs.yml:

name: Update Makefile Doc

on:
  push:
    paths:
      - "Makefile" # Trigger only when the Makefile changes

permissions:
  contents: write # Required to push the new commit

jobs:
  update-doc:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Install makefile2doc
        env:
          # Check the latest version: https://github.com/Merlin-Clos/makefile2doc/releases
          VERSION: v0.1.2
        run: |
          curl -L -o makefile2doc https://github.com/Merlin-Clos/makefile2doc/releases/download/${VERSION}/makefile2doc-linux-amd64
          chmod +x makefile2doc
          sudo mv makefile2doc /usr/local/bin/

      - name: Generate Documentation
        run: makefile2doc

      - name: Commit & Push changes
        uses: stefanzweifel/git-auto-commit-action@v7
        with:
          commit_message: "docs: auto-update MAKEFILE.md"
          file_pattern: MAKEFILE.md

AI-Ready Documentation

makefile2doc bridges the gap between raw code and AI comprehension.

1. Context Window Efficiency

When you provide a raw Makefile to an LLM (ChatGPT, Claude, etc.), it has to parse implementation details like docker compose flags, sed commands, or complex environment variable expansions.

By providing the generated MAKEFILE.md, you offer a high-level summary:

  • Token Savings: Only the intent and dependencies are sent, not the bash implementation.
  • Better Reasoning: LLMs can understand the Workflow Graph (Mermaid) to see how commands relate, preventing it from suggesting commands in the wrong order.

2. Accuracy Enforcement

Using makefile2doc acts as a Forcing Function for your team:

  • If the documentation is wrong, your AI will hallucinate.
  • This incentivizes developers to keep ## @description and ## @depends tags accurate.

3. How to use with LLMs

To give your AI the full context, don’t copy-paste files one by one.

👉 Click here for the Full Context (Print View)

Copy the content of that page and paste it into your AI. It contains the entire documentation in one go.