Skip to content

Commit fb447ff

Browse files
committedNov 11, 2021
feat: support add multi alises for an option
1 parent 4ffe85f commit fb447ff

12 files changed

+102
-53
lines changed
 

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Generic PHP command line flags parse library
1717

1818
- Generic command line options and arguments parser.
1919
- Support set value data type(`int,string,bool,array`), will auto format input value.
20+
- Support set multi alias names for an option.
2021
- Support set multi short names for an option.
2122
- Support set default value for option/argument.
2223
- Support read flag value from ENV var.

‎README.zh-CN.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- 通用的命令行选项和参数解析器
1919
- 支持设置值数据类型(`int,string,bool,array`),将自动格式化输入值
2020
- 支持为选项/参数设置默认值
21+
- 支持为一个选项设置多个别名
2122
- 支持为一个选项设置多个短名称
2223
- 支持从环境变量读取标志值
2324
- 支持设置选项/参数为必须的(`required`)

‎src/Concern/HelperRenderTrait.php

+6-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Toolkit\Stdlib\Helper\DataHelper;
1212
use Toolkit\Stdlib\Helper\IntHelper;
1313
use Toolkit\Stdlib\Str;
14+
use function array_push;
1415
use function array_shift;
1516
use function count;
1617
use function explode;
@@ -79,7 +80,7 @@ trait HelperRenderTrait
7980
/**
8081
* Will call it on before print help message
8182
*
82-
* @var callable
83+
* @var callable(string): string
8384
*/
8485
private $beforePrintHelp;
8586

@@ -298,9 +299,9 @@ protected function buildOptsForHelp(array $optDefines, bool $hasShortOpt): array
298299
}
299300

300301
$names = $opt['shorts'];
301-
/** @see Option support alias name. */
302-
if (isset($opt['alias']) && $opt['alias']) {
303-
$names[] = $opt['alias'];
302+
// support multi alias names.
303+
if (isset($opt['aliases']) && $opt['aliases']) {
304+
array_push($names, ...$opt['aliases']);
304305
}
305306

306307
// option name.
@@ -472,7 +473,7 @@ public function setExampleHelp($exampleHelp): void
472473
}
473474

