Skip to content

Commit 858dee8

Browse files
authored
Merge pull request #4 from adhocore/develop
Develop
2 parents aa5d43a + 29ca631 commit 858dee8

File tree

7 files changed

+133
-120
lines changed

7 files changed

+133
-120
lines changed

src/Argument.php

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,8 @@
1010
*
1111
* @link https://github.com/adhocore/cli
1212
*/
13-
class Argument
13+
class Argument extends Parameter
1414
{
15-
use InflectsString;
16-
17-
protected $name;
18-
19-
protected $rawArg;
20-
21-
protected $default;
22-
23-
protected $required = false;
24-
25-
protected $variadic = false;
26-
27-
public function __construct(string $arg)
28-
{
29-
$this->rawArg = $arg;
30-
31-
$this->parse($arg);
32-
}
33-
3415
protected function parse(string $arg)
3516
{
3617
$this->required = $arg[0] === '<';
@@ -44,26 +25,6 @@ protected function parse(string $arg)
4425
}
4526
}
4627

47-
public function name(): string
48-
{
49-
return $this->name;
50-
}
51-
52-
public function attributeName(): string
53-
{
54-
return $this->toCamelCase($this->name);
55-
}
56-
57-
public function required(): bool
58-
{
59-
return $this->required;
60-
}
61-
62-
public function variadic(): bool
63-
{
64-
return $this->variadic;
65-
}
66-
6728
public function default()
6829
{
6930
if (!$this->variadic) {

src/ArgvParser.php

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,12 @@ public function arguments(string $definitions): self
7777
throw new \InvalidArgumentException('Only last argument can be variadic');
7878
}
7979

80-
$this->_arguments[$argument->name()] = $argument;
81-
$this->_values[$argument->attributeName()] = $argument->default();
80+
$name = $argument->attributeName();
81+
82+
$this->ifAlreadyRegistered($name, $argument);
83+
84+
$this->_arguments[$name] = $argument;
85+
$this->_values[$name] = $argument->default();
8286
}
8387

8488
return $this;
@@ -97,19 +101,26 @@ public function arguments(string $definitions): self
97101
public function option(string $cmd, string $desc = '', callable $filter = null, $default = null): self
98102
{
99103
$option = new Option($cmd, $desc, $default, $filter);
104+
$name = $option->attributeName();
100105

101-
if (isset($this->_options[$option->long()])) {
102-
throw new \InvalidArgumentException(
103-
\sprintf('The option "%s" is already registered', $option->long())
104-
);
105-
}
106+
$this->ifAlreadyRegistered($name, $option);
106107

107-
$this->_values[$option->attributeName()] = $option->default();
108-
$this->_options[$option->long()] = $option;
108+
$this->_options[$name] = $option;
109+
$this->_values[$name] = $option->default();
109110

110111
return $this;
111112
}
112113

114+
protected function ifAlreadyRegistered(string $name, Parameter $param)
115+
{
116+
if (\array_key_exists($name, $this->_values)) {
117+
throw new \InvalidArgumentException(\sprintf(
118+
'The parameter "%s" is already registered',
119+
$param instanceof Option ? $param->long() : $param->name()
120+
));
121+
}
122+
}
123+
113124
/**
114125
* Sets event handler for last option.
115126
*
@@ -176,7 +187,12 @@ public function values(bool $withDefaults = true): array
176187
*/
177188
public function __get(string $key)
178189
{
179-
return isset($this->_values[$key]) ? $this->_values[$key] : null;
190+
return $this->_values[$key] ?? null;
191+
}
192+
193+
public function args(): array
194+
{
195+
return \array_diff_key($this->_values, $this->_options);
180196
}
181197

182198
protected function showHelp()

src/Option.php

