klitsche/dog
Dog is a lightweight source code documentation generator for PHP libraries. Built on phpDocumentor/reflection and Twig, it analyzes code and phpdoc, validates documentation with configurable rules, and outputs Markdown suitable for MkDocs and similar tools.
Installation:
composer require --dev klitsche/dog
Add the package to your devDependencies in composer.json.
Configuration:
Create .dog.yml in your project root with minimal config:
srcPaths:
'src': '/.*\.php$/'
outputDir: 'docs/api'
First Run:
vendor/bin/dog --analyze
This checks your codebase for documentation issues without generating output.
Generate Docs:
vendor/bin/dog
Generates Markdown documentation in docs/api.
For a Laravel project, configure .dog.yml to target app/ and exclude migrations:
title: 'Laravel API Reference'
srcPaths:
'app':
'/.*\.php$/': true
'/migrations/': false
'/tests/': false
outputDir: 'docs/api'
rules:
PublicFileDocBlockMissingRule:
issueLevel: 'ignore' # Skip file-level docblocks for Laravel's auto-generated files
Run vendor/bin/dog to generate API docs for controllers, services, and models.
CI/CD Pipeline: Add to your CI (e.g., GitHub Actions) to enforce documentation standards:
- name: Check Documentation
run: vendor/bin/dog --analyze
Fail the build if --analyze reports error issues.
Pre-Commit Hook:
Use husky or pre-commit to run dog --analyze before commits:
# .husky/pre-commit
vendor/bin/dog --analyze
Laravel Artisan Command: Create a custom Artisan command to trigger documentation generation:
// app/Console/Commands/GenerateDocs.php
public function handle() {
$this->call('vendor:publish', ['--provider' => 'Klitsche\Dog\DogServiceProvider']);
$this->info('Generating documentation...');
shell_exec(base_path('vendor/bin/dog'));
}
Register it in app/Console/Kernel.php:
protected $commands = [
Commands\GenerateDocs::class,
];
Run with:
php artisan generate:docs
Excluding Internal Code:
Use srcPaths to exclude app/Providers/, app/Exceptions/, or app/Console/:
srcPaths:
'app':
'/Providers/': false
'/Console/': false
Customizing Rules for Laravel:
Laravel’s auto-generated files (e.g., app/Providers/AppServiceProvider) often lack docblocks. Adjust rules:
rules:
PublicClassDocBlockMissingRule:
issueLevel: 'ignore'
match:
getElementType: 'Class'
isInternal: true
Enriching with Coverage Data:
Add clover.xml (from PHPUnit) to highlight tested/untested code:
enrichers:
clover:
class: \Klitsche\Dog\Enrichers\Clover\CloverEnricher
file: storage/logs/clover.xml
Custom Printers:
Extend the Markdown printer for Laravel-specific templates (e.g., highlight Illuminate\Contracts):
// app/Providers/DogServiceProvider.php
public function boot() {
$this->app->bind(
'Klitsche\Dog\Printer\Markdown\Printer',
CustomMarkdownPrinter::class
);
}
False Positives in Laravel:
__get(), __set()) may trigger DocBlockMethodAllowedRule. Exclude them:
rules:
DocBlockMethodAllowedRule:
match:
getName: ['!__get', '!__set']
Hash) often lack docblocks. Ignore them:
rules:
PublicClassDocBlockMissingRule:
match:
getFqsen: ['!Illuminate\Support\Facades\Hash']
Output Directory Not Cleared:
dog does not purge outputDir. Add a pre-command to clear it:
rm -rf docs/api && vendor/bin/dog
Or use a Laravel Artisan command:
public function handle() {
File::cleanDirectory(public_path('docs/api'));
shell_exec(base_path('vendor/bin/dog'));
}
PHP 8.0+ Attributes:
dog may misparse attributes (e.g., [Route]) as docblock tags. Exclude files with attributes:
srcPaths:
'app/Http/Controllers':
'/.*\.php$/': true
'/.*\[.*\]/': false # Exclude files with attributes
Circular Dependencies:
If dog hangs, your project may have circular references. Use --debug to log the analysis path:
vendor/bin/dog --debug
Inspect Analysis:
Run with --debug to see which files/rules are being evaluated:
vendor/bin/dog --debug
Outputs a log to storage/logs/dog.log.
Validate Config:
Use vendor/bin/dog --analyze --format=json to get a machine-readable list of issues:
vendor/bin/dog --analyze --format=json > issues.json
Parse issues.json in PHP to filter or customize responses.
Test Rules Locally:
Create a minimal test case (e.g., tests/RuleTest.php) and point srcPaths to it:
srcPaths:
'tests': '/.*RuleTest\.php$/'
Custom Enrichers: Add project-specific data (e.g., Laravel tags, GitHub issues):
// app/Providers/DogServiceProvider.php
public function register() {
$this->app->bind(
'Klitsche\Dog\Enrichers\GitHubIssuesEnricher',
function () {
return new GitHubIssuesEnricher(
config('github.token'),
config('github.repo')
);
}
);
}
Configure in .dog.yml:
enrichers:
github:
class: \App\Enrichers\GitHubIssuesEnricher
Override Default Rules: Disable or modify rules dynamically in a Laravel service provider:
public function boot() {
$config = config('dog.rules');
$config['PublicMethodDocBlockMissingRule']['issueLevel'] = 'ignore';
config(['dog.rules' => $config]);
}
Template Customization:
Extend the Twig templates in vendor/klitsche/dog/src/Printer/Markdown/templates:
cp -r vendor/klitsche/dog/src/Printer/Markdown/templates resources/views/dog/
Override the printer class to use your templates:
// app/Providers/DogServiceProvider.php
public function boot() {
$this->app->bind(
'Klitsche\Dog\Printer\Markdown\Printer',
function () {
return new \Klitsche\Dog\Printer\Markdown\Printer(
app()->basePath('resources/views/dog')
);
}
);
}
Service Container Binding:
If dog fails to load, ensure its service provider is registered:
// config/app.php
'providers' => [
// ...
Klitsche\Dog\DogServiceProvider::class,
],
Facade Conflicts:
Avoid naming your config file .dog.php (conflicts with Laravel’s config). Stick to .dog.yml.
Queue Workers:
If running dog in a queue job, set outputDir to a writable location (e.g., storage/app/docs).
How can I help you explore Laravel packages today?