feature #11431 [Console] End of options (--) signal support (Seldaek)
This PR was squashed before being merged into the 3.0-dev branch (closes #11431).
Discussion
----------
[Console] End of options (--) signal support
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | yes
| BC breaks? | yes-ish
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
| Doc PR |
The first commit is only about -- support + fixes a few other little issues I discovered while adding tests to cover my feature.
The second commit makes use of the first in the Application class, so that if you do `console foo -- --help` for example, it should not trigger the help anymore, but simply have --help available as a dummy arg.
To keep BC, I did this by adding a param to hasParameterOption/getParameterOption instead of doing it by default. This creates another BC issue though in that it changes the InputInterface. I don't think that's a major concern but it's worth mentioning.
The other only minor BC change is if you do getParameterOption() of a flag option i.e. `--foo` without a value. Before it was returning null in ArgvInput and true in ArrayInput. I normalized this to true for both since I think that makes more sense, but strictly speaking while it improves interface interchangeability, it's a BC break.
Commits
-------
834218e
[Console] End of options (--) signal support
This commit is contained in:
commit
4acfc3e26f
@ -158,14 +158,14 @@ class Application
|
||||
*/
|
||||
public function doRun(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (true === $input->hasParameterOption(array('--version', '-V'))) {
|
||||
if (true === $input->hasParameterOption(array('--version', '-V'), true)) {
|
||||
$output->writeln($this->getLongVersion());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$name = $this->getCommandName($input);
|
||||
if (true === $input->hasParameterOption(array('--help', '-h'))) {
|
||||
if (true === $input->hasParameterOption(array('--help', '-h'), true)) {
|
||||
if (!$name) {
|
||||
$name = 'help';
|
||||
$input = new ArrayInput(array('command' => 'help'));
|
||||
@ -734,13 +734,13 @@ class Application
|
||||
*/
|
||||
protected function configureIO(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (true === $input->hasParameterOption(array('--ansi'))) {
|
||||
if (true === $input->hasParameterOption(array('--ansi'), true)) {
|
||||
$output->setDecorated(true);
|
||||
} elseif (true === $input->hasParameterOption(array('--no-ansi'))) {
|
||||
} elseif (true === $input->hasParameterOption(array('--no-ansi'), true)) {
|
||||
$output->setDecorated(false);
|
||||
}
|
||||
|
||||
if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) {
|
||||
if (true === $input->hasParameterOption(array('--no-interaction', '-n'), true)) {
|
||||
$input->setInteractive(false);
|
||||
} elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
|
||||
$inputStream = $this->getHelperSet()->get('question')->getInputStream();
|
||||
@ -749,14 +749,14 @@ class Application
|
||||
}
|
||||
}
|
||||
|
||||
if (true === $input->hasParameterOption(array('--quiet', '-q'))) {
|
||||
if (true === $input->hasParameterOption(array('--quiet', '-q'), true)) {
|
||||
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
|
||||
} else {
|
||||
if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) {
|
||||
if ($input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || $input->getParameterOption('--verbose', false, true) === 3) {
|
||||
$output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
|
||||
} elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) {
|
||||
} elseif ($input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || $input->getParameterOption('--verbose', false, true) === 2) {
|
||||
$output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
|
||||
} elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) {
|
||||
} elseif ($input->hasParameterOption('-v', true) || $input->hasParameterOption('--verbose=1', true) || $input->hasParameterOption('--verbose', true) || $input->getParameterOption('--verbose', false, true)) {
|
||||
$output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
|
||||
}
|
||||
}
|
||||
|
@ -275,14 +275,18 @@ class ArgvInput extends Input
|
||||
* before they have been validated. It must be used carefully.
|
||||
*
|
||||
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
|
||||
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
|
||||
*
|
||||
* @return bool true if the value is contained in the raw parameters
|
||||
*/
|
||||
public function hasParameterOption($values)
|
||||
public function hasParameterOption($values, $onlyParams = false)
|
||||
{
|
||||
$values = (array) $values;
|
||||
|
||||
foreach ($this->tokens as $token) {
|
||||
if ($onlyParams && $token === '--') {
|
||||
return false;
|
||||
}
|
||||
foreach ($values as $value) {
|
||||
if ($token === $value || 0 === strpos($token, $value.'=')) {
|
||||
return true;
|
||||
@ -301,16 +305,20 @@ class ArgvInput extends Input
|
||||
*
|
||||
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
|
||||
* @param mixed $default The default value to return if no result is found
|
||||
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
|
||||
*
|
||||
* @return mixed The option value
|
||||
*/
|
||||
public function getParameterOption($values, $default = false)
|
||||
public function getParameterOption($values, $default = false, $onlyParams = false)
|
||||
{
|
||||
$values = (array) $values;
|
||||
$tokens = $this->tokens;
|
||||
|
||||
while (0 < count($tokens)) {
|
||||
$token = array_shift($tokens);
|
||||
if ($onlyParams && $token === '--') {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($values as $value) {
|
||||
if ($token === $value || 0 === strpos($token, $value.'=')) {
|
||||
|
@ -63,10 +63,11 @@ class ArrayInput extends Input
|
||||
* before they have been validated. It must be used carefully.
|
||||
*
|
||||
* @param string|array $values The values to look for in the raw parameters (can be an array)
|
||||
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
|
||||
*
|
||||
* @return bool true if the value is contained in the raw parameters
|
||||
*/
|
||||
public function hasParameterOption($values)
|
||||
public function hasParameterOption($values, $onlyParams = false)
|
||||
{
|
||||
$values = (array) $values;
|
||||
|
||||
@ -75,6 +76,10 @@ class ArrayInput extends Input
|
||||
$v = $k;
|
||||
}
|
||||
|
||||
if ($onlyParams && $v === '--') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in_array($v, $values)) {
|
||||
return true;
|
||||
}
|
||||
@ -91,14 +96,19 @@ class ArrayInput extends Input
|
||||
*
|
||||
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
|
||||
* @param mixed $default The default value to return if no result is found
|
||||
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
|
||||
*
|
||||
* @return mixed The option value
|
||||
*/
|
||||
public function getParameterOption($values, $default = false)
|
||||
public function getParameterOption($values, $default = false, $onlyParams = false)
|
||||
{
|
||||
$values = (array) $values;
|
||||
|
||||
foreach ($this->parameters as $k => $v) {
|
||||
if ($onlyParams && ($k === '--' || (is_int($k) && $v === '--'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_int($k)) {
|
||||
if (in_array($v, $values)) {
|
||||
return true;
|
||||
@ -136,6 +146,9 @@ class ArrayInput extends Input
|
||||
protected function parse()
|
||||
{
|
||||
foreach ($this->parameters as $key => $value) {
|
||||
if ($key === '--') {
|
||||
return;
|
||||
}
|
||||
if (0 === strpos($key, '--')) {
|
||||
$this->addLongOption(substr($key, 2), $value);
|
||||
} elseif ('-' === $key[0]) {
|
||||
|
@ -32,10 +32,11 @@ interface InputInterface
|
||||
* before they have been validated. It must be used carefully.
|
||||
*
|
||||
* @param string|array $values The values to look for in the raw parameters (can be an array)
|
||||
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
|
||||
*
|
||||
* @return bool true if the value is contained in the raw parameters
|
||||
*/
|
||||
public function hasParameterOption($values);
|
||||
public function hasParameterOption($values, $onlyParams = false);
|
||||
|
||||
/**
|
||||
* Returns the value of a raw option (not parsed).
|
||||
@ -45,10 +46,11 @@ interface InputInterface
|
||||
*
|
||||
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
|
||||
* @param mixed $default The default value to return if no result is found
|
||||
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
|
||||
*
|
||||
* @return mixed The option value
|
||||
*/
|
||||
public function getParameterOption($values, $default = false);
|
||||
public function getParameterOption($values, $default = false, $onlyParams = false);
|
||||
|
||||
/**
|
||||
* Binds the current Input instance with the given arguments and options.
|
||||
|
@ -278,6 +278,21 @@ class ArgvInputTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given option with provided value is in the raw input');
|
||||
}
|
||||
|
||||
public function testHasParameterOptionOnlyOptions()
|
||||
{
|
||||
$input = new ArgvInput(array('cli.php', '-f', 'foo'));
|
||||
$this->assertTrue($input->hasParameterOption('-f', true), '->hasParameterOption() returns true if the given short option is in the raw input');
|
||||
|
||||
$input = new ArgvInput(array('cli.php', '--foo', '--', 'foo'));
|
||||
$this->assertTrue($input->hasParameterOption('--foo', true), '->hasParameterOption() returns true if the given long option is in the raw input');
|
||||
|
||||
$input = new ArgvInput(array('cli.php', '--foo=bar', 'foo'));
|
||||
$this->assertTrue($input->hasParameterOption('--foo', true), '->hasParameterOption() returns true if the given long option with provided value is in the raw input');
|
||||
|
||||
$input = new ArgvInput(array('cli.php', '--', '--foo'));
|
||||
$this->assertFalse($input->hasParameterOption('--foo', true), '->hasParameterOption() returns false if the given option is in the raw input but after an end of options signal');
|
||||
}
|
||||
|
||||
public function testToString()
|
||||
{
|
||||
$input = new ArgvInput(array('cli.php', '-f', 'foo'));
|
||||
@ -290,21 +305,25 @@ class ArgvInputTest extends \PHPUnit_Framework_TestCase
|
||||
/**
|
||||
* @dataProvider provideGetParameterOptionValues
|
||||
*/
|
||||
public function testGetParameterOptionEqualSign($argv, $key, $expected)
|
||||
public function testGetParameterOptionEqualSign($argv, $key, $onlyParams, $expected)
|
||||
{
|
||||
$input = new ArgvInput($argv);
|
||||
$this->assertEquals($expected, $input->getParameterOption($key), '->getParameterOption() returns the expected value');
|
||||
$this->assertEquals($expected, $input->getParameterOption($key, false, $onlyParams), '->getParameterOption() returns the expected value');
|
||||
}
|
||||
|
||||
public function provideGetParameterOptionValues()
|
||||
{
|
||||
return array(
|
||||
array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'dev'),
|
||||
array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'dev'),
|
||||
array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'dev'),
|
||||
array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'dev'),
|
||||
array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), '1'),
|
||||
array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), '1'),
|
||||
array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', false, 'dev'),
|
||||
array(array('app/console', 'foo:bar', '--env=dev'), '--env', false, 'dev'),
|
||||
array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), false, 'dev'),
|
||||
array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), false, 'dev'),
|
||||
array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), false, '1'),
|
||||
array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), false, '1'),
|
||||
array(array('app/console', 'foo:bar', '--env', 'val'), '--env', false, 'val'),
|
||||
array(array('app/console', 'foo:bar', '--env', 'val', '--dummy'), '--env', false, 'val'),
|
||||
array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', false, 'dev'),
|
||||
array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', true, false),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -36,15 +36,24 @@ class ArrayInputTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$input = new ArrayInput(array('--foo'));
|
||||
$this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters');
|
||||
|
||||
$input = new ArrayInput(array('--foo', '--', '--bar'));
|
||||
$this->assertTrue($input->hasParameterOption('--bar'), '->hasParameterOption() returns true if an option is present in the passed parameters');
|
||||
$this->assertFalse($input->hasParameterOption('--bar', true), '->hasParameterOption() returns false if an option is present in the passed parameters after an end of options signal');
|
||||
}
|
||||
|
||||
public function testGetParameterOption()
|
||||
{
|
||||
$input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
|
||||
$this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
|
||||
$this->assertFalse($input->getParameterOption('--bar'), '->getParameterOption() returns the default if an option is not present in the passed parameters');
|
||||
|
||||
$input = new ArrayInput(array('Fabien', '--foo' => 'bar'));
|
||||
$this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
|
||||
|
||||
$input = new ArrayInput(array('--foo', '--', '--bar' => 'woop'));
|
||||
$this->assertEquals('woop', $input->getParameterOption('--bar'), '->getParameterOption() returns the correct value if an option is present in the passed parameters');
|
||||
$this->assertFalse($input->getParameterOption('--bar', false, true), '->getParameterOption() returns false if an option is present in the passed parameters after an end of options signal');
|
||||
}
|
||||
|
||||
public function testParseArguments()
|
||||
@ -91,6 +100,18 @@ class ArrayInputTest extends \PHPUnit_Framework_TestCase
|
||||
array('foo' => 'bar'),
|
||||
'->parse() parses short options',
|
||||
),
|
||||
array(
|
||||
array('--' => null, '-f' => 'bar'),
|
||||
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
|
||||
array('foo' => 'default'),
|
||||
'->parse() does not parse opts after an end of options signal',
|
||||
),
|
||||
array(
|
||||
array('--' => null),
|
||||
array(),
|
||||
array(),
|
||||
'->parse() does not choke on end of options signal',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user