Skip to content

Commit

Permalink
Merge 7b7ed30 into 2f53397
Browse files Browse the repository at this point in the history
  • Loading branch information
thecrypticace committed Aug 22, 2016
2 parents 2f53397 + 7b7ed30 commit e29d419
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 7 deletions.
3 changes: 2 additions & 1 deletion docs/command-definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ Options are always optional (duh). If an option is required, then it should be a
## Default values

```php
$app->command('greet [firstname] [lastname]', function () {
$app->command('greet [firstname] [lastname] [--age=]', function () {
// ...
})->defaults([
'firstname' => 'John',
'lastname' => 'Doe',
'age' => 25,
]);
```

Expand Down
22 changes: 22 additions & 0 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Invoker\ParameterResolver\Container\ParameterNameContainerResolver;
use Invoker\ParameterResolver\Container\TypeHintContainerResolver;
use Invoker\ParameterResolver\ResolverChain;
use ReflectionFunction;
use Silly\Command\Command;
use Silly\Command\ExpressionParser;
use Symfony\Component\Console\Application as SymfonyApplication;
Expand Down Expand Up @@ -90,6 +91,10 @@ public function command($expression, $callable, array $aliases = [])
$command = $this->createCommand($expression, $commandFunction);
$command->setAliases($aliases);

if (is_callable($callable)) {
$command->defaults($this->defaultsViaReflection($callable));
}

$this->add($command);

return $command;
Expand Down Expand Up @@ -195,4 +200,21 @@ private function createCommand($expression, callable $callable)

return $command;
}

private function defaultsViaReflection(callable $callable)
{
$function = new ReflectionFunction($callable);

$defaults = [];

foreach ($function->getParameters() as $parameter) {
if (! $parameter->isDefaultValueAvailable()) {
continue;
}

$defaults[$parameter->name] = $parameter->getDefaultValue();
}

return $defaults;
}
}
19 changes: 14 additions & 5 deletions src/Command/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,28 @@ public function descriptions($description, array $argumentAndOptionDescriptions
/**
* Define default values for the arguments of the command.
*
* @param array $argumentDefaults Default argument values.
* @param array $defaults Default argument values.
*
* @return $this
*
* @api
*/
public function defaults(array $argumentDefaults = [])
public function defaults(array $defaults = [])
{
$definition = $this->getDefinition();

foreach ($argumentDefaults as $name => $default) {
$argument = $definition->getArgument($name);
$argument->setDefault($default);
foreach ($defaults as $name => $default) {
if ($definition->hasArgument($name)) {
$input = $definition->getArgument($name);
} elseif ($definition->hasOption($name)) {
$input = $definition->getOption($name);
} else {
throw new \InvalidArgumentException(
"Unable to set default for [{$name}]. It does not exist as an argument or option."
);
}

$input->setDefault($default);
}

return $this;
Expand Down
45 changes: 44 additions & 1 deletion tests/Command/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function setUp()
$this->application->setAutoExit(false);
$this->application->setCatchExceptions(false);

$this->command = $this->application->command('greet [name] [--yell]', function () {});
$this->command = $this->application->command('greet [name] [--yell] [--times=]', function () {});
}

/**
Expand All @@ -34,13 +34,15 @@ public function allows_to_define_descriptions()
$this->command->descriptions('Greet someone', [
'name' => 'Who?',
'--yell' => 'Yell?',
'--times' => '# of times to greet?',
]);

$definition = $this->command->getDefinition();

$this->assertEquals('Greet someone', $this->command->getDescription());
$this->assertEquals('Who?', $definition->getArgument('name')->getDescription());
$this->assertEquals('Yell?', $definition->getOption('yell')->getDescription());
$this->assertEquals('# of times to greet?', $definition->getOption('times')->getDescription());
}

/**
Expand All @@ -50,10 +52,51 @@ public function allows_to_define_default_values()
{
$this->command->defaults([
'name' => 'John',
'times' => '1',
]);

$definition = $this->command->getDefinition();

$this->assertEquals('John', $definition->getArgument('name')->getDefault());
$this->assertEquals('1', $definition->getOption('times')->getDefault());
}

/**
* @test
*/
public function allows_default_values_to_be_inferred_from_closure_parameters()
{
$command = $this->application->command('greet [name] [--yell] [--times=]', function ($times = 15) {
//
});

$definition = $command->getDefinition();

$this->assertEquals(15, $definition->getOption("times")->getDefault());
}

/**
* @test
*/
public function setting_defaults_falls_back_to_options_when_no_argument_exists()
{
$this->command->defaults([
'times' => '5',
]);

$definition = $this->command->getDefinition();

$this->assertEquals(5, $definition->getOption("times")->getDefault());
}

/**
* @test
* @expectedException \InvalidArgumentException
*/
public function setting_unknown_defaults_throws_an_exception()
{
$this->command->defaults([
'doesnotexist' => '0',
]);
}
}

0 comments on commit e29d419

Please sign in to comment.