Skip to content

Commit 05f7dbf

Browse files
committed
Initial release
0 parents  commit 05f7dbf

16 files changed

+7844
-0
lines changed

.gitattributes

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/.github export-ignore
2+
/examples export-ignore
3+
/tests export-ignore
4+
.* export-ignore
5+
/captainhook.json export-ignore
6+
/composer.json
7+
/composer.lock export-ignore
8+
/phpstan.neon export-ignore
9+
/phpstan.php export-ignore
10+
/phpunit.xml export-ignore

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: [ruudk]

.github/workflows/ci.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
matrix:
15+
php-version: ['8.4']
16+
17+
name: PHP ${{ matrix.php-version }}
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- name: Setup PHP
23+
uses: shivammathur/setup-php@v2
24+
with:
25+
php-version: ${{ matrix.php-version }}
26+
27+
- name: Validate composer.json and composer.lock
28+
run: composer validate --strict
29+
30+
- name: Cache Composer packages
31+
id: composer-cache
32+
uses: actions/cache@v4
33+
with:
34+
path: vendor
35+
key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}
36+
restore-keys: |
37+
${{ runner.os }}-php-${{ matrix.php-version }}-
38+
39+
- name: Install dependencies
40+
run: composer install --prefer-dist --no-progress
41+
42+
- name: Check composer.json normalization
43+
run: composer normalize --diff --dry-run
44+
45+
- name: Check dependencies
46+
run: vendor/bin/composer-dependency-analyser
47+
48+
- name: Run PHP CS Fixer
49+
run: vendor/bin/php-cs-fixer check --diff
50+
51+
- name: Run PHPStan
52+
run: vendor/bin/phpstan analyse
53+
54+
- name: Run tests
55+
run: vendor/bin/phpunit

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/vendor/
2+
/.phpunit.cache/
3+
/.php-cs-fixer.cache