Lines changed: 10 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -10,58 +10,37 @@
1010
*
1111
* @link https://github.com/adhocore/cli
1212
*/
13-
class Option
13+
class Option extends Parameter
1414
{
15-
use InflectsString;
16-
1715
protected $short;
1816

1917
protected $long;
2018

21-
protected $desc;
22-
23-
protected $rawCmd;
24-
25-
protected $default;
26-
27-
protected $required = true;
28-
29-
protected $optional = false;
30-
31-
protected $variadic = false;
32-
3319
protected $filter;
3420

35-
public function __construct(string $cmd, string $desc = null, $default = null, callable $filter = null)
21+
public function __construct(string $raw, string $desc = null, $default = null, callable $filter = null)
3622
{
37-
$this->rawCmd = $cmd;
38-
$this->desc = $desc;
39-
$this->default = $default;
40-
$this->filter = $filter;
41-
$this->required = \strpos($cmd, '<') !== false;
42-
$this->optional = \strpos($cmd, '[') !== false;
43-
44-
if ($this->variadic = \strpos($cmd, '...') !== false) {
45-
$this->default = (array) $this->default;
46-
}
23+
$this->filter = $filter;
4724

48-
$this->parse($cmd);
25+
parent::__construct($raw, $desc, $default);
4926
}
5027

51-
protected function parse(string $cmd)
28+
protected function parse(string $raw)
5229
{
53-
if (\strpos($cmd, '-with-') !== false) {
30+
if (\strpos($raw, '-with-') !== false) {
5431
$this->default = false;
55-
} elseif (\strpos($cmd, '-no-') !== false) {
32+
} elseif (\strpos($raw, '-no-') !== false) {
5633
$this->default = true;
5734
}
5835

59-
$parts = \preg_split('/[\s,\|]+/', $cmd);
36+
$parts = \preg_split('/[\s,\|]+/', $raw);
6037

6138
$this->short = $this->long = $parts[0];
6239
if (isset($parts[1])) {
6340
$this->long = $parts[1];
6441
}
42+
43+
$this->name = \str_replace(['--', 'no-', 'with-'], '', $this->long);
6544
}
6645

6746
public function long(): string
@@ -74,41 +53,11 @@ public function short(): string
7453
return $this->short;
7554
}
7655

77-
public function name(): string
78-
{
79-
return \str_replace(['--', 'no-', 'with-'], '', $this->long);
80-
}
81-
82-
public function attributeName(): string
83-
{
84-
return $this->toCamelCase($this->name());
85-
}
86-
8756
public function is($arg): bool
8857
{
8958
return $this->short === $arg || $this->long === $arg;
9059
}
9160

92-
public function required(): bool
93-
{
94-
return $this->required;
95-
}
96-
97-
public function optional(): bool
98-
{
99-
return $this->optional;
100-
}
101-
102-
public function variadic(): bool
103-
{
104-
return $this->variadic;
105-
}
106-
107-
public function default()
108-
{
109-
return $this->default;
110-
}
111-
11261
public function bool(): bool
11362
{
11463
return \preg_match('/\-no|\-with/', $this->long) > 0;

src/Parameter.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
namespace Ahc\Cli;
4+
5+
/**
6+
* Cli Parameter.
7+
*
8+
* @author Jitendra Adhikari <[email protected]>
9+
* @license MIT
10+
*
11+
* @link https://github.com/adhocore/cli
12+
*/
13+
abstract class Parameter
14+
{
15+
use InflectsString;
16+
17+
protected $name;
18+
19+
protected $raw;
20+
21+
protected $desc;
22+
23+
protected $default;
24+
25+
protected $required = false;
26+
27+
protected $optional = false;
28+
29+
protected $variadic = false;
30+
31+
public function __construct(string $raw, string $desc = null, $default = null)
32+
{
33+
$this->raw = $raw;
34+
$this->desc = $desc;
35+
$this->default = $default;
36+
$this->required = \strpos($raw, '<') !== false;
37+
$this->optional = \strpos($raw, '[') !== false;
38+
$this->variadic = \strpos($raw, '...') !== false;
39+
40+
$this->parse($raw);
41+
}
42+
43+
abstract protected function parse(string $raw);
44+
45+
public function raw(): string
46+
{
47+
return $this->raw;
48+
}
49+
50+
public function name(): string
51+
{
52+
return $this->name;
53+
}
54+
55+
public function attributeName(): string
56+
{
57+
return $this->toCamelCase($this->name);
58+
}
59+
60+
public function required(): bool
61+
{
62+
return $this->required;
63+
}
64+
65+
public function optional(): bool
66+
{
67+
return $this->optional;
68+
}
69+
70+
public function variadic(): bool
71+
{
72+
return $this->variadic;
73+
}
74+
75+
public function default()
76+
{
77+
return $this->default;
78+
}
79+
}

src/Parser.php

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ public function parse(array $argv): self
4343
$argv = $this->normalize($argv);
4444
$count = \count($argv);
4545

46+
$literal = false;
4647
for ($i = 0; $i < $count; $i++) {
47-
list($arg, $nextArg) = [$argv[$i], isset($argv[$i + 1]) ? $argv[$i + 1] : null];
48+
list($arg, $nextArg) = [$argv[$i], $argv[$i + 1] ?? null];
4849

49-
if ($arg[0] !== '-' || !empty($literal) || ($literal = $arg === '--')) {
50+
$literal = $literal ?: $arg === '--';
51+
if ($arg[0] !== '-' || $literal) {
5052
$this->parseArgs($arg);
5153
} else {
5254
$i += (int) $this->parseOptions($arg, $nextArg);
@@ -86,7 +88,7 @@ protected function splitShort(string $arg): array
8688

8789
protected function parseArgs(string $arg)
8890
{
89-
if ($arg == '--') {
91+
if ($arg === '--') {
9092
return;
9193
}
9294

@@ -129,18 +131,14 @@ protected function parseOptions(string $arg, string $nextArg = null)
129131
return $isValue;
130132
}
131133

132-
$this->emit($option->long());
134+
$this->emit($option->attributeName());
133135
$this->setValue($option, $value);
134136

135137
return $isValue;
136138
}
137139

138140
protected function optionFor(string $arg)
139141
{
140-
if (isset($this->_options[$arg])) {
141-
return $this->_options[$arg];
142-
}
143-
144142
foreach ($this->_options as $option) {
145143
if ($option->is($arg)) {
146144
return $option;

tests/ArgvParserTest.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public function test_arguments_with_options()
8787
public function test_options_repeat()
8888
{
8989
$this->expectException(\InvalidArgumentException::class);
90-
$this->expectExceptionMessage('The option "--apple" is already registered');
90+
$this->expectExceptionMessage('The parameter "--apple" is already registered');
9191

9292
$p = $this->newParser()->option('-a --apple', 'Apple')->option('-a --apple', 'Apple');
9393
}
@@ -203,6 +203,14 @@ public function test_no_value()
203203
$this->assertNull($p->xyz);
204204
}
205205

206+
public function test_args()
207+
{
208+
$p = $this->newParser()->arguments('<a> [b]')->option('-x --xyz')
209+
->parse(['php', 'A', '-x', 'X', 'B', 'C', 'D']);
210+
211+
$this->assertSame(['a' => 'A', 'b' => 'B', 'C', 'D'], $p->args());
212+
}
213+
206214
protected function newParser(string $version = '0.0.1', string $desc = null, bool $allowUnknown = false)
207215
{
208216
$p = new ArgvParser('ArgvParserTest', $desc, $allowUnknown);

tests/OptionTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public function test_new($cmd, $expect)
2020
$more += ['bool' => $o->bool()];
2121
}
2222

23+
$this->assertEquals($cmd, $o->raw());
24+
2325
$this->assertEquals($expect, [
2426
'long' => $o->long(),
2527
'short' => $o->short(),

0 commit comments

Comments
 (0)