Symfony 6 brings its CLI to the next level
Brace yourself: autocompletion on options and arguments is finally here!
One the most useful thing ever when using a command line interface is autocompletion. You know about it. If you don’t, well I hope your new to command line interfaces, otherwise you’re missing a whole world.
Anyway, just to be super quick and that everybody understands this, autocompletion gives you suggestion often based on a context. For example, let’s say you want to change the directory you’re in, autocompletion can give you the list of available directories. It can even “type” itself the end of your command if only one result match. It is way more powerful than that, but you get it.
Let’s see how Symfony is bringing its CLI user experience (UX) and developer experience (DX) to the next level since version 5.4/6.0.
If you used Symfony, you are probably familiar to its command line interface. The one you’re using when calling commands like
php bin/console c:c and so on. One big withdrawn before Symfony 5.4 is the lack of autocompletion. Wouldn’t it be nice to have command options and arguments values suggestions?
Thanks to Wouter de Jong and the whole Symfony community after the call to contributions, nearly all framework’s base command have autocompletion for most of their options and arguments! Here are a few examples:
- Suggest secrets names on
- Translation domains on
- Bus and queues in
- Available services in
- And so on.
When typing a command, simply press
TAB and boom! Suggestions will appear like magic. It will save us so much time. Adding this feature to all already available features of the Console component is absolutely mind blowing.
For now, this completion is available for bash only, but it is already planned to bring it to other shells as well.
What’s exciting is that you can also adapt this behavior to your own commands. Let’s see how!
On your custom commands
The first solution that was found when implementing this feature for internal commands was to additionally implement an additional and new interface on existing commands. But brace yourself: it’s been removed and it’s easier than ever now.
Symfony’s Command class now provides a method to override, called
complete where are available the input and the list of suggestions.
When overriding this command, we’ll be checking which argument or option we need to currently complete, as well as fill in the suggestions themselves. Here is how it looks:
This example shows us how to suggest argument values. Take note of the use of
mustSuggestArgumentValuesFor, as it will tell you with what you should fill your suggestions.
Actually, there are 4 possible cases for autocompletion, internally defined by Symfony’s CompletionInput class:
TYPE_NONE, when there’s nothing to complete. It is already implemented by the Console component ;
TYPE_OPTION_NAME, to complete an option name. This one’s already implemented by the Console component as well ;
TYPE_OPTION_VALUE, to complete the value of an option. That’s the first type that will really interest you here ;
TYPE_OPTION_ARGUMENT, to complete the value of an argument. This is the other one that will interest you in your commands.
Fortunately enough, you won’t have to deal with these constants, as helper methods already exist to do so in the component:
Note that there is indeed two different methods, depending if you’re completing an option or an argument. Super useful, isn’t it?
One last word on tests
That’s all great, but how do you test such a thing? I mean, how to do automated unit tests the clean way to check your suggestions are the ones you want?
This new feature also brings the CommandCompletionTester class to ease the task. It’s almost disturbing how simple it is to use it. By passing your command to the constructor of this class and by calling its
complete method, you’re good to go and ready to make any assert you need. Here is an example with the internal
You can see in the data provider that we’re giving the input (here, it’s
--format followed by an empty string), and the suggestions we want to get (“cli” and “html” in this case). Then we only have to assert that the completion matches the expected result and that’s it, our suggestions are tested!
Now we have the power of autocompletion right in our commands. And we even have a way to test them quickly. Symfony is taking CLI application to a whole new level with this.
Remember: even if it is a command line interface, the user experience is primordial!