From b9c9f940b164a69480a19f7141451d3af348a5b3 Mon Sep 17 00:00:00 2001 From: Chris Cornutt Date: Thu, 1 May 2014 08:36:22 -0500 Subject: [PATCH 1/7] Adding functionality to Command for setting requirements on options --- src/Commando/Command.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/Commando/Command.php b/src/Commando/Command.php index 40a5829..71e5479 100755 --- a/src/Commando/Command.php +++ b/src/Commando/Command.php @@ -46,6 +46,7 @@ class Command implements \ArrayAccess, \Iterator 'require' => 'require', 'required' => 'require', 'r' => 'require', + 'requires' => 'requires', 'alias' => 'alias', 'aka' => 'alias', @@ -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 _requires(Option $option, $name) + { + return $option->setRequires($name); + } + /** * @param Option $option * @param string $alias @@ -353,6 +366,17 @@ public function parse() } } } + + // See if our options have what they require + foreach ($this->options as $option) { + $required = $option->hasRequirements($this->options); + if ($required !== true) { + throw new \InvalidArgumentException( + 'Option "'.$option->getName().'" does not have required option(s): '.implode(', ', $required) + ); + } + } + // Set values (validates and performs map when applicable) foreach ($keyvals as $key => $value) { From 2750322b25480b6ef57aa2a24ffae91a1f92ae13 Mon Sep 17 00:00:00 2001 From: Chris Cornutt Date: Thu, 1 May 2014 08:36:51 -0500 Subject: [PATCH 2/7] Adding "requires" handling to Option for defining other options that must be set --- src/Commando/Option.php | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/Commando/Option.php b/src/Commando/Option.php index 9832226..bfaa96a 100755 --- a/src/Commando/Option.php +++ b/src/Commando/Option.php @@ -11,6 +11,7 @@ class Option $value = null, /* mixed */ $description, /* string */ $required = false, /* bool */ + $requires = array(), /* set of other required options for this option */ $boolean = false, /* bool */ $type = 0, /* int see constants */ $rule, /* closure */ @@ -119,6 +120,22 @@ public function setRequired($bool = true) return $this; } + /** + * Set an option as required + * + * @param string $option Option name + */ + public function setRequires($option) + { + if (!is_array($option)) { + $option = array($option); + } + foreach ($option as $opt) { + $this->requires[] = $opt; + } + return $this; + } + /** * @param mixed $value default value * @return Option @@ -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 getRequires() + { + return $this->requires; + } + /** * @return bool is this option a boolean */ @@ -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 hasRequirements($optionsList) + { + $requires = $this->getRequires(); + + $definedOptions = array_keys($optionsList); + $notFound = array(); + foreach ($requires as $req) { + if (!in_array($req, $definedOptions)) { + $notFound[] = $req; + } + } + return (empty($notFound)) ? true : $notFound; + + } + /** * @param mixed value for this option (set on the command line) */ From f0283649c38f904813a81b72b10e82c6982b6504 Mon Sep 17 00:00:00 2001 From: Chris Cornutt Date: Thu, 1 May 2014 08:37:11 -0500 Subject: [PATCH 3/7] Adding tests for new "required" handling to Command class --- tests/Commando/CommandTest.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/Commando/CommandTest.php b/tests/Commando/CommandTest.php index 0ab15db..3fb6afe 100755 --- a/tests/Commando/CommandTest.php +++ b/tests/Commando/CommandTest.php @@ -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') + ->requires('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') + ->requires('b'); + } + } \ No newline at end of file From f7b3fe0017dd4fd6bfd50ad685946f9cfb4c23ae Mon Sep 17 00:00:00 2001 From: Chris Cornutt Date: Thu, 1 May 2014 08:40:56 -0500 Subject: [PATCH 4/7] adding tests for new "requires" handling in options --- tests/Commando/OptionTest.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/Commando/OptionTest.php b/tests/Commando/OptionTest.php index 8eddb47..c27bcd9 100644 --- a/tests/Commando/OptionTest.php +++ b/tests/Commando/OptionTest.php @@ -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->setRequires('foo'); + + $this->assertTrue(in_array('foo', $option->getRequires())); + } + + /** + * Test that the needed requirements are met + */ + public function testOptionRequirementsMet() + { + $option = new Option('f'); + $option->setRequires('foo'); + $optionSet = array( + 'foo' => new Option('foo') + ); + + $this->assertTrue($option->hasRequirements($optionSet)); + } + // Providers public function values() From 11519f9bd25869e6b3ed3553b58fd3b80ecd5d7c Mon Sep 17 00:00:00 2001 From: Chris Cornutt Date: Thu, 1 May 2014 11:44:16 -0500 Subject: [PATCH 5/7] updating from "requires" to "dependsOn" for dependency handling --- src/Commando/Command.php | 8 ++++---- src/Commando/Option.php | 14 +++++++------- tests/Commando/CommandTest.php | 4 ++-- tests/Commando/OptionTest.php | 8 ++++---- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Commando/Command.php b/src/Commando/Command.php index 71e5479..217186a 100755 --- a/src/Commando/Command.php +++ b/src/Commando/Command.php @@ -46,7 +46,6 @@ class Command implements \ArrayAccess, \Iterator 'require' => 'require', 'required' => 'require', 'r' => 'require', - 'requires' => 'requires', 'alias' => 'alias', 'aka' => 'alias', @@ -61,6 +60,7 @@ class Command implements \ArrayAccess, \Iterator 'describeAs' => 'describe', 'description' => 'describe', 'describedAs' => 'describe', + 'dependsOn' => 'dependsOn', 'map' => 'map', 'mapTo' => 'map', @@ -213,9 +213,9 @@ private function _require(Option $option, $require = true) * @param string $name Name of option * @return \Commando\Option instance */ - private function _requires(Option $option, $name) + private function _dependsOn(Option $option, $name) { - return $option->setRequires($name); + return $option->setDependsOn($name); } /** @@ -369,7 +369,7 @@ public function parse() // See if our options have what they require foreach ($this->options as $option) { - $required = $option->hasRequirements($this->options); + $required = $option->hasDependsOn($this->options); if ($required !== true) { throw new \InvalidArgumentException( 'Option "'.$option->getName().'" does not have required option(s): '.implode(', ', $required) diff --git a/src/Commando/Option.php b/src/Commando/Option.php index bfaa96a..b4a3947 100755 --- a/src/Commando/Option.php +++ b/src/Commando/Option.php @@ -11,7 +11,7 @@ class Option $value = null, /* mixed */ $description, /* string */ $required = false, /* bool */ - $requires = array(), /* set of other required options for this option */ + $dependsOn = array(), /* set of other required options for this option */ $boolean = false, /* bool */ $type = 0, /* int see constants */ $rule, /* closure */ @@ -125,13 +125,13 @@ public function setRequired($bool = true) * * @param string $option Option name */ - public function setRequires($option) + public function setDependsOn($option) { if (!is_array($option)) { $option = array($option); } foreach ($option as $opt) { - $this->requires[] = $opt; + $this->dependsOn[] = $opt; } return $this; } @@ -262,9 +262,9 @@ public function getAliases() * Get the current set of this option's requirements * @return array List of required options */ - public function getRequires() + public function getDependsOn() { - return $this->requires; + return $this->dependsOn; } /** @@ -298,9 +298,9 @@ public function isRequired() * @param array $optionsList Set of current options defined * @return boolean|array True if requirements met, array if not found */ - public function hasRequirements($optionsList) + public function hasDependsOn($optionsList) { - $requires = $this->getRequires(); + $requires = $this->getDependsOn(); $definedOptions = array_keys($optionsList); $notFound = array(); diff --git a/tests/Commando/CommandTest.php b/tests/Commando/CommandTest.php index 3fb6afe..b7708f1 100755 --- a/tests/Commando/CommandTest.php +++ b/tests/Commando/CommandTest.php @@ -162,7 +162,7 @@ public function testRequirementsOnOptionsValid() $cmd->option('b'); $cmd->option('a') - ->requires('b'); + ->dependsOn('b'); $this->assertEquals($cmd['a'], 'v1'); } @@ -179,7 +179,7 @@ public function testRequirementsOnOptionsMissing() $cmd->trapErrors(false) ->beepOnError(false); $cmd->option('a') - ->requires('b'); + ->dependsOn('b'); } } \ No newline at end of file diff --git a/tests/Commando/OptionTest.php b/tests/Commando/OptionTest.php index c27bcd9..caacccc 100644 --- a/tests/Commando/OptionTest.php +++ b/tests/Commando/OptionTest.php @@ -137,9 +137,9 @@ public function testDefault($val) public function testSetRequired() { $option = new Option('f'); - $option->setRequires('foo'); + $option->setDependsOn('foo'); - $this->assertTrue(in_array('foo', $option->getRequires())); + $this->assertTrue(in_array('foo', $option->getDependsOn())); } /** @@ -148,12 +148,12 @@ public function testSetRequired() public function testOptionRequirementsMet() { $option = new Option('f'); - $option->setRequires('foo'); + $option->setDependsOn('foo'); $optionSet = array( 'foo' => new Option('foo') ); - $this->assertTrue($option->hasRequirements($optionSet)); + $this->assertTrue($option->hasDependsOn($optionSet)); } // Providers From a79b97870959c9d59b0c346d7d3cb608ae9958ee Mon Sep 17 00:00:00 2001 From: Chris Cornutt Date: Tue, 6 May 2014 07:12:14 -0500 Subject: [PATCH 6/7] moving "dependsOn" over to "needs" as per Issue #31 --- src/Commando/Command.php | 12 ++++++------ tests/Commando/CommandTest.php | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Commando/Command.php b/src/Commando/Command.php index 217186a..21fafcc 100755 --- a/src/Commando/Command.php +++ b/src/Commando/Command.php @@ -60,7 +60,6 @@ class Command implements \ArrayAccess, \Iterator 'describeAs' => 'describe', 'description' => 'describe', 'describedAs' => 'describe', - 'dependsOn' => 'dependsOn', 'map' => 'map', 'mapTo' => 'map', @@ -71,6 +70,7 @@ class Command implements \ArrayAccess, \Iterator // mustBeNumeric // mustBeInt // mustBeFloat + 'needs' => 'needs', 'file' => 'file', 'expectsFile' => 'file', @@ -213,9 +213,9 @@ private function _require(Option $option, $require = true) * @param string $name Name of option * @return \Commando\Option instance */ - private function _dependsOn(Option $option, $name) + private function _needs(Option $option, $name) { - return $option->setDependsOn($name); + return $option->setNeeds($name); } /** @@ -369,10 +369,10 @@ public function parse() // See if our options have what they require foreach ($this->options as $option) { - $required = $option->hasDependsOn($this->options); - if ($required !== true) { + $needs = $option->hasNeeds($this->options); + if ($needs !== true) { throw new \InvalidArgumentException( - 'Option "'.$option->getName().'" does not have required option(s): '.implode(', ', $required) + 'Option "'.$option->getName().'" does not have required option(s): '.implode(', ', $needs) ); } } diff --git a/tests/Commando/CommandTest.php b/tests/Commando/CommandTest.php index b7708f1..08851ce 100755 --- a/tests/Commando/CommandTest.php +++ b/tests/Commando/CommandTest.php @@ -162,7 +162,7 @@ public function testRequirementsOnOptionsValid() $cmd->option('b'); $cmd->option('a') - ->dependsOn('b'); + ->needs('b'); $this->assertEquals($cmd['a'], 'v1'); } @@ -179,7 +179,7 @@ public function testRequirementsOnOptionsMissing() $cmd->trapErrors(false) ->beepOnError(false); $cmd->option('a') - ->dependsOn('b'); + ->needs('b'); } } \ No newline at end of file From 22521268a6154402d3933112cb94ad38e480c93f Mon Sep 17 00:00:00 2001 From: Chris Cornutt Date: Tue, 6 May 2014 07:12:38 -0500 Subject: [PATCH 7/7] Moving from "dependsOn" to "needs" on Option (Issue #31) --- src/Commando/Option.php | 20 ++++++++++---------- tests/Commando/OptionTest.php | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Commando/Option.php b/src/Commando/Option.php index b4a3947..5c1baa5 100755 --- a/src/Commando/Option.php +++ b/src/Commando/Option.php @@ -11,7 +11,7 @@ class Option $value = null, /* mixed */ $description, /* string */ $required = false, /* bool */ - $dependsOn = array(), /* set of other required options for this option */ + $needs = array(), /* set of other required options for this option */ $boolean = false, /* bool */ $type = 0, /* int see constants */ $rule, /* closure */ @@ -125,13 +125,13 @@ public function setRequired($bool = true) * * @param string $option Option name */ - public function setDependsOn($option) + public function setNeeds($option) { if (!is_array($option)) { $option = array($option); } foreach ($option as $opt) { - $this->dependsOn[] = $opt; + $this->needs[] = $opt; } return $this; } @@ -262,9 +262,9 @@ public function getAliases() * Get the current set of this option's requirements * @return array List of required options */ - public function getDependsOn() + public function getNeeds() { - return $this->dependsOn; + return $this->needs; } /** @@ -298,15 +298,15 @@ public function isRequired() * @param array $optionsList Set of current options defined * @return boolean|array True if requirements met, array if not found */ - public function hasDependsOn($optionsList) + public function hasNeeds($optionsList) { - $requires = $this->getDependsOn(); + $needs = $this->getNeeds(); $definedOptions = array_keys($optionsList); $notFound = array(); - foreach ($requires as $req) { - if (!in_array($req, $definedOptions)) { - $notFound[] = $req; + foreach ($needs as $need) { + if (!in_array($need, $definedOptions)) { + $notFound[] = $need; } } return (empty($notFound)) ? true : $notFound; diff --git a/tests/Commando/OptionTest.php b/tests/Commando/OptionTest.php index caacccc..a04b9e3 100644 --- a/tests/Commando/OptionTest.php +++ b/tests/Commando/OptionTest.php @@ -137,9 +137,9 @@ public function testDefault($val) public function testSetRequired() { $option = new Option('f'); - $option->setDependsOn('foo'); + $option->setNeeds('foo'); - $this->assertTrue(in_array('foo', $option->getDependsOn())); + $this->assertTrue(in_array('foo', $option->getNeeds())); } /** @@ -148,12 +148,12 @@ public function testSetRequired() public function testOptionRequirementsMet() { $option = new Option('f'); - $option->setDependsOn('foo'); + $option->setNeeds('foo'); $optionSet = array( 'foo' => new Option('foo') ); - $this->assertTrue($option->hasDependsOn($optionSet)); + $this->assertTrue($option->hasNeeds($optionSet)); } // Providers