Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add requires #31

Merged
merged 7 commits into from
May 9, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/Commando/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class Command implements \ArrayAccess, \Iterator
// mustBeNumeric
// mustBeInt
// mustBeFloat
'needs' => 'needs',

'file' => 'file',
'expectsFile' => 'file',
Expand Down Expand Up @@ -205,6 +206,18 @@ private function _require(Option $option, $require = true)
return $option->setRequired($require);
}

/**
* Set a requirement on an option
*
* @param \Commando\Option $option Current option
* @param string $name Name of option
* @return \Commando\Option instance
*/
private function _needs(Option $option, $name)
{
return $option->setNeeds($name);
}

/**
* @param Option $option
* @param string $alias
Expand Down Expand Up @@ -353,6 +366,17 @@ public function parse()
}
}
}

// See if our options have what they require
foreach ($this->options as $option) {
$needs = $option->hasNeeds($this->options);
if ($needs !== true) {
throw new \InvalidArgumentException(
'Option "'.$option->getName().'" does not have required option(s): '.implode(', ', $needs)
);
}
}

// Set values (validates and performs map when applicable)
foreach ($keyvals as $key => $value) {

Expand Down
47 changes: 47 additions & 0 deletions src/Commando/Option.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Option
$value = null, /* mixed */
$description, /* string */
$required = false, /* bool */
$needs = array(), /* set of other required options for this option */
$boolean = false, /* bool */
$type = 0, /* int see constants */
$rule, /* closure */
Expand Down Expand Up @@ -119,6 +120,22 @@ public function setRequired($bool = true)
return $this;
}

/**
* Set an option as required
*
* @param string $option Option name
*/
public function setNeeds($option)
{
if (!is_array($option)) {
$option = array($option);
}
foreach ($option as $opt) {
$this->needs[] = $opt;
}
return $this;
}

/**
* @param mixed $value default value
* @return Option
Expand Down Expand Up @@ -241,6 +258,15 @@ public function getAliases()
return $this->aliases;
}

/**
* Get the current set of this option's requirements
* @return array List of required options
*/
public function getNeeds()
{
return $this->needs;
}

/**
* @return bool is this option a boolean
*/
Expand All @@ -266,6 +292,27 @@ public function isRequired()
return $this->required;
}

/**
* Check to see if requirements list for option are met
*
* @param array $optionsList Set of current options defined
* @return boolean|array True if requirements met, array if not found
*/
public function hasNeeds($optionsList)
{
$needs = $this->getNeeds();

$definedOptions = array_keys($optionsList);
$notFound = array();
foreach ($needs as $need) {
if (!in_array($need, $definedOptions)) {
$notFound[] = $need;
}
}
return (empty($notFound)) ? true : $notFound;

}

/**
* @param mixed value for this option (set on the command line)
*/
Expand Down
30 changes: 30 additions & 0 deletions tests/Commando/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,34 @@ public function testGetValues()
$this->assertEquals(array('a' => 'v1', 'b' => 'v2'), $cmd->getFlagValues());
}

/**
* Ensure that requirements are resolved correctly
*/
public function testRequirementsOnOptionsValid()
{
$tokens = array('filename', '-a', 'v1', '-b', 'v2');
$cmd = new Command($tokens);

$cmd->option('b');
$cmd->option('a')
->needs('b');

$this->assertEquals($cmd['a'], 'v1');
}

/**
* Test that an exception is thrown when an option isn't set
* @expectedException \InvalidArgumentException
*/
public function testRequirementsOnOptionsMissing()
{
$tokens = array('filename', '-a', 'v1');
$cmd = new Command($tokens);

$cmd->trapErrors(false)
->beepOnError(false);
$cmd->option('a')
->needs('b');
}

}
25 changes: 25 additions & 0 deletions tests/Commando/OptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,31 @@ public function testDefault($val)
$this->assertEquals($val, $option->getValue());
}

/**
* Test that requires options are set correctly
*/
public function testSetRequired()
{
$option = new Option('f');
$option->setNeeds('foo');

$this->assertTrue(in_array('foo', $option->getNeeds()));
}

/**
* Test that the needed requirements are met
*/
public function testOptionRequirementsMet()
{
$option = new Option('f');
$option->setNeeds('foo');
$optionSet = array(
'foo' => new Option('foo')
);

$this->assertTrue($option->hasNeeds($optionSet));
}

// Providers

public function values()
Expand Down