The Console component will receive a lot of new features in Symfony 3.2, mostly related to improving its DX (developer experience). In this first of a three-part series, we introduce four of those new features.
Read the part 2 and part 3 of this series of articles explaining the new features of the Console component in Symfony 3.2.
Command aliases are no longer displayed as separate commands
Best practices recommend to define namespaced commands to avoid collisions and improve your application organization. However, for frequently executed commands, it's convenient to define shortcuts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
class VeryLongNameCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName('app:very:long:name')
->setDescription('Lorem Ipsum...')
// ...
->setAliases(['foo'])
;
}
// ...
}
In the above example, the command can be executed as ./bin/console app:very:long:name
and as ./bin/console foo
. Although there is just one command, Symfony will
show it as two separate commands:
1 2 3 4 5 6
$ ./bin/console
Available commands:
foo Lorem Ipsum...
app:
app:very:long:name Lorem Ipsum...
In Symfony 3.2 aliases are now inlined in their original commands, reducing the clutter of the console output:
1 2 3 4 5
$ ./bin/console
Available commands:
app:
app:very:long:name [foo] Lorem Ipsum...
Errors are now displayed even when using the quiet mode
If you add the -q
or --quiet
option when running a Symfony command, the
output is configured with the OutputInterface::VERBOSITY_QUIET
level. This
makes the command to not output any message, not even error messages.
In Symfony 3.2 we've improved the -q
and --quiet
options to keep
suppressing all the output except for the log messages of Logger::ERROR
level. This way you'll never miss an error message again.
Better support for one command applications
Building a single command application in Symfony is possible but it requires
you to make some changes to not pass the command name continuously. In Symfony
3.2 we've improved the base Application
class to support single command
applications out-of-the-box.
First, define a command as usual and create the console application. Then, set
the only command as the default command and pass true
as the second argument
of setDefaultCommand()
. That will turn the application into a single command
application:
1 2 3 4 5 6 7 8 9 10 11
use Symfony\Component\Console\Application;
$command = new \FooCommand();
$application = new Application();
$application->add($command);
// the second boolean argument tells if this is a single-command app
$application->setDefaultCommand($command->getName(), true);
// this now executes the 'FooCommand' without passing its name
$application->run();
Simpler command testing
Testing a Symfony command is unnecessarily complex and it requires you to go
deep into PHP streams. For example, if your test needs to simulate a user typing
123
, foo
and bar
, you have to do the following:
1 2 3 4 5 6 7 8 9 10 11 12 13
use Symfony\Component\Console\Tester\CommandTester;
$commandTester = new CommandTester($command);
$helper = $command->getHelper('question');
$helper->setInputStream($this->getInputStream("123\nfoo\nbar\n"));
protected function getInputStream($input)
{
$stream = fopen('php://memory', 'r+', false);
fputs($stream, $input);
rewind($stream);
return $stream;
}
In Symfony 3.2 we've simplified command testing by adding a new setInputs()
method to the CommandTester
helper. You just need to pass an array with the
contents that the user would type:
1 2 3 4
use Symfony\Component\Console\Tester\CommandTester;
$commandTester = new CommandTester($command);
$commandTester->setInputs(['123', 'foo', 'bar']);
Wow ! Thank you to contributors, big up to new easy way to do single command application :)
Thanks for making Symfony Commands more usable :)
Great improvements, thank a lot to all who made this happen!
Great work, thanks to all contributors! :)
Great work! Especially the Testing part was quite annoying before