Skip to content

Commit b2e876a

Browse files
committed
new: add error handle
new: add running sub-command support update: modify error display update: some modify for phar build
1 parent 226499b commit b2e876a

22 files changed

+213
-92
lines changed

examples/Commands/TestCommand.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
namespace Inhere\Console\Examples\Commands;
1010

1111
use Inhere\Console\Command;
12+
use Inhere\Console\IO\Output;
1213

1314
/**
1415
* Class Test
1516
* @package Inhere\Console\Examples\Commands
1617
*/
1718
class TestCommand extends Command
1819
{
20+
protected static $name = 'test';
1921
protected static $description = 'this is a test independent command';
2022

2123
/**
@@ -28,7 +30,7 @@ class TestCommand extends Command
2830
* --long,-s option description 1
2931
* --opt option description 2
3032
* @param $input
31-
* @param $output
33+
* @param Output $output
3234
*/
3335
public function execute($input, $output)
3436
{

examples/Controllers/HomeController.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class HomeController extends Controller
2626
/**
2727
* @return array
2828
*/
29-
protected static function commandAliases()
29+
protected static function commandAliases(): array
3030
{
3131
return [
3232
// now, 'home:i' is equals to 'home:index'
@@ -98,6 +98,32 @@ public function defArgCommand()
9898
$this->output->dump($this->input->getArgs(), $this->input->getOpts(), $this->input->getBoolOpt('y'));
9999
}
100100

101+
/**
102+
* a command for test throw exception
103+
*/
104+
public function exCommand()
105+
{
106+
throw new \RuntimeException('oo, this is a runtime exception!');
107+
}
108+
109+
/**
110+
* a command for test trigger error
111+
*/
112+
public function errorCommand()
113+
{
114+
trigger_error('oo, this is a runtime error!', E_USER_ERROR);
115+
}
116+
117+
/**
118+
* will run other command in the command.
119+
*/
120+
public function subRunCommand()
121+
{
122+
$this->writeln('hello this is: ' . __METHOD__);
123+
124+
$this->getApp()->subRun('test', $this->input, $this->output);
125+
}
126+
101127
/**
102128
* dump current env information
103129
*/

examples/Controllers/ProcessController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class ProcessController extends Controller
2222

2323
protected static $description = 'Some simple process to create and use examples';
2424

25-
protected static function commandAliases()
25+
protected static function commandAliases(): array
2626
{
2727
return [
2828
'cpr' => 'childProcess',

examples/app

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
define('BASE_PATH', dirname(__DIR__));
1010

11-
require dirname(__DIR__) . '/tests/boot.php';
11+
require dirname(__DIR__) . '/test/boot.php';
1212

1313
// create app instance
1414
$app = new \Inhere\Console\Application([

examples/home

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
#!/usr/env/php
22
<?php
3+
/**
4+
* only run a controller.
5+
*/
36

47
use Inhere\Console\Examples\Controllers\HomeController;
58

69
define('BASE_PATH', dirname(__DIR__));
710

8-
require dirname(__DIR__) . '/tests/boot.php';
11+
require dirname(__DIR__) . '/test/boot.php';
912

1013
$in = new \Inhere\Console\IO\Input();
1114
$ctrl = new HomeController($in, new \Inhere\Console\IO\Output());
1215
$ctrl->setStandAlone();
1316

14-
exit($ctrl->run($in->getCommand()));
17+
try {
18+
exit($ctrl->run($in->getCommand()));
19+
} catch (ReflectionException $e) {
20+
// ...
21+
}
1522

1623
// can also:
1724

examples/liteApp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
define('BASE_PATH', dirname(__DIR__));
55

6-
require dirname(__DIR__) . '/tests/boot.php';
6+
require dirname(__DIR__) . '/test/boot.php';
77

88
// create app instance
99
$app = new \Inhere\Console\LiteApp;

phar.build.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ $compiler
1414
->setShebang(true)
1515
->addExclude([
1616
'demo',
17-
'tests',
17+
'test',
1818
'tmp',
1919
])
2020
->addFile([
2121
'LICENSE',
2222
'composer.json',
2323
'README.md',
24-
'tests/boot.php',
24+
'test/boot.php',
2525
])
2626
->setCliIndex('examples/app')
2727
// ->setWebIndex('web/index.php')

phpunit.xml.dist

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<phpunit backupGlobals="false"
44
backupStaticAttributes="false"
5-
bootstrap="./tests/boot.php"
5+
bootstrap="test/boot.php"
66
colors="false"
77
convertErrorsToExceptions="true"
88
convertNoticesToExceptions="true"
@@ -12,13 +12,13 @@
1212
>
1313
<testsuites>
1414
<testsuite name="Php Console Test Suite">
15-
<directory>./tests/</directory>
15+
<directory>test</directory>
1616
</testsuite>
1717
</testsuites>
1818

1919
<filter>
2020
<whitelist>
21-
<directory suffix=".php">./src</directory>
21+
<directory suffix=".php">src</directory>
2222
</whitelist>
2323
</filter>
2424
</phpunit>

src/Application.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function controller(string $name, string $class = null, $option = null)
6262
if ($aliases = $class::aliases()) {
6363
$option['aliases'] = isset($option['aliases']) ? array_merge($option['aliases'], $aliases) : $aliases;
6464
}
65-
65+
6666
$this->controllers[$name] = $class;
6767

6868
if (!$option) {
@@ -299,7 +299,7 @@ protected function dispatch(string $name)
299299
}
300300

301301
// command not found
302-
if (true !== self::fire(self::ON_NOT_FOUND, [$this])) {
302+
if (true !== $this->fire(self::ON_NOT_FOUND, [$this])) {
303303
$this->output->liteError("The command '{$name}' is not exists in the console application!");
304304

305305
$commands = array_merge($this->getControllerNames(), $this->getCommandNames());
@@ -361,8 +361,8 @@ public function runCommand($name, $believable = false)
361361
}
362362

363363
/**
364-
* @param string $name Controller name
365-
* @param string $action Command
364+
* @param string $name group name
365+
* @param string $action Command method, no suffix
366366
* @param bool $believable The `$name` is believable
367367
* @param bool $standAlone
368368
* @return mixed

src/Base/AbstractApplication.php

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
namespace Inhere\Console\Base;
1010

1111
use Inhere\Console\IO\Input;
12+
use Inhere\Console\IO\InputInterface;
1213
use Inhere\Console\IO\Output;
1314
use Inhere\Console\Components\Style\Highlighter;
15+
use Inhere\Console\IO\OutputInterface;
1416
use Inhere\Console\Traits\InputOutputAwareTrait;
1517
use Inhere\Console\Traits\SimpleEventTrait;
1618
use Inhere\Console\Components\Style\Style;
@@ -111,7 +113,8 @@ protected function init()
111113
];
112114

113115
$this->commandName = $this->input->getCommand();
114-
set_exception_handler([$this, 'handleException']);
116+
117+
$this->registerErrorHandle();
115118
}
116119

117120
/**
@@ -214,6 +217,21 @@ public function stop($code = 0)
214217
exit((int)$code);
215218
}
216219

220+
/**
221+
* @param string $command
222+
* @param InputInterface $input
223+
* @param OutputInterface $output
224+
* @return int|mixed
225+
*/
226+
public function subRun(string $command, InputInterface $input, OutputInterface $output)
227+
{
228+
$app = clone $this;
229+
$app->setInput($input);
230+
$app->setOutput($output);
231+
232+
return $app->dispatch($command);
233+
}
234+
217235
/**********************************************************
218236
* helper method for the application
219237
**********************************************************/
@@ -232,43 +250,67 @@ protected function runtimeCheck()
232250
}
233251
}
234252

253+
/**
254+
* register error handle
255+
*/
256+
protected function registerErrorHandle()
257+
{
258+
set_error_handler([$this, 'handleError']);
259+
set_exception_handler([$this, 'handleException']);
260+
261+
register_shutdown_function(function () {
262+
if ($e = error_get_last()) {
263+
$this->handleError($e['type'], $e['message'], $e['file'], $e['line']);
264+
}
265+
});
266+
}
267+
268+
/**
269+
* 运行异常处理
270+
* @param int $num
271+
* @param string $str
272+
* @param string $file
273+
* @param int $line
274+
*/
275+
public function handleError(int $num, string $str, string $file, int $line)
276+
{
277+
$this->handleException(new \ErrorException($str, 0, $num, $file, $line));
278+
$this->stop(-1);
279+
}
280+
235281
/**
236282
* 运行异常处理
237283
* @param \Exception|\Throwable $e
238284
*/
239285
public function handleException($e)
240286
{
241287
$class = \get_class($e);
242-
$type = $e instanceof \Error ? 'Error' : 'Exception';
243-
$title = ":( OO ... An $type Occurred!";
244288
$this->logError($e);
245289

246290
// open debug, throw exception
247291
if ($this->isDebug()) {
248292
$tpl = <<<ERR
249-
<danger>$title</danger>
293+
\n<error> Error </error> <mga>%s</mga>
250294
251-
Message <magenta>%s</magenta>
252-
At File <cyan>%s</cyan> line <cyan>%d</cyan>
295+
At File <cyan>%s</cyan> line <bold>%d</bold>
253296
Exception $class
254-
Catch by %s()\n
255-
Code Trace:\n%s\n
297+
<comment>Code View:</comment>\n\n%s
298+
<comment>Code Trace:</comment>\n\n%s\n
256299
ERR;
300+
$line = $e->getLine();
301+
$file = $e->getFile();
302+
$snippet = Highlighter::create()->highlightSnippet(file_get_contents($file), $line, 3, 3);
257303
$message = sprintf(
258304
$tpl,
259305
// $e->getCode(),
260306
$e->getMessage(),
261-
$file = $e->getFile(),
262-
$line = $e->getLine(),
263-
__METHOD__,
264-
$e->getTraceAsString()
307+
$file,
308+
$line,
309+
// __METHOD__,
310+
$snippet,
311+
str_replace('):', "):\n -", $e->getTraceAsString())
265312
);
266313

267-
$source = file_get_contents($file);
268-
$hl = Highlighter::create();
269-
$snippet = $hl->highlightSnippet($source, $line, 3, 3);
270-
$message .= "\nCode View:\n$snippet";
271-
272314
if ($this->meta['hideRootPath'] && ($rootPath = $this->meta['rootPath'])) {
273315
$message = str_replace($rootPath, '{ROOT}', $message);
274316
}
@@ -539,6 +581,19 @@ protected function getRealCommandName(string $name): string
539581
return $this->commandAliases[$name] ?? $name;
540582
}
541583

584+
/**
585+
* @param string $name
586+
* @return mixed|null
587+
*/
588+
public function findCommand(string $name)
589+
{
590+
if (isset($this->commands[$name])) {
591+
return $this->commands[$name];
592+
}
593+
594+
return $this->controllers[$name] ?? null;
595+
}
596+
542597
/**********************************************************
543598
* getter/setter methods
544599
**********************************************************/

0 commit comments

Comments
 (0)