Skip to content

Commit 1119e7f

Browse files
committed
refactor: update handler construct sign, add some tests
1 parent 4dfe19f commit 1119e7f

10 files changed

+185
-60
lines changed

src/Application.php

+35-29
Original file line numberDiff line numberDiff line change
@@ -296,40 +296,46 @@ protected function runCommand(array $info, array $config, array $args): mixed
296296
$handler = $info['handler'];
297297
$iptName = $info['name'];
298298

299-
if (is_object($handler) && method_exists($handler, '__invoke')) {
300-
$fs = SFlags::new();
301-
$fs->setName($iptName);
302-
$fs->addOptsByRules(GlobalOption::getAloneOptions());
303-
304-
// command flags load
305-
if ($cmdOpts = $config['options'] ?? null) {
306-
$fs->addOptsByRules($cmdOpts);
299+
if (is_object($handler)) {
300+
// Command object
301+
if ($handler instanceof Command) {
302+
$handler->setInputOutput($this->input, $this->output);
303+
$result = $handler->run($args);
304+
} else { // Closure
305+
$fs = SFlags::new();
306+
$fs->setName($iptName);
307+
$fs->addOptsByRules(GlobalOption::getAloneOptions());
308+
309+
// command flags load
310+
if ($cmdOpts = $config['options'] ?? null) {
311+
$fs->addOptsByRules($cmdOpts);
312+
}
313+
if ($cmdArgs = $config['arguments'] ?? null) {
314+
$fs->addArgsByRules($cmdArgs);
315+
}
316+
317+
$fs->setDesc($config['desc'] ?? 'No command description message');
318+
319+
// save to input object
320+
$this->input->setFs($fs);
321+
322+
if (!$fs->parse($args)) {
323+
return 0; // render help
324+
}
325+
326+
$result = $handler($fs, $this->output);
307327
}
308-
if ($cmdArgs = $config['arguments'] ?? null) {
309-
$fs->addArgsByRules($cmdArgs);
310-
}
311-
312-
$fs->setDesc($config['desc'] ?? 'No command description message');
313-
314-
// save to input object
315-
$this->input->setFs($fs);
316-
317-
if (!$fs->parse($args)) {
318-
return 0; // render help
319-
}
320-
321-
$result = $handler($fs, $this->output);
322328
} else {
323329
Assert::isTrue(class_exists($handler), "The console command class [$handler] not exists!");
324330

325-
$object = new $handler($this->input, $this->output);
326-
Assert::isTrue($object instanceof Command, "Command class [$handler] must instanceof the " . Command::class);
331+
/** @var $cmd Command */
332+
$cmd = new $handler($this->input, $this->output);
333+
Assert::isTrue($cmd instanceof Command, "Command class [$handler] must instanceof the " . Command::class);
327334

328-
/** @var Command $object */
329-
$object::setName($info['cmdId']); // real command name.
330-
$object->setApp($this);
331-
$object->setCommandName($iptName);
332-
$result = $object->run($args);
335+
$cmd::setName($info['cmdId']); // real command name.
336+
$cmd->setApp($this);
337+
$cmd->setCommandName($iptName);
338+
$result = $cmd->run($args);
333339
}
334340

335341
return $result;

src/Command.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ protected function init(): void
5050
parent::init();
5151
}
5252

53+
/**
54+
* @return array
55+
*/
56+
public function getArguments(): array
57+
{
58+
return [];
59+
}
60+
5361
/**
5462
* @param FlagsParser $fs
5563
*/
@@ -139,7 +147,7 @@ public function getRealCName(): string
139147
/**
140148
* Get the group
141149
*
142-
* @return Controller
150+
* @return Controller|null
143151
*/
144152
public function getGroup(): ?Controller
145153
{

src/Component/Router.php

+21-12
Original file line numberDiff line numberDiff line change
@@ -194,16 +194,10 @@ public function addCommand(string $name, string|Closure|CommandInterface $handle
194194
$config['aliases'] = isset($config['aliases']) ? (array)$config['aliases'] : [];
195195

196196
if (is_string($handler)) {
197-
if (!class_exists($handler)) {
198-
Helper::throwInvalidArgument("The console command class [$handler] not exists!");
199-
}
200-
201-
if (!is_subclass_of($handler, Command::class)) {
202-
Helper::throwInvalidArgument('The console command class must is subclass of the: ' . Command::class);
203-
}
197+
Assert::isTrue(class_exists($handler), "The console command class '$handler' not exists!");
198+
Assert::isTrue(is_subclass_of($handler, Command::class), 'The command class must be subclass of the: ' . Command::class);
204199

205-
// not enable
206-
/** @var Command $handler */
200+
/** @var Command $handler not enable */
207201
if (!$handler::isEnabled()) {
208202
return $this;
209203
}
@@ -212,10 +206,11 @@ public function addCommand(string $name, string|Closure|CommandInterface $handle
212206
if ($aliases = $handler::aliases()) {
213207
$config['aliases'] = array_merge($config['aliases'], $aliases);
214208
}
215-
} elseif (!is_object($handler) || !method_exists($handler, '__invoke')) {
209+
} elseif (!is_object($handler) || !$this->isValidCmdObject($handler)) {
216210
Helper::throwInvalidArgument(
217-
'The console command handler must is an subclass of %s OR a Closure OR a object have method __invoke()',
218-
Command::class
211+
'The command handler must is an subclass of %s OR a Closure OR a sub-object of %s',
212+
Command::class,
213+
Command::class,
219214
);
220215
}
221216

@@ -235,6 +230,20 @@ public function addCommand(string $name, string|Closure|CommandInterface $handle
235230
return $this;
236231
}
237232

233+
/**
234+
* @param object $handler
235+
*
236+
* @return bool
237+
*/
238+
private function isValidCmdObject(object $handler): bool
239+
{
240+
if ($handler instanceof Command) {
241+
return true;
242+
}
243+
244+
return method_exists($handler, '__invoke');
245+
}
246+
238247
/**
239248
* @param array $commands
240249
*

src/Contract/CommandHandlerInterface.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace Inhere\Console\Contract;
1111

1212
use Inhere\Console\AbstractApplication;
13+
use Inhere\Console\Application;
1314

1415
/**
1516
* Interface CommandHandlerInterface
@@ -35,14 +36,14 @@ interface CommandHandlerInterface
3536
*
3637
* @param array $args
3738
*
38-
* @return int|mixed return int is exit code. other is command exec result.
39+
* @return mixed return int is exit code. other is command exec result.
3940
*/
4041
public function run(array $args): mixed;
4142

4243
/**
43-
* @return AbstractApplication|ApplicationInterface
44+
* @return Application
4445
*/
45-
public function getApp(): AbstractApplication;
46+
public function getApp(): Application;
4647

4748
/**
4849
* The input group name.

src/Decorate/AttachApplicationTrait.php

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
namespace Inhere\Console\Decorate;
1111

12-
use Inhere\Console\AbstractApplication;
1312
use Inhere\Console\Application;
1413
use Inhere\Console\Console;
1514
use Toolkit\Stdlib\OS;
@@ -38,9 +37,9 @@ trait AttachApplicationTrait
3837
private bool $attached = false;
3938

4039
/**
41-
* @return AbstractApplication
40+
* @return Application
4241
*/
43-
public function getApp(): AbstractApplication
42+
public function getApp(): Application
4443
{
4544
return $this->app;
4645
}

src/Decorate/InputOutputAwareTrait.php

+13
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,19 @@ public function setOutput(Output $output): void
122122
$this->output = $output;
123123
}
124124

125+
/**
126+
* @param Input $input
127+
* @param Output $output
128+
*
129+
* @return static
130+
*/
131+
public function setInputOutput(Input $input, Output $output): static
132+
{
133+
$this->input = $input;
134+
$this->output = $output;
135+
return $this;
136+
}
137+
125138
/**
126139
* @return FlagsParser
127140
*/

src/Handler/AbstractHandler.php

+15-7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use function cli_set_process_title;
3535
use function error_get_last;
3636
use function function_exists;
37+
use function vdump;
3738
use const PHP_OS;
3839

3940
/**
@@ -140,11 +141,11 @@ public static function aliases(): array
140141
/**
141142
* Command constructor.
142143
*
143-
* @param Input $input
144-
* @param Output $output
144+
* @param Input|null $input
145+
* @param Output|null $output
145146
*/
146-
// TODO public function __construct(Input $input = null, Output $output = null)
147-
public function __construct(Input $input, Output $output)
147+
// public function __construct(Input $input, Output $output)
148+
public function __construct(Input $input = null, Output $output = null)
148149
{
149150
$this->input = $input;
150151
$this->output = $output;
@@ -157,8 +158,7 @@ public function __construct(Input $input, Output $output)
157158

158159
protected function init(): void
159160
{
160-
$this->commentsVars = $this->annotationVars();
161-
161+
// $this->commentsVars = $this->annotationVars();
162162
$this->afterInit();
163163
$this->debugf('attach inner subcommands to "%s"', self::getName());
164164
$this->addCommands($this->commands());
@@ -240,6 +240,12 @@ protected function annotationVars(): array
240240
* running a command
241241
**************************************************************************/
242242

243+
protected function initForRun(): void
244+
{
245+
$this->commentsVars = $this->annotationVars();
246+
247+
}
248+
243249
/**
244250
* @param Input $input
245251
*/
@@ -299,6 +305,8 @@ public function run(array $args): mixed
299305
$name = self::getName();
300306

301307
try {
308+
$this->initForRun();
309+
302310
$this->initFlagsParser($this->input);
303311

304312
$this->log(Console::VERB_DEBUG, "begin run '$name' - parse options", ['args' => $args]);
@@ -335,7 +343,7 @@ protected function doRun(array $args): mixed
335343
if (isset($args[0])) {
336344
$first = $args[0];
337345
$rName = $this->resolveAlias($first);
338-
346+
// vdump($first, $rName);
339347
// TODO
340348
// if ($this->isSub($rName)) {
341349
// }

0 commit comments

Comments
 (0)