# 🍞 mbake
<!-- markdownlint-disable MD033 -->
<div align="center">
<img src="https://raw.githubusercontent.com/ebodshojaei/bake/main/vscode-mbake-extension/icon.png" alt="mbake logo" width="128" height="128">
<br/>
<em>A Makefile formatter and linter. It only took 50 years!</em>
<br/><br/>
<a href="https://opensource.org/licenses/MIT">
<img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"/>
</a>
<a href="https://www.python.org/downloads/">
<img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="Python 3.9+"/>
</a>
<a href="https://pypi.org/project/mbake/">
<img src="https://img.shields.io/pypi/v/mbake.svg" alt="PyPI - mbake"/>
</a>
<a href="https://github.com/psf/black">
<img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code style: black"/>
</a>
<a href="https://pepy.tech/projects/mbake">
<img src="https://static.pepy.tech/badge/mbake" alt="PyPI Downloads"/>
</a>
</div>
<!-- markdownlint-enable MD033 -->
## Table of Contents
- [Features](#features)
- [Installation](#installation)
- [Migration to v1.3.x](#migration-to-v13x)
- [Usage](#usage)
- [Configuration](#configuration)
- [Examples](#examples-1)
- [Contributing](#contributing)
## Features
- Configurable rules via `~/.bake.toml`
- CI/CD integration with check mode
- Extensible plugin architecture
- Rich terminal output with progress indicators
- Syntax validation before and after formatting
- Smart .PHONY detection with automatic insertion
- Suppress formatting with special comments
---
## Formatting Rules
### Indentation & Spacing
- **Tabs for recipes**: Recipe lines use tabs instead of spaces
- **Assignment operators**: Normalized spacing around `:=`, `=`, `+=`, `?=`
- **Target colons**: Consistent spacing around target dependency colons
- **Trailing whitespace**: Removes unnecessary trailing spaces
### Line Continuations
- **Backslash normalization**: Proper spacing around backslash continuations
- **Smart joining**: Consolidates simple continuations while preserving complex structures
### .PHONY Declarations
- **Grouping**: Consolidates multiple `.PHONY` declarations
- **Auto-insertion**: Automatically detects and inserts `.PHONY` declarations when missing (opt-in)
- **Dynamic enhancement**: Enhances existing `.PHONY` declarations with additional detected phony targets
- **Rule-based analysis**: Uses command analysis to determine if targets are phony
- **Minimal changes**: Only modifies `.PHONY` lines, preserves file structure
---
## Installation
### PyPI (Recommended)
```bash
pip install mbake
```
### VSCode Extension
1. Open VSCode
2. Go to Extensions (Ctrl+Shift+X)
3. Search for "mbake Makefile Formatter"
4. Click Install
### From Source
```bash
git clone https://github.com/ebodshojaei/bake.git
cd mbake
pip install -e .
```
### Development Installation
```bash
git clone https://github.com/ebodshojaei/bake.git
cd mbake
pip install -e ".[dev]"
```
### Package Manager Installation
For system package managers and AUR packagers, mbake supports configurable command names to avoid namespace conflicts.
**For AUR packagers**: The default behavior already avoids conflicts with `ruby-bake` - no additional configuration needed!
---
## Migration to v1.3.x
**⚠️ Breaking Change**: Version 1.3.0 introduces a module rename from `bake` to `mbake` for consistency.
### What Changed
- **Python module**: `bake` → `mbake` (for consistency with command name)
- **Command name**: Still `mbake` (unchanged)
- **Configuration**: Still `~/.bake.toml` (unchanged)
### Migration Steps
1. **Update the package**:
```bash
pip install --upgrade mbake
```
2. **If you have shell aliases**, they will continue working:
```bash
# Your existing alias will still work
alias bake='mbake'
bake --version # ✅ Still works
```
3. **If you have Python scripts** that import from `bake`, update them:
```python
# Old (v1.2.x)
from bake.config import Config
# New (v1.3.x)
from mbake.config import Config
```
4. **If you have CI/CD scripts**, update import statements:
```bash
# Old (v1.2.x)
python -c "from bake.cli import main; main()"
# New (v1.3.x)
python -c "from mbake.cli import main; main()"
```
### Backward Compatibility
- **CLI commands**: All commands work exactly the same
- **Configuration files**: No changes needed
- **Shell aliases**: Continue working without modification
- **Python imports**: Require updating to use `mbake` module
---
## Usage
mbake uses a subcommand-based CLI. All commands support both `bake` and `mbake` aliases.
### Quick Start
```bash
# Check version
mbake --version
# Set up your preferred command name (optional)
mbake setup-command mbake # or 'bake' (creates alias) or 'both' (creates alias)
# Initialize configuration (optional)
mbake init
# Format a Makefile
mbake format Makefile
# Validate Makefile syntax
mbake validate Makefile
```
### Configuration Management
```bash
# Initialize configuration file with defaults
bake init
# Initialize with custom path or force overwrite
bake init --config /path/to/config.toml --force
# Show current configuration
bake config
# Show configuration file path
bake config --path
# Use custom configuration file
bake config --config /path/to/config.toml
```
### Formatting Files
```bash
# Format a single Makefile
bake format Makefile
# Format multiple files
bake format Makefile src/Makefile tests/*.mk
# Check if files need formatting (CI/CD mode)
bake format --check Makefile
# Show diff of changes without modifying files
bake format --diff Makefile
# Format with verbose output
bake format --verbose Makefile
# Create backup before formatting
bake format --backup Makefile
# Validate syntax after formatting
bake format --validate Makefile
# Use custom configuration
bake format --config /path/to/config.toml Makefile
```
### Syntax Validation
```bash
# Validate single file
bake validate Makefile
# Validate multiple files
bake validate Makefile src/Makefile tests/*.mk
# Validate with verbose output
bake validate --verbose Makefile
# Use custom configuration
bake validate --config /path/to/config.toml Makefile
```
#### **validate vs format --check**
- **`bake validate`**: Checks if Makefile will execute correctly using GNU `make` (syntax validation)
- **`bake format --check`**: Checks if Makefile follows formatting rules (style validation)
Both are useful! Use `validate` for syntax errors, `format --check` for style issues.
### Version Management
```bash
# Check current version and for updates
bake --version
# Check for updates only (without updating)
bake update --check
# Update to latest version
bake update
# Update with confirmation prompt bypass
bake update --yes
# Force update even if already up to date
bake update --force
```
### Shell Completion
```bash
# Install completion for current shell
bake --install-completion
# Show completion script (for manual installation)
bake --show-completion
```
---
## Configuration
mbake works with sensible defaults. Generate a configuration file with:
```bash
bake init
```
### Sample Configuration
```toml
[formatter]
# Indentation settings
use_tabs = true
tab_width = 4
# Spacing settings
space_around_assignment = true
space_before_colon = false
space_after_colon = true
# Line continuation settings
normalize_line_continuations = true
max_line_length = 120
# PHONY settings
group_phony_declarations = true
phony_at_top = true
auto_insert_phony_declarations = false
# General settings
remove_trailing_whitespace = true
ensure_final_newline = true
normalize_empty_lines = true
max_consecutive_empty_lines = 2
fix_missing_recipe_tabs = true
# Global settings
debug = false
verbose = false
# Error message formatting
gnu_error_format = true # Use GNU standard error format (file:line: Error: message)
wrap_error_messages = false # Wrap long error messages (can interfere with IDE parsing)
```
---
## Smart .PHONY Detection
mbake includes intelligent `.PHONY` detection that automatically identifies and manages phony targets.
### How It Works
Detection uses dynamic analysis of recipe commands rather than hardcoded target names:
- **Command Analysis**: Examines what each target's recipe actually does
- **File Creation Detection**: Identifies if commands create files with the target name
- **Pattern Recognition**: Understands compilation patterns, redirections, and common tools
### Examples
#### Docker/Container Targets
```makefile
# These are detected as phony because they manage containers, not files
up:
docker compose up -d
down:
docker compose down -v
logs:
docker compose logs -f
```
#### Build/Development Targets
```makefile
# These are detected as phony because they don't create files with their names
test:
npm test
lint:
eslint src/
deploy:
ssh user@server 'systemctl restart myapp'
```
#### File vs Phony Target Detection
```makefile
# NOT phony - creates myapp.o file
myapp.o: myapp.c
gcc -c myapp.c -o myapp.o
# Phony - removes files, doesn't create "clean"
clean:
rm -f *.o myapp
```
<!-- markdownlint-disable MD024 -->
### Configuration
Enable auto-insertion in your `~/.bake.toml`:
```toml
[formatter]
auto_insert_phony_declarations = true
```
### Behavior Modes
**Default (Conservative)**:
- Groups existing `.PHONY` declarations
- No automatic insertion or enhancement
- Backwards compatible
**Enhanced (auto_insert_phony_declarations = true)**:
- Automatically inserts `.PHONY` when missing
- Enhances existing `.PHONY` with detected targets
- Uses dynamic analysis for accurate detection
### Before and After
**Input** (no `.PHONY`):
```makefile
setup:
docker compose up -d
npm install
test:
npm test
clean:
docker compose down -v
rm -rf node_modules
```
**Output** (with auto-insertion enabled):
```makefile
setup:
docker compose up -d
npm install
test:
npm test
clean:
docker compose down -v
rm -rf node_modules
```
---
## Examples
### Basic Formatting
**Before:**
```makefile
# Inconsistent spacing and indentation
CC:=gcc
CFLAGS= -Wall -g
SOURCES=main.c \
utils.c \
helper.c
.PHONY: clean
all: $(TARGET)
$(CC) $(CFLAGS) -o $@ $^
.PHONY: install
clean:
rm -f *.o
```
**After:**
```makefile
# Clean, consistent formatting
CC := gcc
CFLAGS = -Wall -g
SOURCES = main.c \
utils.c \
helper.c
.PHONY: clean
all: $(TARGET)
$(CC) $(CFLAGS) -o $@ $^
.PHONY: install
clean:
rm -f *.o
```
### Auto-Insertion Example
**Before** (with `auto_insert_phony_declarations = true`):
```makefile
# Docker development workflow
setup:
docker compose down -v
docker compose up -d
@echo "Services ready!"
build:
docker compose build --no-cache
test:
docker compose exec app npm test
clean:
docker compose down -v
docker system prune -af
```
**After:**
```makefile
# Docker development workflow
.PHONY: clean setup test
setup:
docker compose down -v
docker compose up -d
@echo "Services ready!"
build:
docker compose build --no-cache
test:
docker compose exec app npm test
clean:
docker compose down -v
docker system prune -af
```
### Disable Formatting Example
Disable formatting within a region using special comments that switch formatting in a delimited range.
Use `# bake-format off` to disable formatting for the lines until the next `#bake-format on`, which re-enables formatting.
```makefile
# bake-format off
NO_FORMAT_1= \
1 \
45678 \
#bake-format on
# bake-format off : optional comment
NO_FORMAT_2= \
1 \
45678 \
#bake-format on
```
---
## CI/CD Integration
Use mbake in continuous integration:
```yaml
# GitHub Actions example
- name: Check Makefile formatting
run: |
pip install mbake
bake format --check Makefile
```
Exit codes:
- `0` - No formatting needed or formatting successful
- `1` - Files need formatting (--check mode) or validation failed
- `2` - Error occurred
---
## Development
### Setup
```bash
git clone https://github.com/ebodshojaei/bake.git
cd mbake
pip install -e ".[dev]"
```
### Running Tests
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=bake --cov-report=html
# Run specific test file
pytest tests/test_formatter.py -v
```
### Code Quality
```bash
# Format code
black bake tests
# Lint code
ruff check bake tests
# Type checking
mypy bake
```
---
## Architecture
mbake follows a modular, plugin-based architecture:
```text
bake/
├── __init__.py # Package initialization
├── cli.py # Command-line interface with subcommands
├── config.py # Configuration management
├── core/
│ ├── formatter.py # Main formatting engine
│ └── rules/ # Individual formatting rules
│ ├── tabs.py # Tab/indentation handling
│ ├── spacing.py # Spacing normalization
│ ├── continuation.py # Line continuation formatting
│ └── phony.py # .PHONY declaration management
└── plugins/
└── base.py # Plugin interface
```
### Adding Custom Rules
Extend the `FormatterPlugin` base class:
```python
from bake.plugins.base import FormatterPlugin, FormatResult
class MyCustomRule(FormatterPlugin):
def __init__(self):
super().__init__("my_rule", priority=50)
def format(self, lines: List[str], config: dict) -> FormatResult:
# Your formatting logic here
return FormatResult(
lines=modified_lines,
changed=True,
errors=[],
warnings=[]
)
```
---
## Contributing
Contributions are welcome! Read the [Contributing Guide](CONTRIBUTING.md) for details on development process, submitting pull requests, and reporting issues.
### Quick Start for Contributors
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes
4. Add tests for new functionality
5. Run the test suite (`pytest`)
6. Commit your changes (`git commit -m 'Add amazing feature'`)
7. Push to the branch (`git push origin feature/amazing-feature`)
8. Open a Pull Request
---
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
---
## Design Philosophy
- **Minimal changes**: Only modify what needs to be fixed, preserve file structure
- **Predictable behavior**: Consistent formatting rules across all Makefiles
- **Fast execution**: Efficient processing of large Makefiles
- **Reliable validation**: Ensure formatted Makefiles have correct syntax
- **Developer-friendly**: Rich CLI with helpful error messages and progress indicators
Raw data
{
"_id": null,
"home_page": null,
"name": "mbake",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "build-tools, formatter, linter, makefile",
"author": "mbake Contributors",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/c1/8d/decba145f888fe6d2b5c79f2381516758d4212cb62bcf0c8078aa7878ede/mbake-1.3.1.post1.tar.gz",
"platform": null,
"description": "# \ud83c\udf5e mbake\n\n<!-- markdownlint-disable MD033 -->\n<div align=\"center\">\n <img src=\"https://raw.githubusercontent.com/ebodshojaei/bake/main/vscode-mbake-extension/icon.png\" alt=\"mbake logo\" width=\"128\" height=\"128\">\n <br/>\n <em>A Makefile formatter and linter. It only took 50 years!</em>\n <br/><br/>\n <a href=\"https://opensource.org/licenses/MIT\">\n <img src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License: MIT\"/>\n </a>\n <a href=\"https://www.python.org/downloads/\">\n <img src=\"https://img.shields.io/badge/python-3.9+-blue.svg\" alt=\"Python 3.9+\"/>\n </a>\n <a href=\"https://pypi.org/project/mbake/\">\n <img src=\"https://img.shields.io/pypi/v/mbake.svg\" alt=\"PyPI - mbake\"/>\n </a>\n <a href=\"https://github.com/psf/black\">\n <img src=\"https://img.shields.io/badge/code%20style-black-000000.svg\" alt=\"Code style: black\"/>\n </a>\n <a href=\"https://pepy.tech/projects/mbake\">\n <img src=\"https://static.pepy.tech/badge/mbake\" alt=\"PyPI Downloads\"/>\n </a>\n</div>\n<!-- markdownlint-enable MD033 -->\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Migration to v1.3.x](#migration-to-v13x)\n- [Usage](#usage)\n- [Configuration](#configuration)\n- [Examples](#examples-1)\n- [Contributing](#contributing)\n\n## Features\n\n- Configurable rules via `~/.bake.toml`\n- CI/CD integration with check mode\n- Extensible plugin architecture\n- Rich terminal output with progress indicators\n- Syntax validation before and after formatting\n- Smart .PHONY detection with automatic insertion\n- Suppress formatting with special comments\n\n---\n\n## Formatting Rules\n\n### Indentation & Spacing\n\n- **Tabs for recipes**: Recipe lines use tabs instead of spaces\n- **Assignment operators**: Normalized spacing around `:=`, `=`, `+=`, `?=`\n- **Target colons**: Consistent spacing around target dependency colons\n- **Trailing whitespace**: Removes unnecessary trailing spaces\n\n### Line Continuations\n\n- **Backslash normalization**: Proper spacing around backslash continuations\n- **Smart joining**: Consolidates simple continuations while preserving complex structures\n\n### .PHONY Declarations\n\n- **Grouping**: Consolidates multiple `.PHONY` declarations\n- **Auto-insertion**: Automatically detects and inserts `.PHONY` declarations when missing (opt-in)\n- **Dynamic enhancement**: Enhances existing `.PHONY` declarations with additional detected phony targets\n- **Rule-based analysis**: Uses command analysis to determine if targets are phony\n- **Minimal changes**: Only modifies `.PHONY` lines, preserves file structure\n\n---\n\n## Installation\n\n### PyPI (Recommended)\n\n```bash\npip install mbake\n```\n\n### VSCode Extension\n\n1. Open VSCode\n2. Go to Extensions (Ctrl+Shift+X)\n3. Search for \"mbake Makefile Formatter\"\n4. Click Install\n\n### From Source\n\n```bash\ngit clone https://github.com/ebodshojaei/bake.git\ncd mbake\npip install -e .\n```\n\n### Development Installation\n\n```bash\ngit clone https://github.com/ebodshojaei/bake.git\ncd mbake\npip install -e \".[dev]\"\n```\n\n### Package Manager Installation\n\nFor system package managers and AUR packagers, mbake supports configurable command names to avoid namespace conflicts.\n\n**For AUR packagers**: The default behavior already avoids conflicts with `ruby-bake` - no additional configuration needed!\n\n---\n\n## Migration to v1.3.x\n\n**\u26a0\ufe0f Breaking Change**: Version 1.3.0 introduces a module rename from `bake` to `mbake` for consistency.\n\n### What Changed\n\n- **Python module**: `bake` \u2192 `mbake` (for consistency with command name)\n- **Command name**: Still `mbake` (unchanged)\n- **Configuration**: Still `~/.bake.toml` (unchanged)\n\n### Migration Steps\n\n1. **Update the package**:\n\n ```bash\n pip install --upgrade mbake\n ```\n\n2. **If you have shell aliases**, they will continue working:\n\n ```bash\n # Your existing alias will still work\n alias bake='mbake'\n bake --version # \u2705 Still works\n ```\n\n3. **If you have Python scripts** that import from `bake`, update them:\n\n ```python\n # Old (v1.2.x)\n from bake.config import Config\n \n # New (v1.3.x)\n from mbake.config import Config\n ```\n\n4. **If you have CI/CD scripts**, update import statements:\n\n ```bash\n # Old (v1.2.x)\n python -c \"from bake.cli import main; main()\"\n \n # New (v1.3.x)\n python -c \"from mbake.cli import main; main()\"\n ```\n\n### Backward Compatibility\n\n- **CLI commands**: All commands work exactly the same\n- **Configuration files**: No changes needed\n- **Shell aliases**: Continue working without modification\n- **Python imports**: Require updating to use `mbake` module\n\n---\n\n## Usage\n\nmbake uses a subcommand-based CLI. All commands support both `bake` and `mbake` aliases.\n\n### Quick Start\n\n```bash\n# Check version\nmbake --version\n\n# Set up your preferred command name (optional)\nmbake setup-command mbake # or 'bake' (creates alias) or 'both' (creates alias)\n\n# Initialize configuration (optional)\nmbake init\n\n# Format a Makefile\nmbake format Makefile\n\n# Validate Makefile syntax\nmbake validate Makefile\n```\n\n### Configuration Management\n\n```bash\n# Initialize configuration file with defaults\nbake init\n\n# Initialize with custom path or force overwrite\nbake init --config /path/to/config.toml --force\n\n# Show current configuration\nbake config\n\n# Show configuration file path\nbake config --path\n\n# Use custom configuration file\nbake config --config /path/to/config.toml\n```\n\n### Formatting Files\n\n```bash\n# Format a single Makefile\nbake format Makefile\n\n# Format multiple files\nbake format Makefile src/Makefile tests/*.mk\n\n# Check if files need formatting (CI/CD mode)\nbake format --check Makefile\n\n# Show diff of changes without modifying files\nbake format --diff Makefile\n\n# Format with verbose output\nbake format --verbose Makefile\n\n# Create backup before formatting\nbake format --backup Makefile\n\n# Validate syntax after formatting\nbake format --validate Makefile\n\n# Use custom configuration\nbake format --config /path/to/config.toml Makefile\n```\n\n### Syntax Validation\n\n```bash\n# Validate single file\nbake validate Makefile\n\n# Validate multiple files\nbake validate Makefile src/Makefile tests/*.mk\n\n# Validate with verbose output\nbake validate --verbose Makefile\n\n# Use custom configuration\nbake validate --config /path/to/config.toml Makefile\n```\n\n#### **validate vs format --check**\n\n- **`bake validate`**: Checks if Makefile will execute correctly using GNU `make` (syntax validation)\n- **`bake format --check`**: Checks if Makefile follows formatting rules (style validation)\n\nBoth are useful! Use `validate` for syntax errors, `format --check` for style issues.\n\n### Version Management\n\n```bash\n# Check current version and for updates\nbake --version\n\n# Check for updates only (without updating)\nbake update --check\n\n# Update to latest version\nbake update\n\n# Update with confirmation prompt bypass\nbake update --yes\n\n# Force update even if already up to date\nbake update --force\n```\n\n### Shell Completion\n\n```bash\n# Install completion for current shell\nbake --install-completion\n\n# Show completion script (for manual installation)\nbake --show-completion\n```\n\n---\n\n## Configuration\n\nmbake works with sensible defaults. Generate a configuration file with:\n\n```bash\nbake init\n```\n\n### Sample Configuration\n\n```toml\n[formatter]\n# Indentation settings\nuse_tabs = true\ntab_width = 4\n\n# Spacing settings\nspace_around_assignment = true\nspace_before_colon = false\nspace_after_colon = true\n\n# Line continuation settings\nnormalize_line_continuations = true\nmax_line_length = 120\n\n# PHONY settings\ngroup_phony_declarations = true\nphony_at_top = true\nauto_insert_phony_declarations = false\n\n# General settings\nremove_trailing_whitespace = true\nensure_final_newline = true\nnormalize_empty_lines = true\nmax_consecutive_empty_lines = 2\nfix_missing_recipe_tabs = true\n\n# Global settings\ndebug = false\nverbose = false\n\n# Error message formatting\ngnu_error_format = true # Use GNU standard error format (file:line: Error: message)\nwrap_error_messages = false # Wrap long error messages (can interfere with IDE parsing)\n```\n\n---\n\n## Smart .PHONY Detection\n\nmbake includes intelligent `.PHONY` detection that automatically identifies and manages phony targets.\n\n### How It Works\n\nDetection uses dynamic analysis of recipe commands rather than hardcoded target names:\n\n- **Command Analysis**: Examines what each target's recipe actually does\n- **File Creation Detection**: Identifies if commands create files with the target name\n- **Pattern Recognition**: Understands compilation patterns, redirections, and common tools\n\n### Examples\n\n#### Docker/Container Targets\n\n```makefile\n# These are detected as phony because they manage containers, not files\nup:\n docker compose up -d\n\ndown:\n docker compose down -v\n\nlogs:\n docker compose logs -f\n```\n\n#### Build/Development Targets \n\n```makefile\n# These are detected as phony because they don't create files with their names\ntest:\n npm test\n\nlint:\n eslint src/\n\ndeploy:\n ssh user@server 'systemctl restart myapp'\n```\n\n#### File vs Phony Target Detection\n\n```makefile\n# NOT phony - creates myapp.o file\nmyapp.o: myapp.c\n gcc -c myapp.c -o myapp.o\n\n# Phony - removes files, doesn't create \"clean\"\nclean:\n rm -f *.o myapp\n```\n\n<!-- markdownlint-disable MD024 -->\n### Configuration\n\nEnable auto-insertion in your `~/.bake.toml`:\n\n```toml\n[formatter]\nauto_insert_phony_declarations = true\n```\n\n### Behavior Modes\n\n**Default (Conservative)**:\n\n- Groups existing `.PHONY` declarations\n- No automatic insertion or enhancement\n- Backwards compatible\n\n**Enhanced (auto_insert_phony_declarations = true)**:\n\n- Automatically inserts `.PHONY` when missing\n- Enhances existing `.PHONY` with detected targets\n- Uses dynamic analysis for accurate detection\n\n### Before and After\n\n**Input** (no `.PHONY`):\n\n```makefile\nsetup:\n docker compose up -d\n npm install\n\ntest:\n npm test\n\nclean:\n docker compose down -v\n rm -rf node_modules\n```\n\n**Output** (with auto-insertion enabled):\n\n```makefile\nsetup:\n docker compose up -d\n npm install\n\ntest:\n npm test\n\nclean:\n docker compose down -v\n rm -rf node_modules\n\n```\n\n---\n\n## Examples\n\n### Basic Formatting\n\n**Before:**\n\n```makefile\n# Inconsistent spacing and indentation\nCC:=gcc\nCFLAGS= -Wall -g\nSOURCES=main.c \\\n utils.c \\\n helper.c\n\n.PHONY: clean\nall: $(TARGET)\n $(CC) $(CFLAGS) -o $@ $^\n\n.PHONY: install\nclean:\n rm -f *.o\n```\n\n**After:**\n\n```makefile\n# Clean, consistent formatting\nCC := gcc\nCFLAGS = -Wall -g\nSOURCES = main.c \\\n utils.c \\\n helper.c\n\n.PHONY: clean\nall: $(TARGET)\n $(CC) $(CFLAGS) -o $@ $^\n\n.PHONY: install\nclean:\n rm -f *.o\n\n```\n\n### Auto-Insertion Example\n\n**Before** (with `auto_insert_phony_declarations = true`):\n\n```makefile\n# Docker development workflow\nsetup:\n docker compose down -v\n docker compose up -d\n @echo \"Services ready!\"\n\nbuild:\n docker compose build --no-cache\n\ntest:\n docker compose exec app npm test\n\nclean:\n docker compose down -v\n docker system prune -af\n```\n\n**After:**\n\n```makefile\n# Docker development workflow\n.PHONY: clean setup test\n\nsetup:\n docker compose down -v\n docker compose up -d\n @echo \"Services ready!\"\n\nbuild:\n docker compose build --no-cache\n\ntest:\n docker compose exec app npm test\n\nclean:\n docker compose down -v\n docker system prune -af\n\n```\n\n### Disable Formatting Example\n\nDisable formatting within a region using special comments that switch formatting in a delimited range.\n\nUse `# bake-format off` to disable formatting for the lines until the next `#bake-format on`, which re-enables formatting.\n\n```makefile\n# bake-format off\nNO_FORMAT_1= \\\n 1 \\\n 45678 \\\n\n#bake-format on\n\n# bake-format off : optional comment\nNO_FORMAT_2= \\\n 1 \\\n 45678 \\\n\n#bake-format on\n```\n\n---\n\n## CI/CD Integration\n\nUse mbake in continuous integration:\n\n```yaml\n# GitHub Actions example\n- name: Check Makefile formatting\n run: |\n pip install mbake\n bake format --check Makefile\n```\n\nExit codes:\n\n- `0` - No formatting needed or formatting successful\n- `1` - Files need formatting (--check mode) or validation failed\n- `2` - Error occurred\n\n---\n\n## Development\n\n### Setup\n\n```bash\ngit clone https://github.com/ebodshojaei/bake.git\ncd mbake\npip install -e \".[dev]\"\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run with coverage\npytest --cov=bake --cov-report=html\n\n# Run specific test file\npytest tests/test_formatter.py -v\n```\n\n### Code Quality\n\n```bash\n# Format code\nblack bake tests\n\n# Lint code\nruff check bake tests\n\n# Type checking\nmypy bake\n```\n\n---\n\n## Architecture\n\nmbake follows a modular, plugin-based architecture:\n\n```text\nbake/\n\u251c\u2500\u2500 __init__.py # Package initialization\n\u251c\u2500\u2500 cli.py # Command-line interface with subcommands\n\u251c\u2500\u2500 config.py # Configuration management\n\u251c\u2500\u2500 core/\n\u2502 \u251c\u2500\u2500 formatter.py # Main formatting engine\n\u2502 \u2514\u2500\u2500 rules/ # Individual formatting rules\n\u2502 \u251c\u2500\u2500 tabs.py # Tab/indentation handling\n\u2502 \u251c\u2500\u2500 spacing.py # Spacing normalization\n\u2502 \u251c\u2500\u2500 continuation.py # Line continuation formatting\n\u2502 \u2514\u2500\u2500 phony.py # .PHONY declaration management\n\u2514\u2500\u2500 plugins/\n \u2514\u2500\u2500 base.py # Plugin interface\n```\n\n### Adding Custom Rules\n\nExtend the `FormatterPlugin` base class:\n\n```python\nfrom bake.plugins.base import FormatterPlugin, FormatResult\n\nclass MyCustomRule(FormatterPlugin):\n def __init__(self):\n super().__init__(\"my_rule\", priority=50)\n \n def format(self, lines: List[str], config: dict) -> FormatResult:\n # Your formatting logic here\n return FormatResult(\n lines=modified_lines,\n changed=True,\n errors=[],\n warnings=[]\n )\n```\n\n---\n\n## Contributing\n\nContributions are welcome! Read the [Contributing Guide](CONTRIBUTING.md) for details on development process, submitting pull requests, and reporting issues.\n\n### Quick Start for Contributors\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes\n4. Add tests for new functionality\n5. Run the test suite (`pytest`)\n6. Commit your changes (`git commit -m 'Add amazing feature'`)\n7. Push to the branch (`git push origin feature/amazing-feature`)\n8. Open a Pull Request\n\n---\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n---\n\n## Design Philosophy\n\n- **Minimal changes**: Only modify what needs to be fixed, preserve file structure\n- **Predictable behavior**: Consistent formatting rules across all Makefiles\n- **Fast execution**: Efficient processing of large Makefiles\n- **Reliable validation**: Ensure formatted Makefiles have correct syntax\n- **Developer-friendly**: Rich CLI with helpful error messages and progress indicators\n",
"bugtrack_url": null,
"license": null,
"summary": "A Python-based Makefile formatter and linter",
"version": "1.3.1.post1",
"project_urls": {
"Bug Tracker": "https://github.com/EbodShojaei/bake/issues",
"Changelog": "https://github.com/EbodShojaei/bake/releases",
"Documentation": "https://github.com/EbodShojaei/bake#readme",
"Funding": "https://github.com/sponsors/ebodshojaei",
"Homepage": "https://github.com/EbodShojaei/bake",
"Repository": "https://github.com/EbodShojaei/bake"
},
"split_keywords": [
"build-tools",
" formatter",
" linter",
" makefile"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "f5d9abd401031ab915ad8bb8688eab3f15d7bda868d5669483a5e7f9e6fffcb7",
"md5": "947e94f7732920a62081fd3a00e77fdf",
"sha256": "1a65e079ed566d7ce50bef8877649096a404599a1cde1be91c9981a0f48b168b"
},
"downloads": -1,
"filename": "mbake-1.3.1.post1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "947e94f7732920a62081fd3a00e77fdf",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 70628,
"upload_time": "2025-07-14T03:36:30",
"upload_time_iso_8601": "2025-07-14T03:36:30.901973Z",
"url": "https://files.pythonhosted.org/packages/f5/d9/abd401031ab915ad8bb8688eab3f15d7bda868d5669483a5e7f9e6fffcb7/mbake-1.3.1.post1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c18ddecba145f888fe6d2b5c79f2381516758d4212cb62bcf0c8078aa7878ede",
"md5": "265b76b7fbfaf6f94f06f4495fe6898f",
"sha256": "9cba94fa1bf819e5cd60a6242349a84430e59ff35d2f004284482e0f610fbd85"
},
"downloads": -1,
"filename": "mbake-1.3.1.post1.tar.gz",
"has_sig": false,
"md5_digest": "265b76b7fbfaf6f94f06f4495fe6898f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 2773367,
"upload_time": "2025-07-14T03:36:32",
"upload_time_iso_8601": "2025-07-14T03:36:32.626165Z",
"url": "https://files.pythonhosted.org/packages/c1/8d/decba145f888fe6d2b5c79f2381516758d4212cb62bcf0c8078aa7878ede/mbake-1.3.1.post1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-14 03:36:32",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "EbodShojaei",
"github_project": "bake",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "mbake"
}