[Console] Stop parsing options after encountering "--" token

This enables support for arguments with leading dashes (e.g. "-1"), as supported by getopt in other languages.
This commit is contained in:
Jeremy Mikola 2012-03-16 15:28:57 -04:00
parent 91e977d38c
commit 4d4ef24c47
3 changed files with 24 additions and 2 deletions

View File

@ -168,6 +168,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
* made the defaults (helper set, commands, input definition) in Application more easily customizable
* added support for the shell even if readline is not available
* added support for process isolation in Symfony shell via `--process-isolation` switch
* added support for `--`, which disables options parsing after that point (tokens will be parsed as arguments)
### ClassLoader

View File

@ -75,11 +75,14 @@ class ArgvInput extends Input
*/
protected function parse()
{
$parseOptions = true;
$this->parsed = $this->tokens;
while (null !== $token = array_shift($this->parsed)) {
if (0 === strpos($token, '--')) {
if ($parseOptions && '--' == $token) {
$parseOptions = false;
} elseif ($parseOptions && 0 === strpos($token, '--')) {
$this->parseLongOption($token);
} elseif ('-' === $token[0]) {
} elseif ($parseOptions && '-' === $token[0]) {
$this->parseShortOption($token);
} else {
$this->parseArgument($token);

View File

@ -151,6 +151,24 @@ class ArgvInputTest extends \PHPUnit_Framework_TestCase
$input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name=baz'));
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
$this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions());
try {
$input = new ArgvInput(array('cli.php', '-1'));
$input->bind(new InputDefinition(array(new InputArgument('number'))));
$this->fail('->parse() throws a \RuntimeException if an unknown option is passed');
} catch (\Exception $e) {
$this->assertInstanceOf('\RuntimeException', $e, '->parse() parses arguments with leading dashes as options without having encountered a double-dash sequence');
$this->assertEquals('The "-1" option does not exist.', $e->getMessage(), '->parse() parses arguments with leading dashes as options without having encountered a double-dash sequence');
}
$input = new ArgvInput(array('cli.php', '--', '-1'));
$input->bind(new InputDefinition(array(new InputArgument('number'))));
$this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');
$input = new ArgvInput(array('cli.php', '-f', 'bar', '--', '-1'));
$input->bind(new InputDefinition(array(new InputArgument('number'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));
$this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses arguments with leading dashes as options before having encountered a double-dash sequence');
$this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');
}
public function testGetFirstArgument()