genericmilk/docudoodle
AI-powered PHP documentation generator that analyzes your codebase and creates comprehensive Markdown docs. Supports smart caching, skips existing docs, and enables quick top-up runs. Great for onboarding teams to undocumented apps fast.
Installation:
composer require genericmilk/docudoodle
php artisan vendor:publish --tag=docudoodle-config
This publishes the config file to config/docudoodle.php.
Configure API Key (e.g., OpenAI):
Add to .env:
OPENAI_API_KEY=sk-your-api-key
DOCUDOODLE_API_PROVIDER=openai
First Run:
php artisan docudoodle:generate
Outputs Markdown files to storage/docudoodle (configurable).
For a Laravel project with no existing docs, run:
php artisan docudoodle:generate --extensions=php,blade --skip-dirs="vendor/,tests/"
This generates docs for all PHP/Blade files, skipping test and vendor directories.
Incremental Updates: After implementing a feature, run:
php artisan docudoodle:generate --force-rebuild=false
Only reprocesses changed files (thanks to caching).
Team Sync:
Use --jira or --confluence flags to push docs directly to collaboration tools:
php artisan docudoodle:generate --jira --no-files
CI/CD Integration:
Add to phpunit.xml or GitHub Actions:
<php>
<env name="OPENAI_API_KEY" value="${env.OPENAI_API_KEY}"/>
</php>
Run as part of your deploy pipeline to auto-update docs.
Service Container Binding:
Extend Docudoodle’s DocudoodleServiceProvider to inject custom logic:
// app/Providers/DocudoodleServiceProvider.php
public function register()
{
$this->app->bind('docudoodle.prompt', function () {
return new CustomPromptTemplate();
});
}
Event Listeners: Trigger doc generation post-deploy:
// app/Listeners/GenerateDocsAfterDeploy.php
public function handle(Deployed $event)
{
Artisan::call('docudoodle:generate', [
'--force-rebuild' => true,
]);
}
Custom Output Directories:
Override output_dir in config:
'output_dir' => storage_path('app/docs'),
Use php artisan storage:link to expose docs at /docs.
Multi-Provider Workflows:
Use --api-provider=ollama for offline docs:
php artisan docudoodle:generate --api-provider=ollama --ollama-model=llama3
Template Customization:
Create a resources/docudoodle/templates/custom.md:
## {BASE_NAME}
**Namespace**: {DIRECTORY}
**Content**:
```php
{FILE_CONTENT}
Reference in .env:
DOCUDOODLE_PROMPT_TEMPLATE=resources/docudoodle/templates/custom.md
Orphan Cleanup: Automatically remove docs for deleted files by enabling caching:
'use_cache' => true,
API Key Leaks:
.env and add it to .gitignore. Validate keys in bootstrap/app.php:
if (empty(env('OPENAI_API_KEY'))) {
throw new RuntimeException('API key not set!');
}
Token Limits:
app/Providers/AppServiceProvider.php) may exceed max_tokens.max_tokens in config:
'max_tokens' => 5000,
Caching Quirks:
default_model).php artisan docudoodle:generate --force-rebuild
Wildcard Skipping:
skip_dirs with wildcards (e.g., */tests/*) may not work as expected.'skip_dirs' => ['tests/', 'database/migrations/'],
Dry Runs:
Use --no-files to test API calls without writing files:
php artisan docudoodle:generate --no-files --verbose
Log API Responses:
Enable Laravel’s debug mode and check storage/logs/laravel.log for API errors.
Template Errors: Validate custom templates with:
php artisan docudoodle:generate --template=path/to/template.md --dry-run
Custom Prompt Logic:
Override Docudoodle\Docudoodle::generatePrompt():
// app/Providers/DocudoodleServiceProvider.php
$this->app->afterResolving('docudoodle', function ($docudoodle) {
$docudoodle->setPromptGenerator(function ($file) {
return "Custom prompt for {$file->getPathname()}";
});
});
Post-Processing Docs:
Listen for docudoodle.generated event:
// app/Listeners/ProcessDocs.php
public function handle(DocumentGenerated $event)
{
$content = $event->content;
// Add custom metadata, e.g., last updated timestamp
$content .= "\n\n**Last Updated**: " . now()->format('Y-m-d');
file_put_contents($event->path, $content);
}
Azure OpenAI Debugging: Enable verbose output:
php artisan docudoodle:generate --api-provider=azure --verbose
Check for 401 Unauthorized errors (invalid API key/deployment).
Parallel Processing: Use Laravel’s queue system to process files in parallel:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
$schedule->command('docudoodle:generate')
->everyMinute()
->withoutOverlapping();
}
Ollama Optimization:
For local generation, reduce max_tokens and use smaller models:
DOCUDOODLE_MODEL=llama3:8b
DOCUDOODLE_MAX_TOKENS=2000
Exclude Heavy Files:
Add large files to skip_dirs:
'skip_dirs' => [
'vendor/',
'tests/',
'storage/logs/',
'app/Console/Kernel.php', // Exclude specific files
],
Artisan Command Aliases:
Add to app/Console/Kernel.php:
protected $commands = [
\GenericMilk\Docudoodle\Console\DocudoodleCommand::class,
];
Now use php artisan docudoodle instead of php artisan docudoodle:generate.
Route Caching: If docs include route lists, cache them:
// app/Providers/RouteServiceProvider.php
public function boot()
{
$this->routes->cache(function () {
Artisan::call('docudoodle:generate', [
'--extensions' => 'php',
'--skip-dirs' => 'routes/',
]);
});
}
Testing: Mock the AI provider in tests:
// tests/Feature/DocudoodleTest.php
public function test_generation()
{
$this->mock(\GenericMilk\Docudoodle\Contracts\AIProvider::class, function ($mock) {
$mock->shouldReceive('generate')
->once()
->andReturn("Mocked docs");
});
$this->artisan('docudoodle:generate')->assertExitCode(0);
}
How can I help you explore Laravel packages today?