474475
/**
475-
* @param callable $beforePrintHelp
476+
* @param callable(string): string $beforePrintHelp
476477
*/
477478
public function setBeforePrintHelp(callable $beforePrintHelp): void
478479
{

‎src/Concern/RuleParserTrait.php

+22-13
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public function addArgsByRules(array $rules): void
142142
/**
143143
* Add and argument by rule
144144
*
145-
* @param string|int $name
145+
* @param string $name
146146
* @param string|array $rule please see {@see argRules}
147147
*
148148
* @return $this
@@ -251,10 +251,11 @@ protected function parseRule($rule, string $name = '', int $index = 0, bool $isO
251251
$name = $name ?: $item['name'];
252252
if ($isOption) {
253253
// parse option name.
254-
[$name, $shorts] = $this->parseRuleOptName($name);
254+
[$name, $shorts, $aliases] = $this->parseRuleOptName($name);
255255

256-
// save alias
257-
$item['shorts'] = $shorts ?: $shortsFromRule;
256+
// save shorts and aliases
257+
$item['shorts'] = $shorts ?: $shortsFromRule;
258+
$item['aliases'] = $aliases;
258259
} else {
259260
$item['index'] = $index;
260261
}
@@ -268,7 +269,7 @@ protected function parseRule($rule, string $name = '', int $index = 0, bool $isO
268269
*
269270
* @param string $key 'lang,s' => option name is 'lang', alias 's'
270271
*
271-
* @return array [name, shorts]
272+
* @return array{string, array, array} [name, shorts, aliases]
272273
*/
273274
protected function parseRuleOptName(string $key): array
274275
{
@@ -278,26 +279,34 @@ protected function parseRuleOptName(string $key): array
278279
}
279280

280281
// only name.
281-
if (strpos($key, ',') === false) {
282+
if (!str_contains($key, ',')) {
282283
$name = ltrim($key, '-');
283-
return [$name, []];
284+
return [$name, [], []];
284285
}
285286

286287
$name = '';
287288
$keys = Str::explode($key, ',');
288289

289-
// TIP: first is the option name. remaining is shorts.
290-
$shorts = [];
290+
$shorts = $aliases = [];
291291
foreach ($keys as $k) {
292292
// support like '--name, -n'
293293
$k = ltrim($k, '-');
294294

295-
// long string as option name.
296-
if (!$name && strlen($k) > 1) {
297-
$name = $k;
295+
// max length string as option name.
296+
if (($kl = strlen($k)) > 1) {
297+
if (!$name ) {
298+
$name = $k;
299+
} elseif ($kl > strlen($name)) {
300+
$aliases[] = $name;
301+
// update name
302+
$name = $k;
303+
} else {
304+
$aliases[] = $k;
305+
}
298306
continue;
299307
}
300308

309+
// one char, as shorts
301310
$shorts[] = $k;
302311
}
303312

@@ -306,7 +315,7 @@ protected function parseRuleOptName(string $key): array
306315
$name = array_shift($shorts);
307316
}
308317

309-
return [$name, $shorts];
318+
return [$name, $shorts, $aliases];
310319
}
311320

312321
/**

‎src/Flag/Option.php

+25-17
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@
2828
class Option extends AbstractFlag
2929
{
3030
/**
31-
* alias name
31+
* Shortcuts of the option. eg: ['a', 'b']
3232
*
33-
* @var string
33+
* @var array
3434
*/
35-
private $alias = '';
35+
private $shorts = [];
3636

3737
/**
38-
* Shortcuts of the option. eg: ['a', 'b']
38+
* alias names
3939
*
40-
* @var array
40+
* @var string[]
4141
*/
42-
private $shorts = [];
42+
private $aliases = [];
4343

4444
/**
4545
* Shortcuts of the option, string format. eg: 'a|b'
@@ -62,11 +62,21 @@ public function isBoolean(): bool
6262
}
6363

6464
/**
65-
* @return string
65+
* @return string[]
6666
*/
67-
public function getAlias(): string
67+
public function getAliases(): array
6868
{
69-
return $this->alias;
69+
return $this->aliases;
70+
}
71+
72+
/**
73+
* @param string[] $aliases
74+
*/
75+
public function setAliases(array $aliases): void
76+
{
77+
foreach ($aliases as $alias) {
78+
$this->setAlias($alias);
79+
}
7080
}
7181

7282
/**
@@ -86,7 +96,7 @@ public function setAlias(string $alias): void
8696
throw new FlagException('flag option alias length cannot be < 2 ');
8797
}
8898

89-
$this->alias = $alias;
99+
$this->aliases[] = $alias;
90100
}
91101

92102
/**
@@ -146,11 +156,8 @@ public function getDesc(bool $forHelp = false): string
146156
*/
147157
public function getHelpName(): string
148158
{
149-
$longs = [];
150-
if ($this->alias) {
151-
$longs[] = $this->alias;
152-
}
153-
159+
$longs = $this->aliases;
160+
// append name
154161
$longs[] = $this->name;
155162

156163
// prepend '--'
@@ -188,8 +195,9 @@ public function toArray(): array
188195
{
189196
$info = parent::toArray();
190197

191-
$info['alias'] = $this->alias;
192-
$info['shorts'] = $this->shorts;
198+
$info['aliases'] = $this->aliases;
199+
$info['shorts'] = $this->shorts;
193200
return $info;
194201
}
202+
195203
}

‎src/Flags.php

+13-11
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ protected function setOptValue(string $name, $value): bool
340340
{
341341
$name = $this->resolveAlias($name);
342342
if (!isset($this->options[$name])) {
343-
throw new FlagException("flag option provided but not defined: $name", 404);
343+
throw new FlagException("cannot set value for not defined option: $name", 404);
344344
}
345345

346346
$this->options[$name]->setValue($value);
@@ -759,7 +759,7 @@ protected function resetArguments(): void
759759
* @param mixed $default
760760
* @param array $moreInfo
761761
*
762-
* @psalm-param array{alias: string, helpType: string} $moreInfo
762+
* @psalm-param array{aliases: array, helpType: string} $moreInfo
763763
*
764764
* @return ParserInterface|self
765765
*/
@@ -774,7 +774,7 @@ public function addOpt(
774774
): ParserInterface {
775775
/** @var Option $opt */
776776
$opt = Option::new($name, $desc, $type, $required, $default);
777-
$opt->setAlias($moreInfo['alias'] ?? '');
777+
$opt->setAliases($moreInfo['aliases'] ?? []);
778778
$opt->setShortcut($shortcut);
779779

780780
$this->addOption($opt);
@@ -797,8 +797,8 @@ public function addOptByRule(string $name, $rule): FlagsParser
797797
/** @var Option $option */
798798
$option = Option::newByArray($define['name'], $define);
799799

800-
if (is_array($rule) && isset($rule['alias'])) {
801-
$option->setAlias($rule['alias']);
800+
if (is_array($rule) && isset($rule['aliases'])) {
801+
$option->setAliases($rule['aliases']);
802802
}
803803

804804
parent::addOptByRule($name, $rule);
@@ -831,13 +831,15 @@ public function addOption(Option $option): self
831831
throw new FlagException('cannot repeat add option: ' . $name);
832832
}
833833

834-
// has alias
835-
if ($alias = $option->getAlias()) {
836-
if (isset($this->options[$alias])) {
837-
throw new FlagException("cannot assign alias '$alias' to option '$name', '$alias' is exists option");
838-
}
834+
// has aliases
835+
if ($aliases = $option->getAliases()) {
836+
foreach ($aliases as $alias) {
837+
if (isset($this->options[$alias])) {
838+
throw new FlagException("cannot assign alias '$alias' to option '$name', '$alias' is exists option");
839+
}
839840

840-
$this->setAlias($name, $alias, true);
841+
$this->setAlias($name, $alias, true);
842+
}
841843
}
842844

843845
// has shorts

‎src/FlagsParser.php

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ abstract class FlagsParser implements ParserInterface
6262
'envVar' => '', // support read value from ENV var
6363
'default' => null,
6464
'shorts' => [], // only for option. ['a', 'b']
65+
'aliases' => [], // only for option. ['cd', 'ef']
6566
'hidden' => false, // only for option
6667
// value validator
6768
'validator' => null,

‎src/SFlags.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ protected function setOptValue(string $option, $value): void
495495
{
496496
$option = $this->resolveAlias($option);
497497
if (!isset($this->optDefines[$option])) {
498-
throw new FlagException("flag option provided but not defined: $option", 404);
498+
throw new FlagException("cannot set value for not defined option: $option", 404);
499499
}
500500

501501
$define = $this->optDefines[$option];
@@ -696,6 +696,13 @@ protected function addOptDefine(array $define): void
696696
$this->opts[$name] = FlagType::fmtBasicTypeValue($type, $envVal);
697697
}
698698

699+
// has shorts
700+
if ($define['aliases']) {
701+
foreach ($define['aliases'] as $alias) {
702+
$this->setAlias($name, $alias, true);
703+
}
704+
}
705+
699706
// has shorts
700707
if ($define['shorts']) {
701708
foreach ($define['shorts'] as $short) {

‎test/Concern/RuleParserTest.php

+12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Toolkit\PFlagTest\BaseFlagsTestCase;
66
use Toolkit\PFlagTest\RuleParser;
7+
use function vdump;
78

89
/**
910
* class RuleParserTest
@@ -40,4 +41,15 @@ public function testParseRule_string(): void
4041
$this->assertSame(['23', '45'], $define['default']);
4142
}
4243

44+
45+
public function testParseRule_string_hasAliases(): void
46+
{
47+
$p = RuleParser::new();
48+
49+
$define = $p->parseOpt('this is an string', '-t, --tpl, --tpl-file');
50+
51+
$this->assertEquals('tpl-file', $define['name']);
52+
$this->assertEquals(['tpl'], $define['aliases']);
53+
$this->assertEquals(['t'], $define['shorts']);
54+
}
4355
}

‎test/Flag/OptionTest.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ public function testBasic(): void
1818
$this->assertFalse($opt->hasDefault());
1919
$this->assertFalse($opt->hasValue());
2020

21-
$opt->setAlias('n1');
22-
$this->assertSame('n1', $opt->getAlias());
23-
$this->assertSame('--n1, --name', $opt->getHelpName());
21+
$opt->setAliases(['n1', 'n2']);
22+
$this->assertSame(['n1', 'n2'], $opt->getAliases());
23+
$this->assertSame('--n1, --n2, --name', $opt->getHelpName());
2424

2525
$opt->setShortcut('n');
26-
$this->assertSame('-n, --n1, --name', $opt->getHelpName());
26+
$this->assertEquals('-n, --n1, --n2, --name', $opt->getHelpName());
2727

2828
$opt->setDefault(89);
2929
$this->assertTrue($opt->hasDefault());

‎test/FlagsParserTest.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ private function doCheckBasic(FlagsParser $fs): void
5454
$this->assertSame('http://github.com/inhere', $fs->getArg('github'));
5555
}
5656

57+
// public function testOption_aliases(): void
58+
// {
59+
// $this->runTestsWithParsers(function (FlagsParser $fs) {
60+
// // $fs->addOptByRule('', $rule)
61+
// });
62+
// }
63+
5764
public function testGetOptAndGetArg(): void
5865
{
5966
$this->runTestsWithParsers(function (FlagsParser $fs) {
@@ -271,7 +278,7 @@ protected function doCheckRepeatName(FlagsParser $fs): void
271278
]);
272279
}, $fs);
273280

274-
$this->assertSame(FlagException::class, get_class($e));
281+
$this->assertEquals(FlagException::class, get_class($e));
275282

276283
$e = $this->runAndGetException(function (FlagsParser $fs) {
277284
$fs->addArgsByRules([

‎test/FlagsTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*/
2424
class FlagsTest extends BaseFlagsTestCase
2525
{
26-
public function testParse(): void
26+
public function testAddOptionAndParse(): void
2727
{
2828
$fs = Flags::new();
2929
$fs->addOption(Option::new('name'));

0 commit comments

Comments
 (0)
Please sign in to comment.