Skip to content

Commit aac5e91

Browse files
committed
up: add more check for add flags bind, add more tests
1 parent 1974d5c commit aac5e91

File tree

9 files changed

+443
-274
lines changed

9 files changed

+443
-274
lines changed

src/Concern/HelperRenderTrait.php

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
namespace Toolkit\PFlag\Concern;
44

55
use Toolkit\Cli\Color\ColorTag;
6-
use Toolkit\PFlag\FlagsParser;
76
use Toolkit\PFlag\Flag\Argument;
87
use Toolkit\PFlag\Flag\Option;
8+
use Toolkit\PFlag\FlagsParser;
99
use Toolkit\PFlag\FlagType;
1010
use Toolkit\PFlag\FlagUtil;
1111
use Toolkit\Stdlib\Helper\DataHelper;
@@ -72,10 +72,11 @@ trait HelperRenderTrait
7272
* @param array $argDefines
7373
* @param array $optDefines
7474
* @param bool $withColor
75+
* @param bool $hasShortOpt
7576
*
7677
* @return string
7778
*/
78-
protected function doBuildHelp(array $argDefines, array $optDefines, bool $withColor): string
79+
protected function doBuildHelp(array $argDefines, array $optDefines, bool $withColor, bool $hasShortOpt = false): string
7980
{
8081
$buf = Str\StrBuffer::new();
8182

@@ -90,7 +91,7 @@ protected function doBuildHelp(array $argDefines, array $optDefines, bool $withC
9091
// ------- usage -------
9192
$binName = $this->scriptName ?: FlagUtil::getBinName();
9293
if ($hasArgs || $hasOpts) {
93-
$buf->writeln("<ylw>Usage:</ylw> $binName [Options ...] -- [Arguments ...]\n");
94+
$buf->writeln("<ylw>Usage:</ylw> $binName [--Options ...] [Arguments ...]\n");
9495
}
9596

9697
// ------- args -------
@@ -126,7 +127,7 @@ protected function doBuildHelp(array $argDefines, array $optDefines, bool $withC
126127
}
127128

128129
$nameTag = 'info';
129-
$fmtOpts = $this->buildOptsForHelp($optDefines);
130+
$fmtOpts = $this->buildOptsForHelp($optDefines, $hasShortOpt);
130131

131132
$nameLen = $this->settings['optNameLen'];
132133
$maxWidth = $this->settings['descNlOnOptLen'];
@@ -156,7 +157,7 @@ protected function doBuildHelp(array $argDefines, array $optDefines, bool $withC
156157
$buf->writeln("\n<ylw>Examples:</ylw>");
157158

158159
$lines = is_array($this->exampleHelp) ? $this->exampleHelp : [$this->exampleHelp];
159-
$buf->writeln(' ' . implode("\n ", $lines));;
160+
$buf->writeln(' ' . implode("\n ", $lines));
160161
}
161162

162163
if ($this->moreHelp) {
@@ -258,10 +259,11 @@ protected function buildArgsForHelp(array $argDefines): array
258259

259260
/**
260261
* @param array $optDefines
262+
* @param bool $hasShortOpt
261263
*
262264
* @return array
263265
*/
264-
protected function buildOptsForHelp(array $optDefines): array
266+
protected function buildOptsForHelp(array $optDefines, bool $hasShortOpt): array
265267
{
266268
if (!$optDefines) {
267269
return [];
@@ -271,26 +273,34 @@ protected function buildOptsForHelp(array $optDefines): array
271273
$nameLen = $this->settings['optNameLen'];
272274
ksort($optDefines);
273275

274-
/** @var array|Option $opt {@see DEFINE_ITEM} */
276+
// $hasShortOpt=true will add `strlen('-h, ')` indent.
277+
$prefix = $hasShortOpt ? ' ' : '';
278+
279+
/** @var array|Option $opt {@see FlagsParser::DEFINE_ITEM} */
275280
foreach ($optDefines as $name => $opt) {
276281
$names = $opt['shorts'];
277282
/** @see Option support alias name. */
278283
if (isset($opt['alias']) && $opt['alias']) {
279284
$names[] = $opt['alias'];
280285
}
281-
// real name.
282-
$names[] = $name;
283286

284-
if ($desc = $opt['desc']) {
285-
$desc = trim($desc);
286-
}
287+
// option name.
288+
$names[] = $name;
289+
// option description
290+
$desc = $opt['desc'] ? trim($opt['desc']) : '';
287291

288292
// ensure desc is not empty
289293
$opt['desc'] = $desc ? Str::ucfirst($desc) : "Option $name";
294+
$helpName = FlagUtil::buildOptHelpName($names);
295+
296+
// first elem is long option name.
297+
if (isset($names[0][1])) {
298+
$helpName = $prefix . $helpName;
299+
}
290300

291-
$helpName = FlagUtil::buildOptHelpName($names);
301+
// show type name.
292302
if ($this->showTypeOnHelp) {
293-
$typeName = FlagType::getHelpName($opt['type']);
303+
$typeName = $opt['showType'] ?: FlagType::getHelpName($opt['type']);
294304
$helpName .= $typeName ? " $typeName" : '';
295305
}
296306

src/Concern/RuleParserTrait.php

Lines changed: 83 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
namespace Toolkit\PFlag\Concern;
44

55
use InvalidArgumentException;
6-
use Toolkit\PFlag\FlagsParser;
76
use Toolkit\PFlag\Exception\FlagException;
7+
use Toolkit\PFlag\FlagsParser;
88
use Toolkit\PFlag\FlagType;
99
use Toolkit\Stdlib\Arr;
1010
use Toolkit\Stdlib\Str;
1111
use function array_shift;
1212
use function is_array;
1313
use function is_callable;
14+
use function is_int;
15+
use function is_numeric;
1416
use function ltrim;
1517
use function strlen;
1618
use function strpos;
@@ -84,6 +86,77 @@ trait RuleParserTrait
8486
*/
8587
protected $argRules = [];
8688

89+
/****************************************************************
90+
* add rule methods
91+
***************************************************************/
92+
93+
/**
94+
* @param array $rules
95+
*/
96+
public function addOptsByRules(array $rules): void
97+
{
98+
foreach ($rules as $name => $rule) {
99+
if (is_int($name)) { // only name.
100+
$name = (string)$rule;
101+
$rule = FlagType::STRING;
102+
} else {
103+
$name = (string)$name;
104+
}
105+
106+
$this->addOptByRule($name, $rule);
107+
}
108+
}
109+
110+
/**
111+
* Add and option by rule
112+
*
113+
* @param string $name
114+
* @param string|array $rule {@see optRules}
115+
*
116+
* @return $this
117+
*/
118+
public function addOptByRule(string $name, $rule): self
119+
{
120+
$this->optRules[$name] = $rule;
121+
122+
return $this;
123+
}
124+
125+
/**
126+
* @param array $rules
127+
*
128+
* @see addArgByRule()
129+
*/
130+
public function addArgsByRules(array $rules): void
131+
{
132+
foreach ($rules as $name => $rule) {
133+
if (!$rule) {
134+
throw new FlagException('flag argument rule cannot be empty');
135+
}
136+
137+
$this->addArgByRule((string)$name, $rule);
138+
}
139+
}
140+
141+
/**
142+
* Add and argument by rule
143+
*
144+
* @param string|int $name
145+
* @param string|array $rule please see {@see argRules}
146+
*
147+
* @return $this
148+
*/
149+
public function addArgByRule(string $name, $rule): self
150+
{
151+
if ($name && !is_numeric($name)) {
152+
$this->argRules[$name] = $rule;
153+
} else {
154+
$this->argRules[] = $rule;
155+
}
156+
157+
return $this;
158+
}
159+
87160
/****************************************************************
88161
* parse rule to definition
89162
***************************************************************/
@@ -107,16 +180,20 @@ trait RuleParserTrait
107180
* - 'type;;;default' - not set required,desc
108181
*
109182
* @param string|array $rule
110-
* @param string $name
111-
* @param int $index
112-
* @param bool $isOption
183+
* @param string $name
184+
* @param int $index
185+
* @param bool $isOption
113186
*
114187
* @return array {@see FlagsParser::DEFINE_ITEM}
115188
* @see argRules
116189
* @see optRules
117190
*/
118191
protected function parseRule($rule, string $name = '', int $index = 0, bool $isOption = true): array
119192
{
193+
if (!$rule) {
194+
$rule = FlagType::STRING;
195+
}
196+
120197
$shortsFromRule = [];
121198
if (is_array($rule)) {
122199
$item = Arr::replace(FlagsParser::DEFINE_ITEM, $rule);
@@ -240,35 +317,6 @@ protected function parseRuleOptName(string $key): array
240317
return [$name, $shorts];
241318
}
242319

243-
/****************************************************************
244-
* add rule methods
245-
***************************************************************/
246-
247-
/**
248-
* @param array $rules
249-
*/
250-
public function addOptsByRules(array $rules): void
251-
{
252-
foreach ($rules as $name => $rule) {
253-
$this->addOptByRule($name, $rule);
254-
}
255-
}
256-
257-
/**
258-
* Add and option by rule
259-
*
260-
* @param string $name
261-
* @param string|array $rule {@see optRules}
262-
*
263-
* @return $this
264-
*/
265-
public function addOptByRule(string $name, $rule): self
266-
{
267-
$this->optRules[$name] = $rule;
268-
269-
return $this;
270-
}
271-
272320
/**
273321
* @return array
274322
*/
@@ -284,7 +332,7 @@ public function getOptRules(): array
284332
*/
285333
public function setOptRules(array $optRules): void
286334
{
287-
$this->optRules = $optRules;
335+
$this->addOptsByRules($optRules);
288336
}
289337

290338
/**
@@ -302,38 +350,7 @@ public function getArgRules(): array
302350
*/
303351
public function setArgRules(array $argRules): void
304352
{
305-
$this->argRules = $argRules;
306-
}
307-
308-
/**
309-
* @param array $rules
310-
*
311-
* @see addArgByRule()
312-
*/
313-
public function addArgsByRules(array $rules): void
314-
{
315-
foreach ($rules as $name => $rule) {
316-
$this->addArgByRule($name, $rule);
317-
}
318-
}
319-
320-
/**
321-
* Add and argument by rule
322-
*
323-
* @param string $name
324-
* @param string|array $rule please see {@see argRules}
325-
*
326-
* @return $this
327-
*/
328-
public function addArgByRule(string $name, $rule): self
329-
{
330-
if ($name) {
331-
$this->argRules[$name] = $rule;
332-
} else {
333-
$this->argRules[] = $rule;
334-
}
335-
336-
return $this;
353+
$this->addArgsByRules($argRules);
337354
}
338355

339356
}

src/Contract/ParserInterface.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public function getFlags(): array;
2626
*/
2727
public function getRawArgs(): array;
2828

29+
/**
30+
* @return bool
31+
*/
32+
public function isEmpty(): bool;
33+
2934
/**
3035
* @return bool
3136
*/
@@ -66,7 +71,7 @@ public function addOpt(
6671
* @param mixed $default
6772
* @param array $moreInfo
6873
*
69-
* @psalm-param array{alias: string, showType: string} $moreInfo
74+
* @psalm-param array{showType: string} $moreInfo
7075
*
7176
* @return self
7277
*/
@@ -136,4 +141,13 @@ public function getArgs(): array;
136141
* @psalm-return array<string, string>
137142
*/
138143
public function getOptSimpleDefines(): array;
144+
145+
/**
146+
* @return bool
147+
*/
148+
public function isLocked(): bool;
149+
150+
public function lock(): void;
151+
152+
public function unlock(): void;
139153
}

src/Flag/AbstractFlag.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public static function newByArray(string $name, array $define): self
140140
* @param string $desc
141141
* @param string $type
142142
* @param bool $required
143-
* @param mixed $default The default value
143+
* @param mixed $default The default value
144144
* - for Flag::ARG_OPTIONAL mode only
145145
* - must be null for Flag::OPT_BOOLEAN
146146
*/
@@ -359,11 +359,17 @@ public function setRequired(bool $required): void
359359
}
360360

361361
/**
362+
* @param bool $useTypeOnEmpty
363+
*
362364
* @return string
363365
*/
364-
public function getShowType(): string
366+
public function getShowType(bool $useTypeOnEmpty = false): string
365367
{
366-
return $this->showType ?: $this->type;
368+
if ($useTypeOnEmpty) {
369+
return $this->showType ?: $this->type;
370+
}
371+
372+
return $this->showType;
367373
}
368374

369375
/**

0 commit comments

Comments
 (0)