{"id":28984722,"url":"https://github.com/EbodShojaei/bake","last_synced_at":"2025-06-24T18:02:36.559Z","repository":{"id":300114283,"uuid":"965576317","full_name":"EbodShojaei/bake","owner":"EbodShojaei","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-20T00:23:46.000Z","size":14084,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-20T00:28:48.951Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EbodShojaei.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-13T13:22:01.000Z","updated_at":"2025-06-20T00:23:47.000Z","dependencies_parsed_at":"2025-06-20T00:39:03.882Z","dependency_job_id":null,"html_url":"https://github.com/EbodShojaei/bake","commit_stats":null,"previous_names":["ebodshojaei/bake"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/EbodShojaei/bake","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EbodShojaei%2Fbake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EbodShojaei%2Fbake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EbodShojaei%2Fbake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EbodShojaei%2Fbake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EbodShojaei","download_url":"https://codeload.github.com/EbodShojaei/bake/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EbodShojaei%2Fbake/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261214526,"owners_count":23125815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-24T18:01:55.351Z","updated_at":"2025-06-24T18:02:36.545Z","avatar_url":"https://github.com/EbodShojaei.png","language":"Python","readme":"# 🍞 mbake\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/ebodshojaei/bake/main/vscode-mbake-extension/icon.png\" alt=\"mbake logo\" width=\"128\" height=\"128\"\u003e\n    \u003cbr/\u003e\n    \u003cem\u003eA Makefile formatter and linter. It only took 50 years!\u003c/em\u003e\n    \u003cbr/\u003e\u003cbr/\u003e\n    \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License: MIT\"/\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.python.org/downloads/\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/python-3.9+-blue.svg\" alt=\"Python 3.9+\"/\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/mbake/\"\u003e\n        \u003cimg src=\"https://img.shields.io/pypi/v/mbake.svg\" alt=\"PyPI - mbake\"/\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/psf/black\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/code%20style-black-000000.svg\" alt=\"Code style: black\"/\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://pepy.tech/projects/mbake\"\u003e\n        \u003cimg src=\"https://static.pepy.tech/badge/mbake\" alt=\"PyPI Downloads\"/\u003e\n    \u003c/a\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\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\n---\n\n## Formatting Rules\n\n### Indentation \u0026 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---\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\nbake --version\n\n# Initialize configuration (optional)\nbake init\n\n# Format a Makefile\nbake format Makefile\n\n# Validate Makefile syntax\nbake 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\u003c!-- markdownlint-disable MD024 --\u003e\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\n.PHONY: clean setup test\n\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## 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 utils.c helper.c\n\n.PHONY: all clean install\n\nall: $(TARGET)\n $(CC) $(CFLAGS) -o $@ $^\n\nclean:\n rm -f *.o\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: build 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\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├── __init__.py                 # Package initialization\n├── cli.py                      # Command-line interface with subcommands\n├── config.py                   # Configuration management\n├── core/\n│   ├── formatter.py            # Main formatting engine\n│   └── rules/                  # Individual formatting rules\n│       ├── tabs.py             # Tab/indentation handling\n│       ├── spacing.py          # Spacing normalization\n│       ├── continuation.py     # Line continuation formatting\n│       └── phony.py            # .PHONY declaration management\n└── plugins/\n    └── 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) -\u003e 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","funding_links":[],"categories":["Python","Lint and Highlight"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FEbodShojaei%2Fbake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FEbodShojaei%2Fbake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FEbodShojaei%2Fbake/lists"}