diff --git a/src/Symfony/Component/Console/CHANGELOG.md b/src/Symfony/Component/Console/CHANGELOG.md index 71ed5de78d..1a82efaf17 100644 --- a/src/Symfony/Component/Console/CHANGELOG.md +++ b/src/Symfony/Component/Console/CHANGELOG.md @@ -9,6 +9,7 @@ CHANGELOG * added support for events in `Application` * added a way to normalize EOLs in `ApplicationTester::getDisplay()` and `CommandTester::getDisplay()` * added a way to set the progress bar progress via the `setCurrent` method + * added support for multiple InputOption shortcuts, written as `'-a|-b|-c'` 2.2.0 ----- diff --git a/src/Symfony/Component/Console/Descriptor/XmlDescriptor.php b/src/Symfony/Component/Console/Descriptor/XmlDescriptor.php index 5e1f93f4fc..c828a9ceb8 100644 --- a/src/Symfony/Component/Console/Descriptor/XmlDescriptor.php +++ b/src/Symfony/Component/Console/Descriptor/XmlDescriptor.php @@ -57,7 +57,13 @@ class XmlDescriptor extends Descriptor $dom->appendChild($objectXML = $dom->createElement('option')); $objectXML->setAttribute('name', '--'.$option->getName()); - $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : ''); + $pos = strpos($option->getShortcut(), '|'); + if (false !== $pos) { + $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos)); + $objectXML->setAttribute('shortcuts', '-'.implode('|-', explode('|', $option->getShortcut()))); + } else { + $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : ''); + } $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0); $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0); $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0); diff --git a/src/Symfony/Component/Console/Input/InputDefinition.php b/src/Symfony/Component/Console/Input/InputDefinition.php index 204d293cd0..a18da2b2f3 100644 --- a/src/Symfony/Component/Console/Input/InputDefinition.php +++ b/src/Symfony/Component/Console/Input/InputDefinition.php @@ -266,13 +266,21 @@ class InputDefinition { if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) { throw new \LogicException(sprintf('An option named "%s" already exists.', $option->getName())); - } elseif (isset($this->shortcuts[$option->getShortcut()]) && !$option->equals($this->options[$this->shortcuts[$option->getShortcut()]])) { - throw new \LogicException(sprintf('An option with shortcut "%s" already exists.', $option->getShortcut())); + } + + if ($option->getShortcut()) { + foreach (explode('|', $option->getShortcut()) as $shortcut) { + if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) { + throw new \LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut)); + } + } } $this->options[$option->getName()] = $option; if ($option->getShortcut()) { - $this->shortcuts[$option->getShortcut()] = $option->getName(); + foreach (explode('|', $option->getShortcut()) as $shortcut) { + $this->shortcuts[$shortcut] = $option->getName(); + } } } diff --git a/src/Symfony/Component/Console/Input/InputOption.php b/src/Symfony/Component/Console/Input/InputOption.php index 70f491897c..75fc46ed85 100644 --- a/src/Symfony/Component/Console/Input/InputOption.php +++ b/src/Symfony/Component/Console/Input/InputOption.php @@ -59,9 +59,9 @@ class InputOption } if (null !== $shortcut) { - if ('-' === $shortcut[0]) { - $shortcut = substr($shortcut, 1); - } + $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-')); + $shortcuts = array_filter($shortcuts); + $shortcut = implode('|', $shortcuts); if (empty($shortcut)) { throw new \InvalidArgumentException('An option shortcut cannot be empty.'); diff --git a/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php b/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php index 76316bd863..5cf5011774 100644 --- a/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php +++ b/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php @@ -308,6 +308,15 @@ class InputDefinitionTest extends \PHPUnit_Framework_TestCase $this->assertEquals($this->foo, $definition->getOptionForShortcut('f'), '->getOptionForShortcut() returns a InputOption by its shortcut'); } + public function testGetOptionForMultiShortcut() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->multi)); + $this->assertEquals($this->multi, $definition->getOptionForShortcut('m'), '->getOptionForShortcut() returns a InputOption by its shortcut'); + $this->assertEquals($this->multi, $definition->getOptionForShortcut('mmm'), '->getOptionForShortcut() returns a InputOption by its shortcut'); + } + /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage The "-l" option does not exist. @@ -406,5 +415,6 @@ class InputDefinitionTest extends \PHPUnit_Framework_TestCase $this->bar = new InputOption('bar', 'b'); $this->foo1 = new InputOption('fooBis', 'f'); $this->foo2 = new InputOption('foo', 'p'); + $this->multi = new InputOption('multi', 'm|mm|mmm'); } } diff --git a/src/Symfony/Component/Console/Tests/Input/InputOptionTest.php b/src/Symfony/Component/Console/Tests/Input/InputOptionTest.php index b50c090484..fc291bc197 100644 --- a/src/Symfony/Component/Console/Tests/Input/InputOptionTest.php +++ b/src/Symfony/Component/Console/Tests/Input/InputOptionTest.php @@ -36,8 +36,10 @@ class InputOptionTest extends \PHPUnit_Framework_TestCase { $option = new InputOption('foo', 'f'); $this->assertEquals('f', $option->getShortcut(), '__construct() can take a shortcut as its second argument'); - $option = new InputOption('foo', '-f'); - $this->assertEquals('f', $option->getShortcut(), '__construct() removes the leading - of the shortcut'); + $option = new InputOption('foo', '-f|-ff|fff'); + $this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts'); + $option = new InputOption('foo', 'f|ff|-fff'); + $this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts'); $option = new InputOption('foo'); $this->assertNull($option->getShortcut(), '__construct() makes the shortcut null by default'); }