Skip to content

Commit 000360a

Browse files
committed
feat: support use GROUP COMMAND for run an group command
1 parent 9237760 commit 000360a

10 files changed

+164
-85
lines changed

src/AbstractApplication.php

+18-20
Original file line numberDiff line numberDiff line change
@@ -64,27 +64,27 @@ abstract class AbstractApplication implements ApplicationInterface
6464
];
6565

6666
/** @var array Application runtime stats */
67-
private $stats = [
67+
protected $stats = [
6868
'startTime' => 0,
6969
'endTime' => 0,
7070
'startMemory' => 0,
7171
'endMemory' => 0,
7272
];
7373

7474
/** @var array Application config data */
75-
private $config = [
76-
'name' => 'My Console Application',
77-
'description' => 'This is my console application',
78-
'debug' => Console::VERB_ERROR,
79-
'profile' => false,
80-
'version' => '0.5.1',
81-
'publishAt' => '2017.03.24',
82-
'updateAt' => '2019.01.01',
83-
'rootPath' => '',
84-
'strictMode' => false,
85-
'hideRootPath' => true,
75+
protected $config = [
76+
'name' => 'My Console Application',
77+
'description' => 'This is my console application',
78+
'debug' => Console::VERB_ERROR,
79+
'profile' => false,
80+
'version' => '0.5.1',
81+
'publishAt' => '2017.03.24',
82+
'updateAt' => '2019.01.01',
83+
'rootPath' => '',
84+
'strictMode' => false,
85+
'hideRootPath' => true,
8686
// global options
87-
'no-interactive' => true,
87+
'no-interactive' => true,
8888

8989
// 'timeZone' => 'Asia/Shanghai',
9090
// 'env' => 'prod', // dev test prod
@@ -102,21 +102,19 @@ abstract class AbstractApplication implements ApplicationInterface
102102
/**
103103
* @var Router
104104
*/
105-
private $router;
105+
protected $router;
106106

107107
/**
108108
* @var ErrorHandlerInterface Can custom error handler
109109
*/
110-
private $errorHandler;
110+
protected $errorHandler;
111111

112112
/**
113113
* Class constructor.
114114
*
115-
* @param array $config
116-
* @param Input $input
117-
* @param Output $output
118-
*
119-
* @throws InvalidArgumentException
115+
* @param array $config
116+
* @param Input|null $input
117+
* @param Output|null $output
120118
*/
121119
public function __construct(array $config = [], Input $input = null, Output $output = null)
122120
{

src/AbstractHandler.php

+10-8
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
use function is_array;
4040
use function is_int;
4141
use function is_string;
42+
use function json_encode;
4243
use function preg_replace;
43-
use function setproctitle;
4444
use function sprintf;
4545
use function strpos;
4646
use function strtr;
@@ -553,6 +553,8 @@ protected function showHelp(): bool
553553
return false;
554554
}
555555

556+
$this->log(Console::VERB_DEBUG, 'display help by definition');
557+
556558
// if has InputDefinition object. (The comment of the command will not be parsed and used at this time.)
557559
$help = $definition->getSynopsis();
558560
// parse example
@@ -613,11 +615,6 @@ protected function showHelpByMethodAnnotations(string $method, string $action =
613615
$ref = new ReflectionClass($this);
614616
$name = $this->input->getCommand();
615617

616-
$this->log(Console::VERB_CRAZY, "display help info for the method=$method", [
617-
'class' => static::class,
618-
'action' => $action,
619-
]);
620-
621618
if (!$ref->hasMethod($method)) {
622619
$this->write("The command [<info>$name</info>] don't exist in the group: " . static::getName());
623620
return 0;
@@ -639,6 +636,11 @@ protected function showHelpByMethodAnnotations(string $method, string $action =
639636
$help['Command:'] = sprintf('%s(alias: <info>%s</info>)', $realName, implode(',', $aliases));
640637
}
641638

639+
$path = $this->input->getBinName() . ' ' . $name;
640+
if ($action) {
641+
$path .= " $action";
642+
}
643+
642644
// is an command object
643645
$isCommand = $ref->isSubclassOf(CommandInterface::class);
644646
foreach (array_keys(self::$annotationTags) as $tag) {
@@ -650,7 +652,7 @@ protected function showHelpByMethodAnnotations(string $method, string $action =
650652
}
651653

652654
if ($tag === 'usage') {
653-
$help['Usage:'] = $this->commentsVars['binWithCmd'] . ' [--options ...] [arguments ...]';
655+
$help['Usage:'] = "$path [--options ...] [arguments ...]";
654656
}
655657

656658
continue;
@@ -825,7 +827,7 @@ public function log(int $level, string $message, array $extra = []): void
825827
return;
826828
}
827829

828-
Console::log($message, $extra, $level);
830+
Console::log($level, $message, $extra);
829831
}
830832

831833
/**

src/Application.php

+13-13
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
use function is_object;
2222
use function is_string;
2323
use function method_exists;
24-
use function sprintf;
2524
use function strlen;
2625
use function strpos;
2726
use function substr;
@@ -62,17 +61,18 @@ public function controller(string $name, $class = null, $option = null)
6261
];
6362
}
6463

65-
$this->getRouter()->addGroup($name, $class, (array)$option);
64+
$this->logf(Console::VERB_CRAZY, 'load group controller: %s', $name);
65+
$this->router->addGroup($name, $class, (array)$option);
6666

6767
return $this;
6868
}
6969

7070
/**
7171
* Add group/controller
7272
*
73-
* @param string $name
74-
* @param string|ControllerInterface $class The controller class
75-
* @param null|array|string $option
73+
* @param string $name
74+
* @param string|ControllerInterface|null $class The controller class
75+
* @param null|array|string $option
7676
*
7777
* @return Application|Contract\ApplicationInterface
7878
* @see controller()
@@ -83,9 +83,9 @@ public function addGroup(string $name, $class = null, $option = null)
8383
}
8484

8585
/**
86-
* @param string $name
87-
* @param string|ControllerInterface $class The controller class
88-
* @param null|array|string $option
86+
* @param string $name
87+
* @param string|ControllerInterface|null $class The controller class
88+
* @param null|array|string $option
8989
*
9090
* @return Application|Contract\ApplicationInterface
9191
* @see controller()
@@ -123,7 +123,7 @@ public function setControllers(array $controllers): void
123123
*/
124124
public function addControllers(array $controllers): void
125125
{
126-
$this->getRouter()->addControllers($controllers);
126+
$this->router->addControllers($controllers);
127127
}
128128

129129
/**
@@ -137,7 +137,7 @@ public function command(string $name, $handler = null, $option = null)
137137
];
138138
}
139139

140-
$this->getRouter()->addCommand($name, $handler, (array)$option);
140+
$this->router->addCommand($name, $handler, (array)$option);
141141

142142
return $this;
143143
}
@@ -164,7 +164,7 @@ public function addCommand(string $name, $handler = null, $option = null): self
164164
*/
165165
public function addCommands(array $commands): void
166166
{
167-
$this->getRouter()->addCommands($commands);
167+
$this->router->addCommands($commands);
168168
}
169169

170170
/**
@@ -262,7 +262,7 @@ public function dispatch(string $name, bool $detachedRun = false)
262262
$this->logf(Console::VERB_DEBUG, 'begin dispatch command: %s', $name);
263263

264264
// match handler by input name
265-
$info = $this->getRouter()->match($name);
265+
$info = $this->router->match($name);
266266

267267
// command not found
268268
if (!$info) {
@@ -273,7 +273,7 @@ public function dispatch(string $name, bool $detachedRun = false)
273273

274274
$this->output->error("The command '{$name}' is not exists!");
275275

276-
$commands = $this->getRouter()->getAllNames();
276+
$commands = $this->router->getAllNames();
277277

278278
// find similar command names by similar_text()
279279
if ($similar = Helper::findSimilar($name, $commands)) {

src/Command.php

+12
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@
2828
*/
2929
abstract class Command extends AbstractHandler implements CommandInterface
3030
{
31+
/**
32+
* @var Command
33+
*/
34+
protected $parent;
35+
36+
/**
37+
* @var Command[]
38+
*/
39+
protected $commands = [];
40+
3141
/*
3242
* Do execute command
3343
*/
@@ -63,6 +73,8 @@ protected function showHelp(): bool
6373
$execMethod = 'execute';
6474
$cmdAliases = static::aliases();
6575

76+
$this->logf(Console::VERB_CRAZY, "display help info for the command: %s", static::$name);
77+
6678
return $this->showHelpByMethodAnnotations($execMethod, '', $cmdAliases) !== 0;
6779
}
6880
}

src/Console.php

+40-7
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
use Toolkit\Cli\Cli;
88
use Toolkit\Cli\ColorTag;
99
use function date;
10+
use function debug_backtrace;
1011
use function implode;
1112
use function is_numeric;
1213
use function json_encode;
1314
use function sprintf;
1415
use function strpos;
1516
use function trim;
17+
use const DEBUG_BACKTRACE_IGNORE_ARGS;
1618
use const JSON_PRETTY_PRINT;
1719
use const JSON_UNESCAPED_SLASHES;
1820
use const PHP_EOL;
@@ -92,22 +94,29 @@ public static function newApp(
9294
return new Application($config, $input, $output);
9395
}
9496

97+
/**
98+
* @var int
99+
*/
100+
public static $traceIndex = 1;
101+
95102
/**
96103
* @param int $level
97104
* @param string $format
98105
* @param mixed ...$args
99106
*/
100107
public static function logf(int $level, string $format, ...$args): void
101108
{
109+
$datetime = date('Y/m/d H:i:s');
102110
$levelName = self::LEVEL_NAMES[$level] ?? 'INFO';
103111
$colorName = self::LEVEL2TAG[$level] ?? 'info';
104112

105-
$taggedName = ColorTag::add($levelName, $colorName);
113+
$message = strpos($format, '%') > 0 ? sprintf($format, ...$args) : $format;
114+
$tagName = ColorTag::add($levelName, $colorName);
106115

107-
$datetime = date('Y/m/d H:i:s');
108-
$message = strpos($format, '%') > 0 ? sprintf($format, ...$args) : $format;
116+
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, self::$traceIndex + 2);
117+
$position = self::formatBacktrace($backtrace, self::$traceIndex);
109118

110-
self::writef('%s [%s] %s', $datetime, $taggedName, $message);
119+
self::writef('%s [%s] [%s] %s', $datetime, $tagName, $position, $message);
111120
}
112121

113122
/**
@@ -124,13 +133,14 @@ public static function logf(int $level, string $format, ...$args): void
124133
* 'coId' => 12,
125134
* ]
126135
*/
127-
public static function log(string $msg, array $data = [], int $level = self::VERB_DEBUG, array $opts = []): void
136+
public static function log(int $level, string $msg, array $data = [], array $opts = []): void
128137
{
129138
$levelName = self::LEVEL_NAMES[$level] ?? 'INFO';
130139
$colorName = self::LEVEL2TAG[$level] ?? 'info';
131140
$taggedName = ColorTag::add($levelName, $colorName);
132141

133142
$userOpts = [];
143+
$datetime = date('Y/m/d H:i:s');
134144
foreach ($opts as $n => $v) {
135145
if (is_numeric($n) || strpos($n, '_') === 0) {
136146
$userOpts[] = "[$v]";
@@ -140,8 +150,31 @@ public static function log(string $msg, array $data = [], int $level = self::VER
140150
}
141151

142152
$optString = $userOpts ? ' ' . implode(' ', $userOpts) : '';
143-
$dataString = $data ? PHP_EOL . json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) : '';
153+
$dataString = $data ? json_encode($data, JSON_UNESCAPED_SLASHES) : '';
154+
155+
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, self::$traceIndex + 2);
156+
$position = self::formatBacktrace($backtrace, self::$traceIndex);
157+
158+
self::writef('%s [%s] [%s]%s %s %s', $datetime, $taggedName, $position, $optString, trim($msg), $dataString);
159+
}
160+
161+
/**
162+
* @param array $traces
163+
* @param int $index
164+
*
165+
* @return string
166+
*/
167+
private static function formatBacktrace(array $traces, int $index): string
168+
{
169+
$position = 'unknown';
170+
171+
if (isset($traces[$index+1])) {
172+
$tInfo = $traces[$index];
173+
$prev = $traces[$index+1];
174+
175+
$position = sprintf('%s.%s:%d', $prev['class'], $prev['function'] ?? 'UNKNOWN', $tInfo['line']);
176+
}
144177

145-
self::writef('%s [%s]%s %s %s', date('Y/m/d H:i:s'), $taggedName, $optString, trim($msg), $dataString);
178+
return ColorTag::add($position, 'green');
146179
}
147180
}

0 commit comments

Comments
 (0)