Skip to content

Commit b2013cf

Browse files
committed
update some logic, add more tests
1 parent e7bd9a9 commit b2013cf

File tree

12 files changed

+350
-40
lines changed

12 files changed

+350
-40
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ $rules = [
168168

169169
**For options**
170170

171+
- option allow set alias/shorts
172+
171173
> TIP: name `long,s` - first is the option name. remaining is short names.
172174
173175
**For arguments**
@@ -187,13 +189,19 @@ The const `SFlags::DEFINE_ITEM`:
187189
// 'index' => 0, // only for argument
188190
'required' => false,
189191
'default' => null,
190-
'aliases' => [], // only for option
192+
'shorts' => [], // only for option
191193
// value validator
192194
'validator' => null,
193195
// 'category' => null
194196
];
195197
```
196198

199+
## Unit tests
200+
201+
```bash
202+
phpunit
203+
```
204+
197205
## License
198206

199207
[MIT](LICENSE)

src/Contract/FlagInterface.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ public function getType(): string;
2828
*/
2929
public function getName(): string;
3030

31+
/**
32+
* @return string
33+
*/
34+
public function getHelpName(): string;
35+
3136
/**
3237
* @return string
3338
*/

src/Contract/ValidatorInterface.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,21 @@
88
interface ValidatorInterface
99
{
1010
/**
11+
* Validate input value
12+
* - you can throw FlagException on fail
13+
*
14+
* Returns:
15+
* - bool `False` mark fail
16+
* - array [bool, value]
17+
* - bool `False` mark fail
18+
* - value filtered new value
19+
*
1120
* @param mixed $value
1221
* @param string $name
1322
*
14-
* @return bool
23+
* @return bool|array
1524
*/
16-
public function __invoke($value, string $name): bool;
25+
public function __invoke($value, string $name);
1726

1827
/**
1928
* @return string

src/Flag/AbstractFlag.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111

1212
use Toolkit\Cli\Helper\FlagHelper;
1313
use Toolkit\PFlag\Contract\FlagInterface;
14+
use Toolkit\PFlag\Contract\ValidatorInterface;
1415
use Toolkit\PFlag\Exception\FlagException;
1516
use Toolkit\PFlag\FlagType;
17+
use function is_array;
18+
use function is_bool;
1619

1720
/**
1821
* Class Flag
@@ -63,9 +66,9 @@ abstract class AbstractFlag implements FlagInterface
6366

6467
/**
6568
* The flag value validator
66-
* - if validate fail, please throw FlagException
69+
* - if validate fail, please return for OR throw FlagException
6770
*
68-
* @var callable
71+
* @var callable|ValidatorInterface
6972
*/
7073
protected $validator;
7174

@@ -142,10 +145,12 @@ public function setValue($value): void
142145
// has validator
143146
if ($cb = $this->validator) {
144147
$ok = true;
145-
$ret = $cb($value);
148+
$ret = $cb($value, $this->name);
146149

147-
if ($ret) {
150+
if (is_array($ret)) {
148151
[$ok, $value] = $ret;
152+
} elseif (is_bool($ret)) {
153+
$ok = $ret;
149154
}
150155

151156
if (false === $ok) {
@@ -184,10 +189,6 @@ public function hasDefault(): bool
184189
return $this->default !== null;
185190
}
186191

187-
/******************************************************************
188-
*
189-
*****************************************************************/
190-
191192
/**
192193
* @return string
193194
*/
@@ -196,6 +197,10 @@ public function getNameMark(): string
196197
return $this->name;
197198
}
198199

200+
/******************************************************************
201+
* getter/setter methods
202+
*****************************************************************/
203+
199204
/**
200205
* @return string
201206
*/

src/Flag/Argument.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ public function getNameMark(): string
4747
return sprintf('#%d%s', $this->index, $mark);
4848
}
4949

50+
/**
51+
* @return string
52+
*/
53+
public function getHelpName(): string
54+
{
55+
return $this->name ?: 'ARG' . $this->index;
56+
}
57+
5058
/**
5159
* @return int
5260
*/

src/Flag/Option.php

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
namespace Toolkit\PFlag\Flag;
1111

1212
use Toolkit\PFlag\FlagType;
13+
use function array_filter;
1314
use function implode;
15+
use function rtrim;
16+
use function trim;
1417

1518
/**
1619
* Class Option
@@ -62,6 +65,10 @@ public function getAlias(): string
6265
*/
6366
public function setAlias(string $alias): void
6467
{
68+
if ($alias = trim($alias)) {
69+
70+
}
71+
6572
$this->alias = $alias;
6673
}
6774

@@ -74,14 +81,13 @@ public function getShortcut(): string
7481
}
7582

7683
/**
77-
* @param string $shortcut eg: 'a,b' Or '-a,-b'
84+
* @param string $shortcut eg: 'a,b' Or '-a,-b' Or '-a, -b'
7885
*/
7986
public function setShortcut(string $shortcut): void
8087
{
81-
$shortcuts = preg_split('{(,)-?}', ltrim($shortcut, '-'));
82-
$shortcuts = array_filter($shortcuts);
88+
$shortcuts = preg_split('{,\s?-?}', ltrim($shortcut, '-'));
8389

84-
$this->setShorts($shortcuts);
90+
$this->setShorts(array_filter($shortcuts));
8591
}
8692

8793
/**
@@ -98,6 +104,35 @@ public function getShorts(): array
98104
public function setShorts(array $shorts): void
99105
{
100106
$this->shorts = $shorts;
101-
$this->shortcut = implode('|', $shorts);
107+
$this->shortcut = '-' . rtrim(implode(', -', $shorts));
108+
}
109+
110+
/**
111+
* @return string
112+
*/
113+
public function getHelpName(): string
114+
{
115+
$shorts = $this->shortcut;
116+
117+
$names = [];
118+
if ($this->alias) {
119+
$names[] = $this->alias;
120+
}
121+
122+
$names[] = $this->name;
123+
124+
return '-' . rtrim(implode(', -', $shorts));
125+
}
126+
127+
/**
128+
* @return array
129+
*/
130+
public function toArray(): array
131+
{
132+
$info = parent::toArray();
133+
134+
$info['alias'] = $this->alias;
135+
$info['shorts'] = $this->shorts;
136+
return $info;
102137
}
103138
}

src/SFlags.php

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class SFlags extends AbstractParser
5050
// 'index' => 0, // only for argument
5151
'required' => false,
5252
'default' => null,
53-
'aliases' => [], // only for option
53+
'shorts' => [], // only for option. ['a', 'b']
5454
// value validator
5555
'validator' => null,
5656
// 'category' => null
@@ -75,7 +75,7 @@ class SFlags extends AbstractParser
7575
* // - array is define item self::DEFINE_ITEM
7676
* 'long,s',
7777
* // name => rule
78-
* // TIP: name 'long,s' - first is the option name. remaining is aliases.
78+
* // TIP: name 'long,s' - first is the option name. remaining is shorts.
7979
* 'long,s' => int,
8080
* 'f' => bool,
8181
* 'long' => string,
@@ -499,25 +499,43 @@ public function parseDefinedArgs(array $argRules): void
499499

500500
// collect value
501501
if ($isArray) {
502-
$this->args[$index] = array_slice($args, $index); // remain args
502+
$arrValues = array_slice($args, $index); // remain args
503+
foreach ($arrValues as $arrValue) {
504+
$this->collectArgValue($arrValue, $index, true, $define);
505+
}
503506
} else {
504507
$value = $args[$index];
505-
506-
// has validator
507-
if ($cb = $define['validator']) {
508-
$ok = $cb($value, $name ?: "#$index");
509-
if ($ok === false) {
510-
throw new FlagException("flag argument '$name' value not pass validate");
511-
}
512-
}
513-
514-
$this->args[$index] = $value;
508+
$this->collectArgValue($value, $index, false, $define);
515509
}
516510

517511
$index++;
518512
}
519513
}
520514

515+
/**
516+
* @param mixed $value
517+
* @param int $index
518+
* @param bool $isArray
519+
* @param array $define
520+
*/
521+
protected function collectArgValue($value, int $index, bool $isArray, array $define): void
522+
{
523+
// has validator
524+
if ($cb = $define['validator']) {
525+
$name = $define['name'] ?: "#$index";
526+
527+
$ok = $cb($value, $define['name'] ?: "#$index");
528+
if ($ok === false) {
529+
throw new FlagException("flag argument '$name' value not pass validate");
530+
}
531+
}
532+
533+
if ($isArray) {
534+
$this->args[$index][] = $value;
535+
} else {
536+
$this->args[$index] = $value;
537+
}
538+
}
521539

522540
/**
523541
* @param int $index
@@ -588,11 +606,11 @@ protected function parseOptRules(array $rules): void
588606
}
589607

590608
/**
591-
* Parse option name and aliases
609+
* Parse option name and shorts
592610
*
593611
* @param string $key 'lang,s' => option name is 'lang', alias 's'
594612
*
595-
* @return array [name, aliases]
613+
* @return array [name, shorts]
596614
*/
597615
protected function parseRuleOptName(string $key): array
598616
{
@@ -609,18 +627,18 @@ protected function parseRuleOptName(string $key): array
609627
$name = '';
610628
$keys = Str::explode($key, ',');
611629

612-
// TIP: first is the option name. remaining is aliases.
613-
$aliases = [];
630+
// TIP: first is the option name. remaining is shorts.
631+
$shorts = [];
614632
foreach ($keys as $i => $k) {
615633
if ($i === 0) {
616634
$name = $k;
617635
} else {
618-
$aliases[] = $k;
636+
$shorts[] = $k;
619637
$this->setAlias($name, $k, true);
620638
}
621639
}
622640

623-
return [$name, $aliases];
641+
return [$name, $shorts];
624642
}
625643

626644
/**
@@ -651,11 +669,11 @@ protected function parseRuleOptName(string $key): array
651669
*/
652670
protected function parseRule($rule, string $name = '', int $index = 0, bool $isOption = true): array
653671
{
654-
$aliasesFromArr = [];
672+
$shortsFromArr = [];
655673
if (is_array($rule)) {
656674
$item = Arr::replace(self::DEFINE_ITEM, $rule);
657675
// set alias by array item
658-
$aliasesFromArr = $item['aliases'];
676+
$shortsFromArr = $item['shorts'];
659677
} else { // parse string rule.
660678
$item = self::DEFINE_ITEM;
661679
$rule = trim((string)$rule, self::TRIM_CHARS);
@@ -683,10 +701,10 @@ protected function parseRule($rule, string $name = '', int $index = 0, bool $isO
683701
$name = $name ?: $item['name'];
684702
if ($isOption) {
685703
// parse option name.
686-
[$name, $aliases] = $this->parseRuleOptName($name);
704+
[$name, $shorts] = $this->parseRuleOptName($name);
687705

688706
// save alias
689-
$item['aliases'] = $aliases ?: $aliasesFromArr;
707+
$item['shorts'] = $shorts ?: $shortsFromArr;
690708
if ($item['required']) {
691709
$this->requiredOpts[] = $name;
692710
}
@@ -832,7 +850,6 @@ public function getArgs(): array
832850
***************************************************************/
833851

834852

835-
836853
/**
837854
* @return array
838855
*/

0 commit comments

Comments
 (0)