oomphinc/composer-installers-extender
Extends Composer Installers to add custom installer types and paths without forking. Define extra installer mappings for plugins/themes/modules and other packages, keeping your project’s directory structure consistent across Composer installs.
Installation Update Composer to require the new version (PHP 7.1+ and Composer 2+ required):
composer require --dev oomphinc/composer-installers-extender:^2.0
Ensure composer/installers is installed (required dependency):
composer require --dev composer/installers
Basic Configuration
Define custom installers in composer/installers-extender.json (auto-generated or manual):
{
"installers": {
"laravel-module": {
"type": "laravel-module",
"target": "modules/{$name}/",
"stub": "stubs/module.stub"
}
}
}
Update composer.json to include new dev dependencies:
{
"require-dev": {
"phpunit/phpunit": "^9.0",
"squizlabs/php_codesniffer": "^3.6",
"oomphinc/composer-installers-extender": "^2.0"
}
}
First Use Case Install a custom package type (e.g., a "module") via Composer:
composer require vendor/module-package:dev-main --dev
Verify files are installed in modules/module-package/ and include generated LICENSE/CHANGELOG.md.
Custom Package Types
Define reusable types (e.g., type: "laravel-theme") in installers-extender.json:
{
"installers": {
"laravel-theme": {
"type": "laravel-theme",
"target": "resources/themes/{$name}/",
"stub": "stubs/theme.stub"
}
}
}
Use stubs to generate boilerplate (e.g., LICENSE, CHANGELOG.md):
{# stubs/theme.stub #}
# LICENSE
Copyright © {{ year }}. All rights reserved.
Dynamic Paths with Placeholders
Leverage {$name}, {$version} in installer-paths:
"extra": {
"installer-paths": {
"packages/{$name}/src/{$name}/": ["type:laravel-package"],
"packages/{$name}/tests/": ["type:laravel-package"]
}
}
Post-Install Hooks
Combine with post-install-cmd to run scripts (e.g., PHPUnit tests):
"scripts": {
"post-install-cmd": [
"@php artisan vendor:publish --tag=config",
"@phpunit --testdox-html report.xml"
]
}
Multi-Package Projects
Use wildcards for grouped packages (e.g., type: "myvendor-*"):
"installer-paths": {
"vendor-packages/{$name}/": ["type:myvendor-*"]
}
Auto-Generated Documentation
Use stubs to include CHANGELOG.md/LICENSE in installed packages:
{# stubs/package.stub #}
## CHANGELOG
All notable changes to this project will be documented in this file.
PSR-2 Compliance
Leverage php_codesniffer in CI/CD pipelines:
"scripts": {
"cs-check": "phpcs --standard=PSR2 src/"
}
Namespace Resolution
Dynamically update config/app.php via stubs:
{# stubs/module.stub #}
'providers' => [
{{ namespace }}\\Providers\\{{ name }}ServiceProvider::class,
],
PHP/Composer Version Mismatch
Your Composer version (1.x) does not satisfy requirement (2.x).composer self-update
Namespace Changes
OomphInc\ComposerInstallersExtender\Installer moved to OomphInc\ComposerInstallersExtender\Installers\Installer.use OomphInc\ComposerInstallersExtender\Installers\Installer;
Missing Dev Dependencies
Class 'PHPUnit\Framework\TestCase' not found.composer require --dev phpunit/phpunit squizlabs/php_codesniffer
Stub File Changes
{{ year }} or other Twig variables.{{ year }} = {{ "now"|date("Y") }}
Composer 2 Quirks
composer clear-cache
composer require vendor/package --dry-run --no-install
COMPOSER_DEBUG=1 composer require vendor/package
vendor/composer/installed.json for details.Custom Installer Classes
Extend OomphInc\ComposerInstallersExtender\Installers\Installer:
namespace App\Composer;
use OomphInc\ComposerInstallersExtender\Installers\Installer;
class ModuleInstaller extends Installer {
protected $stub = __DIR__ . '/../../stubs/module.stub';
public function getInstallPath($package) {
return 'custom/' . $package->getName();
}
}
Register in installers-extender.json:
"installers": {
"laravel-module": {
"class": "App\\Composer\\ModuleInstaller"
}
}
Dynamic Stubs with Twig
Use Twig for dynamic content (e.g., {{ year }}):
{# stubs/license.stub #}
Copyright © {{ year }} Your Name. All rights reserved.
PSR-2 Enforcement
Add php_codesniffer to CI:
# .github/workflows/ci.yml
- name: PHP_CodeSniffer
run: phpcs --standard=PSR2 src/ tests/
/) for cross-platform paths.installer-paths unless explicitly supported.type: "myvendor-module") to avoid clashes.LICENSE/CHANGELOG.md if required by your project.How can I help you explore Laravel packages today?