diff --git a/src/CommandLine/Parser.php b/src/CommandLine/Parser.php index 0c75125..33805bc 100644 --- a/src/CommandLine/Parser.php +++ b/src/CommandLine/Parser.php @@ -21,6 +21,7 @@ class Parser Repeatable = 'repeatable', Enum = 'enum', RealPath = 'realpath', + Normalizer = 'normalizer', Default = 'default'; /** @deprecated use Parser::Argument */ @@ -139,9 +140,11 @@ public function parse(?array $args = null): array } } + $this->checkArg($opt, $arg); + if ( !empty($opt[self::Enum]) - && !in_array($arg, $opt[self::Enum], true) + && !in_array(is_array($arg) ? reset($arg) : $arg, $opt[self::Enum], true) && !( $opt[self::Optional] && $arg === true @@ -150,8 +153,6 @@ public function parse(?array $args = null): array throw new \Exception("Value of option $name must be " . implode(', or ', $opt[self::Enum]) . '.'); } - $this->checkArg($opt, $arg); - if (empty($opt[self::Repeatable])) { $params[$name] = $arg; } else { @@ -187,6 +188,10 @@ public function help(): void public function checkArg(array $opt, &$arg): void { + if (isset($opt[self::Normalizer])) { + $arg = $opt[self::Normalizer]($arg); + } + if (!empty($opt[self::RealPath])) { $path = realpath($arg); if ($path === false) { diff --git a/tests/Parser.phpt b/tests/Parser.phpt index 4031106..cb6a729 100644 --- a/tests/Parser.phpt +++ b/tests/Parser.phpt @@ -194,6 +194,36 @@ test('realpath', function () { +test('normalizer', function () { + $cmd = new Parser(' + -p param + ', [ + '-p' => [Parser::Normalizer => function ($arg) { return "$arg-normalized"; }], + ]); + + Assert::same(['-p' => 'val-normalized'], $cmd->parse(explode(' ', '-p val'))); + + + $cmd = new Parser(' + -p + ', [ + '-p' => [Parser::Normalizer => function () { return 'a'; }], + ]); + + Assert::same(['-p' => 'a'], $cmd->parse(explode(' ', '-p xxx'))); + + + $cmd = new Parser(' + -p + ', [ + '-p' => [Parser::Normalizer => function () { return ['a', 'foo']; }], + ]); + + Assert::same(['-p' => ['a', 'foo']], $cmd->parse(explode(' ', '-p xxx'))); +}); + + + test('positional arguments', function () { $cmd = new Parser('', [ 'pos' => [],