diff --git a/src/output/IMessenger.php b/src/output/IMessenger.php index f645f11..aeceae9 100644 --- a/src/output/IMessenger.php +++ b/src/output/IMessenger.php @@ -6,6 +6,7 @@ namespace nur\sery\output; */ interface IMessenger { const LEVEL_DEBUG = -1, LEVEL_NORMAL = 0, LEVEL_MAJOR = 1, LEVEL_NONE = 2; + const MIN_LEVEL = self::LEVEL_DEBUG, MAX_LEVEL = self::LEVEL_MAJOR; /** réinitialiser les paramètres de l'objet */ function resetParams(?array $params=null): void; diff --git a/src/output/TODO.md b/src/output/TODO.md index 2f03b55..059a71d 100644 --- a/src/output/TODO.md +++ b/src/output/TODO.md @@ -2,8 +2,9 @@ ## TOOD -* [ ] affichage des exceptions en message technique. - si pas de message, prendre le message de l'exception par défaut +* [ ] section(), title() et action() acceptent une fonction qui fait le travail + avec en premier argument l'instance de messenger, et qui termine l'objet + l'objet ensuite * [ ] possibilité de paramétrer le nom du fichier destination pour faire une rotation des logs * [ ] support quiet (uniquement major), very-quiet (aucun message n'est affiché) diff --git a/src/output/std/StdMessenger.php b/src/output/std/StdMessenger.php index 325e9b4..3bf925b 100644 --- a/src/output/std/StdMessenger.php +++ b/src/output/std/StdMessenger.php @@ -3,7 +3,10 @@ namespace nur\sery\output\std; use Exception; use nulib\cl; +use nulib\ExceptionShadow; +use nulib\UserException; use nur\sery\output\IMessenger; +use Throwable; class StdMessenger implements IMessenger { const INDENT = " "; @@ -22,7 +25,12 @@ class StdMessenger implements IMessenger { "none" => self::LEVEL_NONE, "silent" => self::LEVEL_NONE, ]; - protected static function verifix_level($level, int $max_level=self::LEVEL_MAJOR): int { + protected static function decr_level(int $level): int { + if (--$level < self::MIN_LEVEL) $level = self::MIN_LEVEL; + return $level; + } + + protected static function verifix_level($level, int $max_level=self::MAX_LEVEL): int { if (!in_array($level, self::VALID_LEVELS, true)) { $level = cl::get(self::LEVEL_MAP, $level, $level); } @@ -65,7 +73,7 @@ class StdMessenger implements IMessenger { "error" => ["debugE", "e", ""], "warn" => ["debugW", "w", ""], "note" => ["debugN", "i", ""], - "info" => ["debugI", "D", ""], + "info" => ["debug", "D", ""], "step" => ["*", ".", ""], "print" => [null, null, null], ], @@ -201,6 +209,18 @@ class StdMessenger implements IMessenger { return $level >= $this->minLevel; } + protected function getIndentLevel(bool $withActions=true): int { + $indentLevel = count($this->titles) - 1; + if ($indentLevel < 0) $indentLevel = 0; + if ($withActions) { + foreach ($this->actions as $action) { + if ($action["level"] < $this->minLevel) continue; + $indentLevel++; + } + } + return $indentLevel; + } + protected function _printTitle(?string $linePrefix, int $level, string $type, $content, int $indentLevel, StdOutput $out): void { @@ -319,8 +339,9 @@ class StdMessenger implements IMessenger { } } - protected function _printGeneric(int $level, string $type, $content, int $indentLevel, StdOutput $out): void { - $linePrefix = $this->getLinePrefix(); + protected function _printGeneric(?string $linePrefix, int $level, + string $type, $content, + int $indentLevel, StdOutput $out): void { $prefixes = self::GENERIC_PREFIXES[$level][$type]; if ($out->isColor()) { $prefix = $prefixes[1]; @@ -350,6 +371,53 @@ class StdMessenger implements IMessenger { } } + protected function _printGenericOrException(?int $level, string $type, $content, int $indentLevel, StdOutput $out): void { + $linePrefix = $this->getLinePrefix(); + # si $content contient des exceptions, les afficher avec un level moindre + $exceptions = null; + if (is_array($content)) { + $valueContent = null; + foreach ($content as $value) { + if ($value instanceof Throwable || $value instanceof ExceptionShadow) { + $exceptions[] = $value; + } else { + $valueContent[] = $value; + } + } + $content = $valueContent; + } elseif ($content instanceof Throwable || $content instanceof ExceptionShadow) { + $exceptions[] = $content; + $content = null; + } + + $printActions = true; + $showContent = $this->checkLevel($level); + if ($content !== null && $showContent) { + $this->printActions(); $printActions = false; + $this->_printGeneric($linePrefix, $level, $type, $content, $indentLevel, $out); + } + if ($exceptions !== null) { + $level1 = self::decr_level($level); + $showTraceback = $this->checkLevel($level1); + foreach ($exceptions as $exception) { + # tout d'abord userMessage + $userMessage = UserException::get_user_message($exception); + if ($userMessage !== null && $showContent) { + if ($printActions) { $this->printActions(); $printActions = false; } + $this->_printGeneric($linePrefix, $level, $type, $userMessage, $indentLevel, $out); + } + # puis summary et traceback + if ($showTraceback) { + if ($printActions) { $this->printActions(); $printActions = false; } + $summary = UserException::get_summary($exception); + $traceback = UserException::get_traceback($exception); + $this->_printGeneric($linePrefix, $level1, $type, $summary, $indentLevel, $out); + $this->_printGeneric($linePrefix, $level1, $type, $traceback, $indentLevel, $out); + } + } + } + } + /** @var bool est-on dans une section? */ protected $inSection; @@ -370,7 +438,7 @@ class StdMessenger implements IMessenger { protected function printSection() { $section =& $this->section; - if ($section["print_content"]) { + if ($section !== null && $section["print_content"]) { $this->_printTitle( $section["line_prefix"], $section["level"], "section", $section["content"], @@ -384,18 +452,6 @@ class StdMessenger implements IMessenger { $this->section = null; } - protected function getIndentLevel(bool $withActions=true): int { - $indentLevel = count($this->titles) - 1; - if ($indentLevel < 0) $indentLevel = 0; - if ($withActions) { - foreach ($this->actions as $action) { - if ($action["level"] < $this->minLevel) continue; - $indentLevel++; - } - } - return $indentLevel; - } - /** @var array */ protected $titles; @@ -440,7 +496,10 @@ class StdMessenger implements IMessenger { } if ($title["print_descs"]) { foreach ($title["descs"] as $desc) { - $this->_printGeneric($desc["level"], "desc", $desc["content"], $indentLevel, $err); + $this->_printGeneric( + $desc["line_prefix"], $desc["level"], + "desc", $desc["content"], + $indentLevel, $err); } $title["descs"] = []; $title["print_descs"] = false; @@ -511,10 +570,7 @@ class StdMessenger implements IMessenger { } function step($content, ?int $level=null): void { - if (!$this->checkLevel($level)) return; - if (!$this->actions) $this->action(null); - $this->printActions(); - $this->_printGeneric($level, "step", $content, $this->getIndentLevel(), $this->err); + $this->_printGenericOrException($level, "step", $content, $this->getIndentLevel(), $this->err); } function asuccess($content=null): void { @@ -552,33 +608,23 @@ class StdMessenger implements IMessenger { } function print($content, ?int $level=null): void { - if (!$this->checkLevel($level)) return; - $this->printActions(); - $this->_printGeneric($level, "print", $content, $this->getIndentLevel(), $this->out); + $this->_printGenericOrException($level, "print", $content, $this->getIndentLevel(), $this->out); } function info($content, ?int $level=null): void { - if (!$this->checkLevel($level)) return; - $this->printActions(); - $this->_printGeneric($level, "info", $content, $this->getIndentLevel(), $this->err); + $this->_printGenericOrException($level, "info", $content, $this->getIndentLevel(), $this->err); } function note($content, ?int $level=null): void { - if (!$this->checkLevel($level)) return; - $this->printActions(); - $this->_printGeneric($level, "note", $content, $this->getIndentLevel(), $this->err); + $this->_printGenericOrException($level, "note", $content, $this->getIndentLevel(), $this->err); } function warn($content, ?int $level=null): void { - if (!$this->checkLevel($level)) return; - $this->printActions(); - $this->_printGeneric($level, "warn", $content, $this->getIndentLevel(), $this->err); + $this->_printGenericOrException($level, "warn", $content, $this->getIndentLevel(), $this->err); } function error($content, ?int $level=null): void { - if (!$this->checkLevel($level)) return; - $this->printActions(); - $this->_printGeneric($level, "error", $content, $this->getIndentLevel(), $this->err); + $this->_printGenericOrException($level, "error", $content, $this->getIndentLevel(), $this->err); } function end(bool $all=false): void { diff --git a/tbin/test-console.php b/tbin/test-console.php index d364f57..248f4b2 100755 --- a/tbin/test-console.php +++ b/tbin/test-console.php @@ -2,6 +2,7 @@ action("multi-line\naction"); $c->step("multi-line\nstep"); $c->adone("multi-line\ndone"); $c->end(true); + +$exception = new Exception("message"); +$userException1 = new UserException("userMessage"); +$userException2 = new UserException("userMessage", "techMessage"); +$c->section("Exceptions"); +$c->title("avec message"); +$c->info(["exception", $exception]); +$c->info(["userException1", $userException1]); +$c->info(["userException2", $userException2]); +$c->end(); + +$c->title("sans message"); +$c->info($exception); +$c->info($userException1); +$c->info($userException2); +$c->end();