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

Juan Miguel Rodriguez
Contributed by Juan Miguel Rodriguez in #18790

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

Olaf Klischat
Contributed by Olaf Klischat in #18781

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

Grégoire Pineau
Contributed by Grégoire Pineau in #16906

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

Robin Chalas
Contributed by Robin Chalas in #18710

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']);
Published in #Living on the edge