Installation:
composer require --dev sweetchuck/composer-suite
Define Suites:
Add suite configurations to your composer.json under extra/composer-suite:
"extra": {
"composer-suite": {
"suite-name": {
"description": "Suite description",
"actions": [
{
"type": "replaceRecursive",
"config": {
"parents": ["require"],
"items": {
"laravel/framework": "^8.0"
}
}
}
]
}
}
}
Generate Suites:
composer suite:generate
This creates files like composer.suite-name.json.
Activate a Suite:
export COMPOSER='composer.suite-name.json'
composer update
Dependency Version Testing:
Create suites for testing different dependency versions (e.g., Laravel 8 vs. Laravel 9). Use replaceRecursive to override version constraints in require or require-dev.
Multi-Environment Development:
prepend/append to add local repositories for development:
"actions": [
{
"type": "prepend",
"config": {
"parents": ["repositories"],
"items": {
"local/package": {
"type": "path",
"url": "../path/to/package"
}
}
}
}
]
composer suite:generate
export COMPOSER='composer.local.json'
composer update
CI/CD Matrix Testing:
Feature Flagging:
unset to conditionally remove dev dependencies:
"actions": [
{
"type": "unset",
"config": {
"parents": ["require-dev", ["phpunit/phpunit"]]
}
}
]
Laravel-Specific:
laravel/framework versions for testing migrations or features across versions.insertBefore/insertAfter to modify autoload-dev for testing custom PSR-4 paths.External Files:
Store suite definitions in .composer-suite/composer-suite.*.json for non-VCS-sensitive configurations (e.g., team-specific setups).
Validation: Add a script to validate active suites:
composer validate && composer suite:list
CI/CD:
Use COMPOSER env var in GitHub Actions/CircleCI to dynamically switch suites:
jobs:
test:
env:
COMPOSER: 'composer.laravel9.json'
Path Resolution:
repositories or extra must be absolute when using generated suites. Use ../../ or $PWD for consistency.realpath() in scripts to resolve paths dynamically.Suite Priority:
Lock File Conflicts:
composer.lock. Always:
cp composer.lock composer.suite-name.lock
before switching suites.
Action Order:
description to clarify intent:
"actions": [
{ "type": "prepend", "config": { ... }, "description": "Add local repos" },
{ "type": "replaceRecursive", "config": { ... }, "description": "Pin versions" }
]
Schema Changes:
actions key format (see release notes).Dry Runs:
Use composer -vv suite:generate to see applied changes without writing files.
Validate Suites:
COMPOSER='composer.suite-name.json' composer validate
Exit code 0 = valid; non-zero = errors (e.g., circular dependencies).
List Suites:
composer suite:list
Verify generated files and their descriptions.
Custom Actions: Extend the plugin by adding new action types. Example:
// In a custom plugin
$suite->addAction('customAction', function ($config, $json) {
// Modify $json array here
});
Post-Generation Hooks:
Use Composer’s post-autoload-dump script to run tasks after suite activation:
"scripts": {
"post-autoload-dump": [
"@php artisan optimize:clear",
"php artisan config:clear"
]
}
Dynamic Suites:
Generate suites programmatically via Composer’s post-install-cmd or post-update-cmd:
"scripts": {
"post-install-cmd": [
"php vendor/bin/composer-suite generate --suite=dynamic"
]
}
Template Suites:
Store boilerplate suites in a templates/ directory and symlink them into .composer-suite/ for reuse across projects.
Git Ignore:
Add generated files to .gitignore:
composer.*.json
composer.*.lock
Laravel Mix: Combine with Laravel Mix for environment-specific asset builds:
// mix.js
if (process.env.MIX_COMPOSER_SUITE === 'local') {
mix.webpackConfig.devtool = 'source-map';
}
Set MIX_COMPOSER_SUITE via a script that reads COMPOSER.
How can I help you explore Laravel packages today?