diff --git a/src/PHPSemVerChecker/Console/Command/BaseCommand.php b/src/PHPSemVerChecker/Console/Command/BaseCommand.php index f098e9a..84fede8 100644 --- a/src/PHPSemVerChecker/Console/Command/BaseCommand.php +++ b/src/PHPSemVerChecker/Console/Command/BaseCommand.php @@ -26,7 +26,7 @@ protected function initialize(InputInterface $input, OutputInterface $output) $configPath = $input->getOption('config'); $this->config = $configPath ? Configuration::fromFile($configPath) : Configuration::defaults('php-semver-checker'); $inputMerger = new InputMerger(); - $inputMerger->merge($input, $this->config); + $inputMerger->merge($input, $this->getDefinition(), $this->config); // Set overrides LevelMapping::setOverrides($this->config->getLevelMapping()); diff --git a/src/PHPSemVerChecker/Console/InputMerger.php b/src/PHPSemVerChecker/Console/InputMerger.php index b7fb249..28d10e2 100644 --- a/src/PHPSemVerChecker/Console/InputMerger.php +++ b/src/PHPSemVerChecker/Console/InputMerger.php @@ -3,6 +3,7 @@ namespace PHPSemVerChecker\Console; use PHPSemVerChecker\Configuration\Configuration; +use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputInterface; /** @@ -14,24 +15,34 @@ class InputMerger { /** - * @param \Symfony\Component\Console\Input\InputInterface $input - * @param \PHPSemVerChecker\Configuration\Configuration $config + * @param \Symfony\Component\Console\Input\InputInterface $input Actual input + * @param \Symfony\Component\Console\Input\InputDefinition $inputDefinition Definition of input arguments/options + * @param \PHPSemVerChecker\Configuration\Configuration $config */ - public function merge(InputInterface $input, Configuration $config) + public function merge(InputInterface $input, InputDefinition $inputDefinition, Configuration $config) { foreach ($input->getArguments() as $argument => $value) { - if ($input->hasArgumentSet($argument)) { + if ($value !== null) { $config->set($argument, $value); } else { - $input->setArgument($argument, $config->get($argument)); + $configValue = $config->get($argument); + // Only set an argument from config if actually known + if ($configValue !== null) { + $input->setArgument($argument, $configValue); + } } } - foreach ($input->getOptions() as $option => $value) { - if ($input->hasOptionSet($option)) { - $config->set($option, $value); + foreach ($input->getOptions() as $optionName => $value) { + $option = $inputDefinition->getOption($optionName); + // Make sure VALUE_NONE is only used when differing from default + if ((!$option->acceptValue() && $value !== $option->getDefault()) || ($option->acceptValue() && $value !== null)) { + $config->set($optionName, $value); } else { - $input->setOption($option, $config->get($option)); + $configValue = $config->get($optionName); + if ($configValue !== null) { + $input->setOption($optionName, $configValue); + } } } } diff --git a/tests/PHPSemVerChecker/Console/InputMergerTest.php b/tests/PHPSemVerChecker/Console/InputMergerTest.php index c375d1a..7e0230b 100644 --- a/tests/PHPSemVerChecker/Console/InputMergerTest.php +++ b/tests/PHPSemVerChecker/Console/InputMergerTest.php @@ -25,7 +25,7 @@ public function testMerge() $this->assertEquals('in-before cli', $input->getOption('include-before'), 'Test setup: Could not prepare input arguments'); $im = new InputMerger(); - $im->merge($input, $config); + $im->merge($input, $command->getDefinition(), $config); $this->assertEquals('in-before cli', $config->get('include-before'), 'Configuration must be overwritten by CLI option'); $this->assertEquals('src-before cli', $config->get('source-before'), 'Configuration must be overwritten by CLI argument'); $this->assertEquals('src-before cli', $input->getArgument('source-before'), 'Input arguments must not be overwritten by empty configuration'); @@ -33,4 +33,20 @@ public function testMerge() $this->assertEquals('src-after config', $input->getArgument('source-after'), 'Missing input arguments must take on existing configuration'); $this->assertEquals(true, $config->get('full-path'), 'CLI option should use Configuration value and not CLI default'); } + + /** + * @expectedException \Symfony\Component\Console\Exception\RuntimeException + */ + public function testEmptyInputShouldThrowException() + { + // Default/empty configuration + $config = new Configuration([]); + // No input arguments + $input = new InspectableArgvInput([null]); + $command = new CompareCommand(); + $input->bind($command->getDefinition()); + $im = new InputMerger(); + $im->merge($input, $command->getDefinition(), $config); + $input->validate(); + } }