I'm building a CLI application for my app using Symfony Console. The application is required to do some simple package management operations to manage plugins. Therefore, I need a command option named --version
with shortcut -v
, which does not seem to be possible since --version
is reserved for the application version and -v
is reserved for the default verbosity setting.
How can I either disable the default options or overwrite them for this subcommand?
The error popping up states
[Symfony\Component\Console\Exception\LogicException] An option named "version" already exists.
So, here is a solution that works, but I don't recommend it. I recommend you simply use --package-version
or some other sort of option for your command, because this requires a lot of extra work and doesn't play well for future Symfony updates.
The first thing you can do is copy the console
command in your bin/
directory to a new command, and change the use
statement to your own extended Application:
// use Symfony\Bundle\FrameworkBundle\Console\Application;
use AppBundle\Console\Application;
Then create a new Application
class that extends the existing Symfony Application, that looks like this:
namespace AppBundle\Console;
use AppBundle\Command\YourCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Event\ConsoleErrorEvent;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class TestApplication extends Application
{
const NAME = 'Alternative Application';
const VERSION = '1.0';
// these are normally private, but must now be protected as they exist in doRun()
protected $command;
protected $defaultCommand;
protected $dispatcher;
protected $runningCommand;
/**
* {@inheritdoc}
*/
public function __construct()
{
parent::__construct(static::NAME, static::VERSION);
// manually add the commands you want to be handled by this
$this->add(new YourCommand());
}
/**
* {@inheritdoc}
*/
public function doRun(InputInterface $input, OutputInterface $output)
{
/* remove these lines
if (true === $input->hasParameterOption(array('--version', '-V'), true)) {
$output->writeln($this->getLongVersion());
return 0;
}
*/
// copy the rest of the doRun() function as it
// exists in the base Application class
// ...
}
/**
* {@inheritdoc}
*
* Return everything from the default input definition except the 'version' option
*/
protected function getDefaultInputDefinition()
{
$definition = [];
$defaultDefinition = parent::getDefaultInputDefinition();
foreach ($defaultDefinition->getOptions() as $option) {
if ($option->getName() !== 'version') {
$definition[] = $option;
}
}
foreach ($defaultDefinition->getArguments() as $argument) {
$definition[] = $argument;
}
return new InputDefinition($definition);
}
}
Now add your application with your own --version
option:
namespace AppBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class YourCommand extends ContainerAwareCommand
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('your:command')
->addOption('--version', '-V', InputOption::VALUE_NONE, 'okay')
;
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if ($input->hasOption('version')) {
// do something
}
}
}
Then you can call your command via:
php bin/console your:command
php bin/console your:comand --version
Note that I do NOT recommend this. This is a lot of extra work for almost no gain at all other than saving yourself a few keystrokes with a different option now. Plus if bin/console
or Symfony\Component\Console\Application
changes in the future, or you'll have to manually update those files since you overrode them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With