123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- <?php
-
- namespace Illuminate\Console;
-
- use Illuminate\Support\Str;
- use InvalidArgumentException;
- use Symfony\Component\Console\Input\InputOption;
- use Symfony\Component\Console\Input\InputArgument;
-
- class Parser
- {
- /**
- * Parse the given console command definition into an array.
- *
- * @param string $expression
- * @return array
- *
- * @throws \InvalidArgumentException
- */
- public static function parse($expression)
- {
- $name = static::name($expression);
-
- if (preg_match_all('/\{\s*(.*?)\s*\}/', $expression, $matches)) {
- if (count($matches[1])) {
- return array_merge([$name], static::parameters($matches[1]));
- }
- }
-
- return [$name, [], []];
- }
-
- /**
- * Extract the name of the command from the expression.
- *
- * @param string $expression
- * @return string
- */
- protected static function name($expression)
- {
- if (trim($expression) === '') {
- throw new InvalidArgumentException('Console command definition is empty.');
- }
-
- if (! preg_match('/[^\s]+/', $expression, $matches)) {
- throw new InvalidArgumentException('Unable to determine command name from signature.');
- }
-
- return $matches[0];
- }
-
- /**
- * Extract all of the parameters from the tokens.
- *
- * @param array $tokens
- * @return array
- */
- protected static function parameters(array $tokens)
- {
- $arguments = [];
-
- $options = [];
-
- foreach ($tokens as $token) {
- if (preg_match('/-{2,}(.*)/', $token, $matches)) {
- $options[] = static::parseOption($matches[1]);
- } else {
- $arguments[] = static::parseArgument($token);
- }
- }
-
- return [$arguments, $options];
- }
-
- /**
- * Parse an argument expression.
- *
- * @param string $token
- * @return \Symfony\Component\Console\Input\InputArgument
- */
- protected static function parseArgument($token)
- {
- list($token, $description) = static::extractDescription($token);
-
- switch (true) {
- case Str::endsWith($token, '?*'):
- return new InputArgument(trim($token, '?*'), InputArgument::IS_ARRAY, $description);
- case Str::endsWith($token, '*'):
- return new InputArgument(trim($token, '*'), InputArgument::IS_ARRAY | InputArgument::REQUIRED, $description);
- case Str::endsWith($token, '?'):
- return new InputArgument(trim($token, '?'), InputArgument::OPTIONAL, $description);
- case preg_match('/(.+)\=\*(.+)/', $token, $matches):
- return new InputArgument($matches[1], InputArgument::IS_ARRAY, $description, preg_split('/,\s?/', $matches[2]));
- case preg_match('/(.+)\=(.+)/', $token, $matches):
- return new InputArgument($matches[1], InputArgument::OPTIONAL, $description, $matches[2]);
- default:
- return new InputArgument($token, InputArgument::REQUIRED, $description);
- }
- }
-
- /**
- * Parse an option expression.
- *
- * @param string $token
- * @return \Symfony\Component\Console\Input\InputOption
- */
- protected static function parseOption($token)
- {
- list($token, $description) = static::extractDescription($token);
-
- $matches = preg_split('/\s*\|\s*/', $token, 2);
-
- if (isset($matches[1])) {
- $shortcut = $matches[0];
- $token = $matches[1];
- } else {
- $shortcut = null;
- }
-
- switch (true) {
- case Str::endsWith($token, '='):
- return new InputOption(trim($token, '='), $shortcut, InputOption::VALUE_OPTIONAL, $description);
- case Str::endsWith($token, '=*'):
- return new InputOption(trim($token, '=*'), $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description);
- case preg_match('/(.+)\=\*(.+)/', $token, $matches):
- return new InputOption($matches[1], $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description, preg_split('/,\s?/', $matches[2]));
- case preg_match('/(.+)\=(.+)/', $token, $matches):
- return new InputOption($matches[1], $shortcut, InputOption::VALUE_OPTIONAL, $description, $matches[2]);
- default:
- return new InputOption($token, $shortcut, InputOption::VALUE_NONE, $description);
- }
- }
-
- /**
- * Parse the token into its token and description segments.
- *
- * @param string $token
- * @return array
- */
- protected static function extractDescription($token)
- {
- $parts = preg_split('/\s+:\s+/', trim($token), 2);
-
- return count($parts) === 2 ? $parts : [$token, ''];
- }
- }
|