sinefineinfinitum / ponymator
Ponymator - generate docs for php project
Requires
- php: ^8.0
- nikic/php-parser: ^5.7
Requires (Dev)
- phpstan/phpstan: ^2.2
- phpunit/phpunit: ^10.5.0
- squizlabs/php_codesniffer: ^4.0
This package is auto-updated.
Last update: 2026-06-02 20:43:09 UTC
README
A CLI-first PHP documentation generator that produces deterministic Markdown documentation for a project's public API.
Principles
AST-First Correctness
Ponymator uses PHP Abstract Syntax Tree analysis (via nikic/php-parser) as the single source of truth. Public API extraction — classes, interfaces, traits, enums, public methods, signatures, inheritance, implemented interfaces, modifiers, and dependencies — is derived from parsed PHP source code, never from regex or string matching. If source code cannot be parsed, the tool fails with actionable diagnostics.
Deterministic Output
For identical source code and configuration, repeated runs produce byte-identical Markdown files. Ordering of classes, methods, dependencies, imports, modifiers, and sections is fully deterministic, making output suitable for CI comparison.
CLI-First Experience
| Mode | Flag | Description |
|---|---|---|
| Full | --full |
Regenerate all documentation |
| Diff | --diff |
Regenerate only changed files (default) |
Exit codes:
0— success1— generic error (config, parse, runtime)
Test-First Quality
Every behavior affecting documentation, CLI contracts, configuration, parsing, or exit codes is covered by PHPUnit tests. Required coverage: AST parsing, Markdown format, config validation, full generation, incremental diff, error handling.
Installation
composer require sinefineinfinitum/ponymator
Usage
vendor/bin/ponymator [--full | --diff] [--config=<path>] [--help]
By default, Ponimator runs in diff mode — only regenerating documentation for changed source files.
Generated Documentation Example
The generated Markdown includes YAML frontmatter with a content hash and type, followed by a summary of the entity:
--- type: class hash: 3d8f1b2c9a0e --- # `App\Service\UserService` ## Head **Type**: class **Modifiers**: readonly **Parent**: `App\Abstracts\BaseService` **Interfaces**: `App\Contracts\ServiceInterface` ## Methods - public static function create(string $name, array $data = []): App\Models\User - public function findById(int $id, ?bool $active = true): ?App\Models\User ## Used by - [App\Contract\ServiceInterface](..\Contract\ServiceInterface.md) - `Vendor\Package\SomeClass` ## Dependencies - [App\Abstract\BaseService](..\Abstract\BaseService.md) - [App\Model\User](..\Model\User.md) ## Creates - `create`: [`App\Models\User`](..\Models\User.md) - `findById`: [`App\Models\User`](..\Models\User.md)
Requirements
- PHP ^8.0
- ext-json (usually built-in)
Development
composer install vendor/bin/phpunit vendor/bin/phpstan analyse vendor/bin/phpcs
Architecture
src/
├── Analyzer/ # AST parsing, entity & dependency extraction
│ ├── Extractor/ # — class, interface, trait, enum extractors
│ ├── Linker/ # — cross-reference index builder
│ ├── Visitor/ # — AST visitors (entities, deps, creations)
├── Cli/ # Argument parsing
├── Comparator/ # Hash-based file comparison
├── Documentation/ # Generation, cross-linking, rendering, cleanup
│ ├── Cleaner/ # — outdated doc removal
│ ├── Linker/ # — cross-reference resolution
│ ├── Processor/ # — page generation orchestration
│ └── Renderer/ # — per-entity Markdown renderers
├── Filesystem/ # Path resolution, file scanning
├── Config.php # Configuration loading & validation
└── Ponymator.php # Main orchestrator
Configuration
Configuration file: .ponymator.json. Example:
{
"source": "app",
"target": "api-docs",
"ignore": ["vendor", "node_modules"]
}
License
MIT