Skip to content

Commit

Permalink
Merge pull request nategood#63 from NeoVance/38-option-repetition-and…
Browse files Browse the repository at this point in the history
…-grouping

38 option repetition and grouping
  • Loading branch information
Nate Good authored Nov 9, 2016
2 parents afb6b93 + 9409163 commit 4b50548
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
vendor
composer.lock
.c9
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,19 @@ $hello_cmd->option('c')
->aka('cap')
->describedAs('Always capitalize the words in a name')
->boolean();

// Define an incremental flag "-e" aka "--educate"
$hello_cmd->option('e')
->aka('educate')
->map(function($value) {
$postfix = array('', 'Jr', 'esq', 'PhD');
return $postfix[$value] === '' ? '' : " {$postfix[$value]}";
})
->count(4);

$name = $hello_cmd['capitalize'] ? ucwords($hello_cmd[0]) : $hello_cmd[0];

echo "Hello {$hello_cmd['title']}$name!", PHP_EOL;
echo "Hello {$hello_cmd['title']}$name{$hello_cmd['educate']}!", PHP_EOL;
```

Running it:
Expand All @@ -80,6 +89,9 @@ Running it:

> php hello.php -c -t Mr 'nate good'
Hello, Mr. Nate Good!

> php hello.php -ceet Mr 'nate good'
Hello, Mr. Nate Good esq!

Things to note:

Expand Down Expand Up @@ -203,6 +215,12 @@ Aliases: _N/A_

Specifices that the flag is a boolean type flag.

### `increment (int $max)`

Aliases: `i`, `count`, `repeats`, `repeatable`

Specifies that the flag is a counter type flag. The value of the flag will be incremented up to the value of `$max` for each time the flag is used in the command. Options that are set to `increment` or `boolean` types can be grouped together.

### `default (mixed $defaultValue)`

Aliases: `defaultsTo`
Expand Down
19 changes: 15 additions & 4 deletions examples/greet.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
* > php green.php -c 'nate good'
* Hello Nate Good!
*
* > php greet.php -c -s Mr 'nate good'
* > php greet.php -cs Mr 'nate good'
* Hello Mr. Nate Good!
*
* > php greet.php -c -s Mister 'nate good'
* > php greet.php -cs Mister 'nate good'
* Hello Mr. Nate Good!
*
* php greet.php -ceet Mr 'nate good'
* Hello Mr. Nate Good esq!
*
* > php greet.php
* # Throws an Exception because the command requires at least one
Expand Down Expand Up @@ -57,8 +60,16 @@
->aka('capitalize')
->aka('cap')
->describedAs('Always capitalize the words in a name')
->boolean();
->boolean()

->option('e')
->aka('educate')
->map(function($value) {
$postfix = array('', 'Jr', 'esq', 'PhD');
return $postfix[$value] === '' ? '' : " {$postfix[$value]}";
})
->count(4);

$name = $hello_cmd['capitalize'] ? ucwords($hello_cmd[0]) : $hello_cmd[0];

echo "Hello {$hello_cmd['title']}$name!", PHP_EOL;
echo "Hello {$hello_cmd['title']}$name{$hello_cmd['educate']}!", PHP_EOL;
37 changes: 37 additions & 0 deletions src/Commando/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ class Command implements \ArrayAccess, \Iterator
'mapTo' => 'map',
'cast' => 'map',
'castWith' => 'map',

'increment' => 'increment',
'repeatable' => 'increment',
'repeats' => 'increment',
'count' => 'increment',
'i' => 'increment',

'must' => 'must',
// mustBeNumeric
Expand Down Expand Up @@ -308,6 +314,16 @@ private function _map(Option $option, \Closure $callback)
{
return $option->setMap($callback);
}

/**
* @param Option $option
* @param integer $max
* @return Option
*/
private function _increment(Option $option, $max = 0)
{
return $option->setIncrement($max);
}

/**
* @return Option
Expand Down Expand Up @@ -375,6 +391,21 @@ public function parse()
$token = array_shift($tokens);

list($name, $type) = $this->_parseOption($token);

// We allow short groups
if (strlen($name) > 1 && $type === self::OPTION_TYPE_SHORT) {

$group = str_split($name);
// correct option name
$name = array_shift($group);

// Iterate in reverse order to keep the option order correct
// options that don't require an argument can be mixed.
foreach(array_reverse($group) as $nextShort) {
// put it back into $tokens for another loop
array_unshift($tokens, "-{$nextShort}");
}
}

if ($type === self::OPTION_TYPE_ARGUMENT) {
// its an argument, use an int as the index
Expand All @@ -398,6 +429,12 @@ public function parse()
$option = $this->getOption($name);
if ($option->isBoolean()) {
$keyvals[$name] = !$option->getDefault();// inverse of the default, as expected
} elseif ($option->isIncrement()) {
if (!isset($keyvals[$name])) {
$keyvals[$name] = $option->getDefault() + 1;
} else {
$keyvals[$name]++;
}
} else {
// the next token MUST be an "argument" and not another flag/option
$token = array_shift($tokens);
Expand Down
32 changes: 32 additions & 0 deletions src/Commando/Option.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class Option
$type = 0, /* int see constants */
$rule, /* closure */
$map, /* closure */
$increment = false, /* bool */
$max_value = 0, /* int max value for increment */
$default, /* mixed default value for this option when no value is specified */
$file = false, /* bool */
$file_require_exists, /* bool require that the file path is valid */
Expand Down Expand Up @@ -115,6 +117,20 @@ public function setBoolean($bool = true)
$this->boolean = $bool;
return $this;
}

/**
* @param int $max
* @return Option
*/
public function setIncrement($max = 0)
{
if($this->default === null) {
$this->setDefault(0);
}
$this->increment = true;
$this->max_value = $max;
return $this;
}

/**
* Require that the argument is a file. This will
Expand Down Expand Up @@ -313,6 +329,14 @@ public function isBoolean()
// $this->value = false; // ?
return $this->boolean;
}

/**
* @return bool is this option an incremental option
*/
public function isIncrement()
{
return $this->increment;
}

/**
* @return bool is this option a boolean
Expand Down Expand Up @@ -368,6 +392,14 @@ public function setValue($value)
if (!$this->validate($value)) {
throw new \Exception(sprintf('Invalid value, %s, for option %s', $value, $this->name));
}
if ($this->isIncrement()) {
if (!is_int($value)) {
throw new \Exception(sprintf('Integer expected as value for %s, received %s instead', $this->name, $value));
}
if ($value > $this->max_value && $this->max_value > 0) {
$value = $this->max_value;
}
}
if ($this->isFile()) {
$file_path = $this->parseFilePath($value);
if (empty($file_path)) {
Expand Down
24 changes: 24 additions & 0 deletions tests/Commando/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,30 @@ public function testBooleanOption()
->boolean();
$this->assertTrue($cmd['b']);
}

public function testIncrementOption()
{
$tokens = array('filename', '-vvvv');
$cmd = new Command($tokens);
$cmd
->flag('v')
->aka('verbosity')
->increment();

$this->assertEquals(4, $cmd['verbosity']);
}

public function testIncrementOptionMaxValue()
{
$tokens = array('filename', '-vvvv');
$cmd = new Command($tokens);
$cmd
->flag('v')
->aka('verbosity')
->increment(3);

$this->assertEquals(3, $cmd['verbosity']);
}

public function testGetValues()
{
Expand Down

0 comments on commit 4b50548

Please sign in to comment.