.php-cs-fixer.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use PhpCsFixer\Finder;
6+
use Ticketswap\PhpCsFixerConfig\PhpCsFixerConfigFactory;
7+
use Ticketswap\PhpCsFixerConfig\RuleSet\TicketSwapRuleSet;
8+
9+
$finder = Finder::create()
10+
->in(__DIR__ . '/examples')
11+
->in(__DIR__ . '/src')
12+
->in(__DIR__ . '/tests')
13+
->append([__DIR__ . '/.php-cs-fixer.php']);
14+
15+
return PhpCsFixerConfigFactory::create(TicketSwapRuleSet::create())->setFinder($finder);

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Ruud Kamphuis
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
<p align="center">
2+
<strong>Symfony Config Code Generator</strong><br>
3+
<em>Transform ContainerBuilder configurations into modern Symfony configuration files with zero effort</em>
4+
</p>
5+
<p align="center">
6+
<a href="https://packagist.org/packages/ruudk/symfony-config-code-generator"><img src="https://poser.pugx.org/ruudk/symfony-config-code-generator/v?style=for-the-badge" alt="Latest Stable Version"></a>
7+
<a href="https://packagist.org/packages/ruudk/symfony-config-code-generator"><img src="https://poser.pugx.org/ruudk/symfony-config-code-generator/require/php?style=for-the-badge" alt="PHP Version Require"></a>
8+
<a href="https://packagist.org/packages/ruudk/symfony-config-code-generator"><img src="https://poser.pugx.org/ruudk/symfony-config-code-generator/downloads?style=for-the-badge" alt="Total Downloads"></a>
9+
<a href="https://packagist.org/packages/ruudk/symfony-config-code-generator"><img src="https://poser.pugx.org/ruudk/symfony-config-code-generator/license?style=for-the-badge" alt="License"></a>
10+
</p>
11+
12+
------
13+
14+
# Symfony Config Code Generator
15+
16+
**Convert your runtime ContainerBuilder into beautiful, production-ready Symfony configuration files!**
17+
18+
This library bridges the gap between programmatic container building and modern Symfony configuration, making it perfect for migrations, code generation tools, and bundle configuration exports.
19+
20+
## ✨ Why This Library?
21+
22+
Ever needed to convert a dynamically built Symfony container into static configuration files? Migrating from legacy code? Building developer tools that generate Symfony configs? **This is your solution!**
23+
24+
🎯 **Runtime to Config** - Transform ContainerBuilder instances into modern Symfony configuration
25+
🎯 **Full Feature Support** - Handles all Symfony DI features: autowiring, tags, aliases, decorators, and more
26+
🎯 **Clean Output** - Generates human-readable configuration using Symfony's best practices
27+
🎯 **Smart Imports** - Automatically manages function imports and namespaces
28+
🎯 **Type Safety** - Preserves references, parameters, and expressions correctly
29+
30+
## 🚀 Key Features
31+
32+
### 🎨 Complete Symfony DI Support
33+
- **Services** - Full service definitions with classes, arguments, and method calls
34+
- **Parameters** - Regular parameters and environment variables
35+
- **References** - Service references, typed references, and inner references
36+
- **Tags** - Service tags with attributes for event listeners, commands, etc.
37+
- **Autowiring & Autoconfigure** - Modern DI features preserved
38+
- **Decorators** - Service decoration with priority support
39+
- **Aliases** - Service and interface aliases
40+
- **Expressions** - Expression language support for dynamic values
41+
- **Tagged Iterators** - Inject collections of tagged services
42+
- **Environment-specific** - Conditional service registration
43+
44+
### 🔧 Smart Code Generation
45+
- **Clean Formatting** - Properly indented, readable output
46+
- **Automatic Imports** - Function imports added automatically
47+
- **Fluent Interface** - Modern configurator syntax
48+
- **Type Preservation** - Maintains type information for better IDE support
49+
50+
## 📦 Installation
51+
52+
Install via Composer:
53+
54+
```bash
55+
composer require ruudk/symfony-config-code-generator --dev
56+
```
57+
58+
## 💡 Usage
59+
60+
Transform your ContainerBuilder into a configuration file in seconds:
61+
62+
<!-- source: examples/example.php -->
63+
```php
64+
<?php
65+
66+
declare(strict_types=1);
67+
68+
include 'vendor/autoload.php';
69+
70+
use Ruudk\SymfonyConfigCodeGenerator\SymfonyConfigCodeGenerator;
71+
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
72+
use Symfony\Component\DependencyInjection\ContainerBuilder;
73+
use Symfony\Component\DependencyInjection\Reference;
74+
use Symfony\Component\ExpressionLanguage\Expression;
75+
76+
$container = new ContainerBuilder();
77+
78+
// Parameters
79+
$container->setParameter('app.debug', true);
80+
$container->setParameter('database.url', '%env(DATABASE_URL)%');
81+
82+
// Simple service with autowiring
83+
$container->register('app.logger', 'Psr\Log\LoggerInterface')
84+
->setAutowired(true);
85+
86+
// Service with arguments and method calls
87+
$container->register('app.mailer', 'App\Service\MailerService')
88+
->addArgument(new Reference('mailer.transport'))
89+
->addArgument('%database.url%')
90+
->addMethodCall('setLogger', [new Reference('app.logger')])
91+
->addMethodCall('configure', [[
92+
'from' => '[email protected]',
93+
]]);
94+
95+
// Event listener with tags
96+
$container->register('app.request_listener', 'App\EventListener\RequestListener')
97+
->addTag('kernel.event_listener', [
98+
'event' => 'kernel.request',
99+
'priority' => 100,
100+
]);
101+
102+
// Service with expression
103+
$container->register('app.feature_service', 'App\Service\FeatureService')
104+
->addArgument(new Expression('parameter("app.debug") ? "debug" : "production"'));
105+
106+
// Service with tagged iterator
107+
$container->register('app.handler_registry', 'App\Service\HandlerRegistry')
108+
->addArgument(new TaggedIteratorArgument('app.handler'));
109+
110+
// Tagged services
111+
$container->register('app.user_handler', 'App\Handler\UserHandler')
112+
->addTag('app.handler');
113+
114+
// Generate the configuration
115+
echo new SymfonyConfigCodeGenerator()->dumpFile($container);
116+
```
117+
118+
### Output
119+
120+
<!-- output: examples/example.php -->
121+
```php
122+
<?php
123+
124+
declare(strict_types=1);
125+
126+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
127+
use function Symfony\Component\DependencyInjection\Loader\Configurator\env;
128+
use function Symfony\Component\DependencyInjection\Loader\Configurator\expr;
129+
use function Symfony\Component\DependencyInjection\Loader\Configurator\param;
130+
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
131+
use function Symfony\Component\DependencyInjection\Loader\Configurator\tagged_iterator;
132+
133+
// This file was automatically generated and should not be edited.
134+
135+
return static function (ContainerConfigurator $configurator) : void {
136+
$parameters = $configurator->parameters();
137+
$parameters->set(
138+
'app.debug',
139+
true,
140+
);
141+
$parameters->set(
142+
'database.url',
143+
env('DATABASE_URL'),
144+
);
145+
146+
$services = $configurator->services();
147+
148+
$services->set(
149+
'app.feature_service',
150+
\App\Service\FeatureService::class,
151+
)
152+
->args(
153+
[
154+
expr('parameter("app.debug") ? "debug" : "production"'),
155+
],
156+
);
157+
158+
$services->set(
159+
'app.handler_registry',
160+
\App\Service\HandlerRegistry::class,
161+
)
162+
->args(
163+
[
164+
tagged_iterator('app.handler'),
165+
],
166+
);
167+
168+
$services->set(
169+
'app.logger',
170+
\Psr\Log\LoggerInterface::class,
171+
)
172+
->autowire();
173+
174+
$services->set(
175+
'app.mailer',
176+
\App\Service\MailerService::class,
177+
)
178+
->args(
179+
[
180+
service('mailer.transport'),
181+
param('database.url'),
182+
],
183+
)
184+
->call(
185+
'setLogger',
186+
[
187+
service('app.logger'),
188+
],
189+
)
190+
->call(
191+
'configure',
192+
[
193+
[
194+
'from' => '[email protected]',
195+
],
196+
],
197+
);
198+
199+
$services->set(
200+
'app.request_listener',
201+
\App\EventListener\RequestListener::class,
202+
)
203+
->tag(
204+
'kernel.event_listener',
205+
[
206+
'event' => 'kernel.request',
207+
'priority' => 100,
208+
],
209+
);
210+
211+
$services->set(
212+
'app.user_handler',
213+
\App\Handler\UserHandler::class,
214+
)
215+
->tag('app.handler');
216+
};
217+
```
218+
219+
## 🎯 Perfect For
220+
221+
- **Legacy Migration** - Convert old bundle configurations to modern format
222+
- **Code Generation** - Build tools that output Symfony configurations
223+
- **Configuration Export** - Export runtime container state for debugging
224+
- **Bundle Development** - Generate configuration examples from code
225+
- **Testing** - Verify container configurations programmatically
226+
227+
## 🏗️ Built With
228+
229+
This library is powered by [ruudk/code-generator](https://github.com/ruudk/code-generator), providing robust code generation capabilities with automatic formatting and imports.
230+
231+
## 💖 Support This Project
232+
233+
Love this tool? Help me keep building awesome open source software!
234+
235+
[![Sponsor](https://img.shields.io/badge/Sponsor-%E2%9D%A4-pink)](https://github.com/sponsors/ruudk)
236+
237+
Your sponsorship helps me dedicate more time to maintaining and improving this project. Every contribution, no matter the size, makes a difference!
238+
239+
## 🤝 Contributing
240+
241+
I welcome contributions! Whether it's a bug fix, new feature, or documentation improvement, I'd love to see your PRs.
242+
243+
## 📄 License
244+
245+
MIT License – Free to use in your projects! If you're using this and finding value, please consider [sponsoring](https://github.com/sponsors/ruudk) to support continued development.

captainhook.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"commit-msg": {
3+
"enabled": true,
4+
"actions": []
5+
},
6+
"pre-commit": {
7+
"enabled": true,
8+
"actions": [
9+
{
10+
"action": "composer validate --strict"
11+
},
12+
{
13+
"action": "composer normalize --diff --dry-run"
14+
},
15+
{
16+
"action": "\\CaptainHook\\App\\Hook\\PHP\\Action\\Linting"
17+
},
18+
{
19+
"action": "cd examples && for file in *.php; do echo \"Testing examples/$file...\"; php \"$file\" > /dev/null 2>&1 || { echo \"✗ Failed: examples/$file\"; exit 1; }; echo \"✓ Passed: examples/$file\"; done",
20+
"options": {
21+
"label": "Validate example files"
22+
}
23+
},
24+
{
25+
"action": "\\Ruudk\\ReadmeExamplesSyncHook\\SyncReadmeExamples"
26+
},
27+
{
28+
"action": "vendor/bin/php-cs-fixer check --diff"
29+
},
30+
{
31+
"action": "vendor/bin/phpstan"
32+
},
33+
{
34+
"action": "vendor/bin/phpunit"
35+
}
36+
]
37+
}
38+
}

0 commit comments

Comments
 (0)