Skip to content

Commit

Permalink
Merge pull request #87 from stecman/conflicting-options
Browse files Browse the repository at this point in the history
Prevent global/application options conflicting with CompletionCommand
  • Loading branch information
stecman committed Jan 19, 2019
2 parents 4d1901e + 08a5263 commit bd07a24
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 1 deletion.
47 changes: 46 additions & 1 deletion src/CompletionCommand.php
Expand Up @@ -10,7 +10,6 @@

class CompletionCommand extends SymfonyCommand
{

/**
* @var CompletionHandler
*/
Expand Down Expand Up @@ -49,6 +48,52 @@ public function getNativeDefinition()
return $this->createDefinition();
}

/**
* Ignore user-defined global options
*
* Any global options defined by user-code are meaningless to this command.
* Options outside of the core defaults are ignored to avoid name and shortcut conflicts.
*/
public function mergeApplicationDefinition($mergeArgs = true)
{
// Get current application options
$appDefinition = $this->getApplication()->getDefinition();
$originalOptions = $appDefinition->getOptions();

// Temporarily replace application options with a filtered list
$appDefinition->setOptions(
$this->filterApplicationOptions($originalOptions)
);

parent::mergeApplicationDefinition($mergeArgs);

// Restore original application options
$appDefinition->setOptions($originalOptions);
}

/**
* Reduce the passed list of options to the core defaults (if they exist)
*
* @param InputOption[] $appOptions
* @return InputOption[]
*/
protected function filterApplicationOptions(array $appOptions)
{
return array_filter($appOptions, function(InputOption $option) {
static $coreOptions = array(
'help' => true,
'quiet' => true,
'verbose' => true,
'version' => true,
'ansi' => true,
'no-ansi' => true,
'no-interaction' => true,
);

return isset($coreOptions[$option->getName()]);
});
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$this->handler = new CompletionHandler($this->getApplication());
Expand Down
@@ -0,0 +1,41 @@
<?php

namespace Stecman\Component\Symfony\Console\BashCompletion\Tests;

use PHPUnit\Framework\TestCase;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;

class CompletionCommandTest extends TestCase
{
/**
* Ensure conflicting options names and shortcuts from the application do not break the completion command
*/
public function testConflictingGlobalOptions()
{
$app = new Application('Base application');

// Conflicting option shortcut
$app->getDefinition()->addOption(
new InputOption('conflicting-shortcut', 'g', InputOption::VALUE_NONE)
);

// Conflicting option name
$app->getDefinition()->addOption(
new InputOption('program', null, InputOption::VALUE_REQUIRED)
);

$app->add(new CompletionCommand());

// Check completion command doesn't throw
$app->doRun(new StringInput('_completion -g --program foo'), new NullOutput());
$app->doRun(new StringInput('_completion --help'), new NullOutput());
$app->doRun(new StringInput('help _completion'), new NullOutput());

// Check default options are available
$app->doRun(new StringInput('_completion -V -vv --no-ansi --quiet'), new NullOutput());
}
}

0 comments on commit bd07a24

Please sign in to comment.