diff --git a/src/CLImate.php b/src/CLImate.php index a66c7721..634120d6 100644 --- a/src/CLImate.php +++ b/src/CLImate.php @@ -258,6 +258,11 @@ public function usage(array $argv = null) return $this->arguments->usage($this, $argv); } + public function command($name) + { + return new Command($name, $this); + } + /** * Set the program's description * diff --git a/src/Command.php b/src/Command.php new file mode 100644 index 00000000..747038df --- /dev/null +++ b/src/Command.php @@ -0,0 +1,247 @@ +name = $name; + $this->climate = $climate; + + $this->filter = new Filter; + $this->summary = new Summary; + $this->parser = new Parser; + } + + /** + * Add an argument. + * + * @throws \Exception if $argument isn't an array or Argument object. + * @param Argument|string $argument + * @param $options + */ + public function add($argument, array $options = []) + { + if (is_string($argument)) { + $argument = Argument::createFromArray($argument, $options); + } + + if (!($argument instanceof Argument)) { + throw new \Exception('Please provide an argument name or object.'); + } + + $this->arguments[$argument->name()] = $argument; + } + + + /** + * Determine if an argument exists. + * + * @param string $name + * @return bool + */ + public function exists($name) + { + return isset($this->arguments[$name]); + } + + + /** + * Retrieve an argument's value. + * + * @param string $name + * @return string|int|float|bool|null + */ + public function get($name) + { + return isset($this->arguments[$name]) ? $this->arguments[$name]->value() : null; + } + + + /** + * Retrieve all arguments. + * + * @return Argument[] + */ + public function all() + { + return $this->arguments; + } + + + /** + * Determine if an argument has been defined on the command line. + * + * This can be useful for making sure an argument is present on the command + * line before parse()'ing them into argument objects. + * + * @param string $name + * @param array $argv + * + * @return bool + */ + public function defined($name, array $argv = null) + { + // The argument isn't defined if it's not defined by the calling code. + if (!$this->exists($name)) { + return false; + } + + $argument = $this->arguments[$name]; + $command_arguments = $this->parser->arguments($argv); + + foreach ($command_arguments as $command_argument) { + if ($this->isArgument($argument, $command_argument)) { + return true; + } + } + + return false; + } + + + /** + * Check if the defined argument matches the command argument. + * + * @param Argument $argument + * @param string $command_argument + * + * @return bool + */ + private function isArgument($argument, $command_argument) + { + $possibilities = [ + $argument->prefix() => "-{$argument->prefix()}", + $argument->longPrefix() => "--{$argument->longPrefix()}", + ]; + + foreach ($possibilities as $key => $search) { + if ($key && strpos($command_argument, $search) === 0) { + return true; + } + } + + return false; + } + + + /** + * Retrieve all arguments as key/value pairs. + * + * @return array + */ + public function toArray() + { + $return = []; + + foreach ($this->all() as $name => $argument) { + $return[$name] = $argument->value(); + } + + return $return; + } + + + /** + * Set a program's description. + * + * @param string $description + */ + public function description($description) + { + $this->description = trim($description); + } + + + /** + * Output a script's usage statement. + * + * @param CLImate $climate + * @param array $argv + */ + public function usage(CLImate $climate, array $argv = null) + { + $this->summary + ->setClimate($climate) + ->setDescription($this->description) + ->setCommand($this->parser->command($argv)) + ->setFilter($this->filter, $this->all()) + ->output(); + } + + + /** + * Parse command line arguments into CLImate arguments. + * + * @throws \Exception if required arguments aren't defined. + * @param array $argv + */ + public function parse(array $argv = null) + { + $this->parser->setFilter($this->filter, $this->all()); + + $this->parser->parse($argv); + } + + + /** + * Get the trailing arguments + * + * @return string|null + */ + public function trailing() + { + return $this->parser->trailing(); + } +}