Remove all services arguments from Symfony config with a script
I'm helping a team migrate from Symfony 3.4 to a newer version of the framework. One of our objectives is to move away from using the container to get access to services and use dependency injection instead. Our first step was enabling auto wiring, which should simplify the rest of the work because the framework will automagically inject every new service we add to the constructor directly into the service—no need to edit any configuration.
The next step we plan is to use Rector to transform every call to Container::get
to dependency injection.
Rector will save us tremendous time by refactoring the code but will not touch the configuration. In the configuration, when a service definition declares the service arguments, it takes precedence over the auto wiring. We need to clean all the configuration files by removing the arguments declaration.
I decided to see if I could use awk
to script that and avoid the manual work requested on many different config files, and I managed to do so in less time than expected. Practicing some awk
katas was worth it, after all.
Here is the script. It looks for arguments:
and sets a variable indicating that we are in an argument block. Once in that block, we look for the first line not starting with -
to say we are out of the argument block. The script prints every line outside arguments blocks, when ARGUMENT_BLOCK == 0
.
BEGIN {
ARGUMENT_BLOCK == 0
}
ARGUMENT_BLOCK == 1 && !/[[:blank:]]*-/ {
ARGUMENT_BLOCK = 0
}
/arguments:/ {
ARGUMENT_BLOCK = 1
}
ARGUMENT_BLOCK == 0 {print $0}
Here is an example of a diff once the script was used on a services.yaml
file. Note that the script deals with the single and multiline YAML array format.
@@ -2,29 +2,12 @@
sdk.entity.list:
class: XXX\ListsRepository
factory: [ '@doctrine.orm.default_entity_manager', 'getRepository' ]
- arguments:
- - 'SDKListBundle:Lists'
sdk.service.list:
class: XXX\ListBundle\Services\Lists
- arguments:
- - '@service_container'
- - '@event_dispatcher'
- - '@sdk.entity.list'
sdk.entity.list_access_set:
class: XXX\Repository\ListAccessSetRepository
factory: [ '@doctrine.orm.default_entity_manager', 'getRepository' ]
- arguments: ['SDKListBundle:ListAccessSet']
sdk.service.list_access_set:
class: XXX\Services\ListAccessSet
- arguments:
- - '@sdk.entity.list_access_set'
- - '@sdk.entity.mapping_list_access_set'
- - '@logger'
\ No newline at end of file
To run the script on a single file you can use awk -i inplace -f script file
.
And if you have a lot of services.yaml
files to edit at once, you can use a combination of find
, xargs
and awk
:find ./src -name services.yml | xargs awk -i inplace -f script
.
That step is now automated; we don't need to edit hundreds or more service definitions manually. A few minutes of work and a lot of time saved.
- Improve your automated testing : You will learn how to fix your tests and make them pass from things that slow you down to things that save you time. This is a self-paced video course in French.
- Helping your teams: I help software teams deliver better software sooner. We'll work on technical issues with code, test or architecture, or the process and organization depending on your needs. Book a free call where we'll discuss how things are going on your side and how I can help you.
- Deliver a talk in your organization: I have a few talks that I enjoy presenting, and I can share with your organization(meetup, conference, company, BBL). If you feel that we could work on a new topic together, let's discuss that.