Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Console] Optionally stop options parsing at "--", fixes #21869 #21870

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/Symfony/Component/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,14 @@ public function run(InputInterface $input = null, OutputInterface $output = null
*/
public function doRun(InputInterface $input, OutputInterface $output)
{
if (true === $input->hasParameterOption(array('--version', '-V'))) {
if (true === $input->hasParameterOption(array('--version', '-V'), $input::OPTION_FLAG_POSIX)) {
$output->writeln($this->getLongVersion());

return 0;
}

$name = $this->getCommandName($input);
if (true === $input->hasParameterOption(array('--help', '-h'))) {
if (true === $input->hasParameterOption(array('--help', '-h'), $input::OPTION_FLAG_POSIX)) {
if (!$name) {
$name = 'help';
$input = new ArrayInput(array('command' => 'help'));
Expand Down Expand Up @@ -789,13 +789,13 @@ public function setTerminalDimensions($width, $height)
*/
protected function configureIO(InputInterface $input, OutputInterface $output)
{
if (true === $input->hasParameterOption(array('--ansi'))) {
if (true === $input->hasParameterOption(array('--ansi'), $input::OPTION_FLAG_POSIX)) {
$output->setDecorated(true);
} elseif (true === $input->hasParameterOption(array('--no-ansi'))) {
} elseif (true === $input->hasParameterOption(array('--no-ansi'), $input::OPTION_FLAG_POSIX)) {
$output->setDecorated(false);
}

if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) {
if (true === $input->hasParameterOption(array('--no-interaction', '-n'), $input::OPTION_FLAG_POSIX)) {
$input->setInteractive(false);
} elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
$inputStream = $this->getHelperSet()->get('question')->getInputStream();
Expand All @@ -804,15 +804,15 @@ protected function configureIO(InputInterface $input, OutputInterface $output)
}
}

if (true === $input->hasParameterOption(array('--quiet', '-q'))) {
if (true === $input->hasParameterOption(array('--quiet', '-q'), $input::OPTION_FLAG_POSIX)) {
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
$input->setInteractive(false);
} else {
if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) {
if ($input->hasParameterOption('-vvv', $input::OPTION_FLAG_POSIX) || $input->hasParameterOption('--verbose=3', $input::OPTION_FLAG_POSIX) || $input->getParameterOption('--verbose', false, $input::OPTION_FLAG_POSIX) === 3) {
$output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
} elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) {
} elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2', $input::OPTION_FLAG_POSIX) || $input->getParameterOption('--verbose', false, $input::OPTION_FLAG_POSIX) === 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', $input::OPTION_FLAG_POSIX) || $input->hasParameterOption('--verbose=1', $input::OPTION_FLAG_POSIX) || $input->hasParameterOption('--verbose', $input::OPTION_FLAG_POSIX) || $input->getParameterOption('--verbose', false, $input::OPTION_FLAG_POSIX)) {
$output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
}
}
Expand Down
28 changes: 25 additions & 3 deletions src/Symfony/Component/Console/Input/ArgvInput.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,14 @@ public function getFirstArgument()
/**
* {@inheritdoc}
*/
public function hasParameterOption($values)
public function hasParameterOption($values, $flags = InputInterface::OPTION_FLAG_DEFAULT)
{
$values = (array) $values;

foreach ($this->tokens as $token) {
if ($this->isEndOfOptions($token, $flags)) {
break;
}
foreach ($values as $value) {
if ($token === $value || 0 === strpos($token, $value.'=')) {
return true;
Expand All @@ -293,14 +296,16 @@ public function hasParameterOption($values)
/**
* {@inheritdoc}
*/
public function getParameterOption($values, $default = false)
public function getParameterOption($values, $default = false, $flags = InputInterface::OPTION_FLAG_DEFAULT)
{
$values = (array) $values;
$tokens = $this->tokens;

while (0 < count($tokens)) {
$token = array_shift($tokens);

if ($this->isEndOfOptions($token, $flags)) {
break;
}
foreach ($values as $value) {
if ($token === $value || 0 === strpos($token, $value.'=')) {
if (false !== $pos = strpos($token, '=')) {
Expand All @@ -315,6 +320,23 @@ public function getParameterOption($values, $default = false)
return $default;
}

/**
* private helper method to detect end of options in command-line arguments, used
* to assist with a more POSIX compatible parsing of arguments.
*
* @param string $token
* @param int $flags
*
* @return bool
*/
private function isEndOfOptions($token, $flags = InputInterface::OPTION_FLAG_DEFAULT)
{
return
$flags & InputInterface::OPTION_FLAG_POSIX
&& InputInterface::POSIX_OPTIONS_END === $token
;
}

/**
* Returns a stringified representation of the args passed to the command.
*
Expand Down
28 changes: 26 additions & 2 deletions src/Symfony/Component/Console/Input/ArrayInput.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function getFirstArgument()
/**
* {@inheritdoc}
*/
public function hasParameterOption($values)
public function hasParameterOption($values, $flags = InputInterface::OPTION_FLAG_DEFAULT)
{
$values = (array) $values;

Expand All @@ -63,6 +63,10 @@ public function hasParameterOption($values)
$v = $k;
}

if ($this->isEndOfOptions($v, $flags)) {
break;
}

if (in_array($v, $values)) {
return true;
}
Expand All @@ -74,11 +78,14 @@ public function hasParameterOption($values)
/**
* {@inheritdoc}
*/
public function getParameterOption($values, $default = false)
public function getParameterOption($values, $default = false, $flags = InputInterface::OPTION_FLAG_DEFAULT)
{
$values = (array) $values;

foreach ($this->parameters as $k => $v) {
if ($this->isEndOfOptions(is_int($k) ? $v : $k, $flags)) {
break;
}
if (is_int($k)) {
if (in_array($v, $values)) {
return true;
Expand All @@ -91,6 +98,23 @@ public function getParameterOption($values, $default = false)
return $default;
}

/**
* private helper method to detect end of options in command-line arguments, used
* to assist with a more POSIX compatible parsing of arguments.
*
* @param string $token
* @param int $flags
*
* @return bool
*/
private function isEndOfOptions($token, $flags = InputInterface::OPTION_FLAG_DEFAULT)
{
return
$flags & InputInterface::OPTION_FLAG_POSIX
&& InputInterface::POSIX_OPTIONS_END === $token
;
}

/**
* Returns a stringified representation of the args passed to the command.
*
Expand Down
20 changes: 18 additions & 2 deletions src/Symfony/Component/Console/Input/InputInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@
*/
interface InputInterface
{
/**
* @see hasParameterOption()
*/
const OPTION_FLAG_DEFAULT = 0;
const OPTION_FLAG_POSIX = 1;
const POSIX_OPTIONS_END = '--';

/**
* Returns the first argument from the raw parameters (not parsed).
*
Expand All @@ -32,23 +39,32 @@ public function getFirstArgument();
* 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 int $flags Parse flags
*
* How far to look for options:
*
* OPTION_FLAG_DEFAULT: (default) scan all arguments incl. operands
* OPTION_FLAG_POSIX: Do not search for option(s) after POSIX_OPTIONS_END ("--")
*
* @return bool true if the value is contained in the raw parameters
*/
public function hasParameterOption($values);
public function hasParameterOption($values, $flags = self::OPTION_FLAG_DEFAULT);

/**
* Returns the value of a raw option (not parsed).
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
*
* @see hasParameterOption() for $flags
*
* @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 int $flags Parse flags
*
* @return mixed The option value
*/
public function getParameterOption($values, $default = false);
public function getParameterOption($values, $default = false, $flags = self::OPTION_FLAG_DEFAULT);

/**
* Binds the current Input instance with the given arguments and options.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Tom Klingenberg <https://github.com/ktomk/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Console\Tests\Input;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;

/**
* Extra test-case to cover the introduction of $flags for InputInterface::hasParameterOption()
* and InputInterface::getParameterOption().
*/
class ExtraInputsPosixOptionsTest extends TestCase
{
public function testArrayInput()
{
$input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar', '--', '--bar', '--baz' => 'foo'));
$this->hasParameterAssertions($input);
$this->getParameterAssertions($input);
}

public function testArgvInput()
{
$input = new ArgvInput(array('Fabien', '--foo', 'bar', '--', '--bar', '--baz', 'foo'));
$this->hasParameterAssertions($input);
$this->getParameterAssertions($input);
}

private function hasParameterAssertions(InputInterface $input)
{
$this->assertInputHasParameterOption($input, '--foo', '--foo always exists');
$this->assertInputNeverHasParameterOption($input, '--zzz', '--zzz never exists');
$this->assertInputHasParameterOption(
$input,
array('--zzz', '--foo'),
'--foo is found with --zzz that never exists'
);
$this->assertInputHasOnlyNotParameterOption($input, '--bar', '--bar is not found');
$this->assertInputHasParameterOption($input, array('--bar', '--foo'), '--foo is found even --bar is not found');
$this->assertInputHasOnlyNotParameterOption($input, '--baz');

$this->assertTrue($input->hasParameterOption('--bar'), 'Default behaviour');
$this->assertFalse($input->hasParameterOption('--bar', $input::OPTION_FLAG_POSIX), 'Posix flag');

$this->assertFalse($input->hasParameterOption(array('--bar'), $input::OPTION_FLAG_POSIX), 'Posix flag');
$this->assertFalse(
$input->hasParameterOption(array('--bar', '--baz'), $input::OPTION_FLAG_POSIX),
'Posix flag'
);
$this->assertTrue(
$input->hasParameterOption(array('--bar', '--baz', '--foo'), $input::OPTION_FLAG_POSIX),
'Posix flag'
);
}

/**
* Assert that regardless of flags, input never has an option.
*
* @param InputInterface $input
* @param $values
* @param null $message
*/
private function assertInputNeverHasParameterOption(InputInterface $input, $values, $message = null)
{
if (strlen($message)) {
$message = " ($message)";
}

$this->assertFalse($input->hasParameterOption($values), "default flag $message");
$this->assertFalse($input->hasParameterOption($values, $input::OPTION_FLAG_POSIX), "posix flag $message");
}

/**
* Assert that regardless of the flag the values are available.
*
* @param InputInterface $input
* @param $values
* @param null $message
*/
private function assertInputHasParameterOption(InputInterface $input, $values, $message = null)
{
if (strlen($message)) {
$message = " ($message)";
}

$this->assertTrue($input->hasParameterOption($values), "default flag $message");
$this->assertTrue($input->hasParameterOption($values, $input::OPTION_FLAG_POSIX), "posix flag $message");
}

/**
* Assert that with POSIX flag the values are not available, but are available by default.
*
* @param InputInterface $input
* @param $values
* @param null $message
*/
private function assertInputHasOnlyNotParameterOption(InputInterface $input, $values, $message = null)
{
if (strlen($message)) {
$message = " ($message)";
}

$this->assertTrue($input->hasParameterOption($values), "default flag $message");
$this->assertFalse($input->hasParameterOption($values, $input::OPTION_FLAG_POSIX), "posix flag $message");
}

/**
* @param $input
*/
private function getParameterAssertions(InputInterface $input)
{
$this->assertEquals('bar', $input->getParameterOption('--foo'));
$this->assertSame('bar', $input->getParameterOption('--foo', false, $input::OPTION_FLAG_POSIX));

$this->assertEquals('foo', $input->getParameterOption('--baz'));
$this->assertSame(false, $input->getParameterOption('--baz', false, $input::OPTION_FLAG_POSIX));
}
}