diff --git a/LICENSE b/LICENSE index d449d3e..2d836fb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) +Copyright (c) 2019 Marvin Schreurs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 94ddc85..a53ed0d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ -# laravel-output-writer +# Console Writer -Console output interface for laravel. \ No newline at end of file +Console input/output writer for Symfony. Features a dedicated class for console +interactivity based on Symfony's Console component, allowing +easier styling through proper class inheritance while providing a simple and +non-obstructive interface for use in your console commands. \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..3603829 --- /dev/null +++ b/composer.json @@ -0,0 +1,31 @@ +{ + "name": "danmaku/console-writer", + "type": "library", + "description": "Easily adaptable console input/output writer for Symfony.", + "authors": [ + { + "name": "Marvin Schreurs", + "email": "fristi@danmaku.moe", + "homepage": "https://fristi.danmaku.moe", + "role": "Developer" + } + ], + "support": { + "email": "fristi@danmaku.moe" + }, + "keywords": [ + "console", + "symfony" + ], + "license": "MIT", + "minimum-stability": "dev", + "require": { + "php": ">=7.2.0", + "symfony/console": "^4.2" + }, + "autoload": { + "psr-4": { + "Danmaku\\Console\\": "src/Console" + } + } +} diff --git a/herrfristi/laravel-output-writer/composer.json b/herrfristi/laravel-output-writer/composer.json deleted file mode 100644 index e69de29..0000000 diff --git a/herrfristi/laravel-output-writer/src/Console/Command/BaseCommand.php b/herrfristi/laravel-output-writer/src/Console/Command/BaseCommand.php deleted file mode 100644 index 77d0ee9..0000000 --- a/herrfristi/laravel-output-writer/src/Console/Command/BaseCommand.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ - -namespace Arc\Base\Console\Command; - - -use Arc\Base\Console\Output\BaseOutputWriter; -use Arc\Base\Console\Output\OutputWriterInterface; -use Illuminate\Console\Command; -use Illuminate\Console\OutputStyle; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Class BaseCommand - * - * @package Arc\Base\Console\Command - * @author Marvin Schreurs - */ -abstract class BaseCommand extends Command -{ - /** - * OutputWriterInterface instance. - * - * @var OutputWriterInterface $writer - */ - protected $writer; - - /** - * @inheritDoc - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $this->setOutputWriter($input, $output); - return parent::execute($input, $output); - } - - /** - * Set the output writer to use with this command. - */ - protected function setOutputWriter(InputInterface $input, OutputInterface $output): void - { - $this->writer = new BaseOutputWriter($input, $output); - } -} \ No newline at end of file diff --git a/herrfristi/laravel-output-writer/src/Console/Question/BaseChoiceQuestion.php b/herrfristi/laravel-output-writer/src/Console/Question/BaseChoiceQuestion.php deleted file mode 100644 index 09cdf24..0000000 --- a/herrfristi/laravel-output-writer/src/Console/Question/BaseChoiceQuestion.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ - -namespace Arc\Base\Console\Question; - - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Question\ChoiceQuestion; - -/** - * Class BaseChoiceQuestion - * - * @package Arc\Base\Console\Question - * @author Marvin Schreurs - */ -class BaseChoiceQuestion extends ChoiceQuestion -{ - protected function isAssoc($array) - { - return true; - } -} \ No newline at end of file diff --git a/herrfristi/laravel-output-writer/src/Console/Question/BaseConfirmationQuestion.php b/herrfristi/laravel-output-writer/src/Console/Question/BaseConfirmationQuestion.php deleted file mode 100644 index bf5a6a6..0000000 --- a/herrfristi/laravel-output-writer/src/Console/Question/BaseConfirmationQuestion.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ - -namespace Arc\Base\Console\Question; - - -use Symfony\Component\Console\Question\ConfirmationQuestion; - -/** - * Class BaseConfirmationQuestion - * - * @package Arc\Base\Console\Question - * @author Marvin Schreurs - */ -class BaseConfirmationQuestion extends ConfirmationQuestion -{ - protected function isAssoc($array) - { - return true; - } -} \ No newline at end of file diff --git a/herrfristi/laravel-output-writer/src/Console/Question/BaseQuestion.php b/herrfristi/laravel-output-writer/src/Console/Question/BaseQuestion.php deleted file mode 100644 index 26fc542..0000000 --- a/herrfristi/laravel-output-writer/src/Console/Question/BaseQuestion.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ - -namespace Arc\Base\Console\Question; - - -use Symfony\Component\Console\Question\Question; - -/** - * Class BaseQuestion - * - * @package Arc\Base\Console\Question - * @author Marvin Schreurs - */ -class BaseQuestion extends Question -{ - protected function isAssoc($array) - { - return true; - } -} \ No newline at end of file diff --git a/herrfristi/laravel-output-writer/src/Console/Helper/UnfuckedQuestionHelper.php b/src/Console/Helper/InheritableQuestionHelper.php similarity index 97% rename from herrfristi/laravel-output-writer/src/Console/Helper/UnfuckedQuestionHelper.php rename to src/Console/Helper/InheritableQuestionHelper.php index 1c7c352..9cb4a87 100644 --- a/herrfristi/laravel-output-writer/src/Console/Helper/UnfuckedQuestionHelper.php +++ b/src/Console/Helper/InheritableQuestionHelper.php @@ -1,16 +1,16 @@ + * @package Danmaku\Console\Helper + * @author Marvin Schreurs */ -namespace Arc\Base\Console\Helper; +namespace Danmaku\Console\Helper; use Symfony\Component\Console\Exception\RuntimeException; @@ -25,12 +25,12 @@ use Symfony\Component\Console\Question\ChoiceQuestion; use Symfony\Component\Console\Question\Question; /** - * Class UnfuckedQuestionHelper + * Class InheritableQuestionHelper * - * @package Arc\Base\Console\Helper - * @author Marvin Schreurs + * @package Danmaku\Console\Helper + * @author Marvin Schreurs */ -class UnfuckedQuestionHelper extends \Symfony\Component\Console\Helper\QuestionHelper +class InheritableQuestionHelper extends \Symfony\Component\Console\Helper\QuestionHelper { protected $inputStream; protected static $shell; diff --git a/herrfristi/laravel-output-writer/src/Console/Helper/QuestionHelper.php b/src/Console/Helper/QuestionHelper.php similarity index 94% rename from herrfristi/laravel-output-writer/src/Console/Helper/QuestionHelper.php rename to src/Console/Helper/QuestionHelper.php index 1aae1fb..d94b5d1 100644 --- a/herrfristi/laravel-output-writer/src/Console/Helper/QuestionHelper.php +++ b/src/Console/Helper/QuestionHelper.php @@ -6,11 +6,11 @@ * * PHP version 7.2 * - * @package Arc\Base\Console\Helper - * @author Marvin Schreurs + * @package Danmaku\Console\Helper + * @author Marvin Schreurs */ -namespace Arc\Base\Console\Helper; +namespace Danmaku\Console\Helper; use Symfony\Component\Console\Exception\RuntimeException; @@ -28,10 +28,10 @@ use Symfony\Component\Console\Style\SymfonyStyle; /** * Class QuestionHelper * - * @package Arc\Base\Console\Helper - * @author Marvin Schreurs + * @package Danmaku\Console\Helper + * @author Marvin Schreurs */ -class QuestionHelper extends UnfuckedQuestionHelper +class QuestionHelper extends InheritableQuestionHelper { public function ask(InputInterface $input, OutputInterface $output, Question $question) { diff --git a/src/Console/Question/ChoiceQuestion.php b/src/Console/Question/ChoiceQuestion.php new file mode 100644 index 0000000..05ce56d --- /dev/null +++ b/src/Console/Question/ChoiceQuestion.php @@ -0,0 +1,31 @@ + + */ + +namespace Danmaku\Console\Question; + + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Question\ChoiceQuestion as SymfonyChoiceQuestion; + +/** + * Class ChoiceQuestion + * + * @package Danmaku\Console\Question + * @author Marvin Schreurs + */ +class ChoiceQuestion extends SymfonyChoiceQuestion +{ + protected function isAssoc($array) + { + return true; + } +} \ No newline at end of file diff --git a/src/Console/Question/ConfirmationQuestion.php b/src/Console/Question/ConfirmationQuestion.php new file mode 100644 index 0000000..f333517 --- /dev/null +++ b/src/Console/Question/ConfirmationQuestion.php @@ -0,0 +1,30 @@ + + */ + +namespace Danmaku\Console\Question; + + +use Symfony\Component\Console\Question\ConfirmationQuestion as SymfonyConfirmationQuestion; + +/** + * Class ConfirmationQuestion + * + * @package Danmaku\Console\Question + * @author Marvin Schreurs + */ +class ConfirmationQuestion extends SymfonyConfirmationQuestion +{ + protected function isAssoc($array) + { + return true; + } +} \ No newline at end of file diff --git a/src/Console/Question/Question.php b/src/Console/Question/Question.php new file mode 100644 index 0000000..2354590 --- /dev/null +++ b/src/Console/Question/Question.php @@ -0,0 +1,30 @@ + + */ + +namespace Danmaku\Console\Question; + + +use Symfony\Component\Console\Question\Question as SymfonyQuestion; + +/** + * Class Question + * + * @package Danmaku\Console\Question + * @author Marvin Schreurs + */ +class Question extends SymfonyQuestion +{ + protected function isAssoc($array) + { + return true; + } +} \ No newline at end of file diff --git a/herrfristi/laravel-output-writer/src/Console/Output/BaseOutputWriter.php b/src/Console/Writer/DefaultOutputWriter.php similarity index 79% rename from herrfristi/laravel-output-writer/src/Console/Output/BaseOutputWriter.php rename to src/Console/Writer/DefaultOutputWriter.php index ff93f94..4726a17 100644 --- a/herrfristi/laravel-output-writer/src/Console/Output/BaseOutputWriter.php +++ b/src/Console/Writer/DefaultOutputWriter.php @@ -1,22 +1,22 @@ + * @package Danmaku\Console\Writer + * @author Marvin Schreurs */ -namespace Arc\Base\Console\Output; +namespace Danmaku\Console\Writer; -use Arc\Base\Console\Helper\QuestionHelper; -use Arc\Base\Console\Question\BaseChoiceQuestion; -use Arc\Base\Console\Question\BaseConfirmationQuestion; -use Arc\Base\Console\Question\BaseQuestion; +use Danmaku\Console\Helper\QuestionHelper; +use Danmaku\Console\Question\ChoiceQuestion; +use Danmaku\Console\Question\ConfirmationQuestion; +use Danmaku\Console\Question\Question; use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Formatter\OutputFormatterStyle; @@ -27,18 +27,16 @@ use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ChoiceQuestion; -use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Question\Question; +use Symfony\Component\Console\Question\Question as SymfonyQuestion; use Symfony\Component\Console\Terminal; /** - * Class BaseOutputWriter + * Class DefaultOutputWriter * - * @package Arc\Base\Console\Output - * @author Marvin Schreurs + * @package Danmaku\Console\Writer + * @author Marvin Schreurs */ -class BaseOutputWriter implements OutputWriterInterface +class DefaultOutputWriter implements OutputWriterInterface { /** * Console input interface. @@ -93,11 +91,13 @@ class BaseOutputWriter implements OutputWriterInterface 'warning' => ['yellow', 'black'], 'danger' => ['red', 'black'], 'success' => ['green', 'black'], + 'debug' => ['black', 'white'], 'comment-bg' => ['black', 'white'], 'info-bg' => ['black', 'cyan'], 'warning-bg' => ['black', 'yellow'], 'danger-bg' => ['white', 'red'], 'success-bg' => ['black', 'green'], + 'debug-bg' => ['black', 'white'], 'title' => ['green', 'black'], 'section' => ['white', 'black'], 'question'=> ['green', 'black'], @@ -110,7 +110,7 @@ class BaseOutputWriter implements OutputWriterInterface * * @var int $maxLineLength */ - protected $maxLineLength = 80; + protected $maxLineLength = 120; /** * BaseOutputStyler constructor. @@ -136,9 +136,6 @@ class BaseOutputWriter implements OutputWriterInterface $this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), $this->maxLineLength); } - /** - * {@inheritdoc} - */ public function title(string $title): void { $this->autoPrependBlock(); @@ -149,9 +146,6 @@ class BaseOutputWriter implements OutputWriterInterface $this->newLine(); } - /** - * {@inheritdoc} - */ public function section(string $heading): void { $this->autoPrependBlock(); @@ -162,9 +156,6 @@ class BaseOutputWriter implements OutputWriterInterface $this->newLine(); } - /** - * {@inheritdoc} - */ public function table(array $headers, array $rows): void { $style = clone Table::getStyleDefinition('symfony-style-guide'); @@ -179,9 +170,6 @@ class BaseOutputWriter implements OutputWriterInterface $this->newLine(); } - /** - * {@inheritdoc} - */ public function list(array $items, bool $dictionary = false): void { $this->autoPrependText(); @@ -205,10 +193,7 @@ class BaseOutputWriter implements OutputWriterInterface $this->newLine(); } - /** - * {@inheritdoc} - */ - public function text($message, string $style = null): void + public function text($message, string $style = null, $verbosity = OutputInterface::VERBOSITY_NORMAL): void { $this->autoPrependText(); @@ -218,85 +203,78 @@ class BaseOutputWriter implements OutputWriterInterface $message = sprintf(" <$style>%s", $message); } - $this->writeln(sprintf(' %s', $message)); + $this->writeln(sprintf(' %s', $message), $verbosity); } } - /** - * {@inheritdoc} - */ public function success($message, bool $padding = false): void { - $style = $padding ? 'success-bg' : 'success'; - $this->block($message, 'OK', $style, ' ', $padding); + if(!$this->output->isQuiet()) { + $style = $padding ? 'success-bg' : 'success'; + $this->block($message, 'OK', $style, ' ', $padding); + } } - /** - * {@inheritdoc} - */ public function error($message, bool $padding = false): void { - $style = $padding ? 'danger-bg' : 'danger'; - $this->block($message, 'ERROR', $style, ' ', $padding); + if(!$this->output->isQuiet()) { + $style = $padding ? 'danger-bg' : 'danger'; + $this->block($message, 'ERROR', $style, ' ', $padding); + } } - /** - * {@inheritdoc} - */ public function warning($message, bool $padding = false): void { - $style = $padding ? 'warning-bg' : 'warning'; - $this->block($message, 'WARN', $style, ' ', $padding); + if(!$this->output->isQuiet()) { + $style = $padding ? 'warning-bg' : 'warning'; + $this->block($message, 'WARN', $style, ' ', $padding); + } } - /** - * {@inheritdoc} - */ public function comment($message, bool $padding = false): void { - $style = $padding ? 'comment-bg' : 'comment'; - $this->block($message, null, $style, " // ", $padding, false); + if($this->output->isVeryVerbose()) { + $style = $padding ? 'comment-bg' : 'comment'; + $this->block($message, null, $style, " // ", $padding, false); + } } - /** - * {@inheritdoc} - */ public function info($message, bool $padding = false): void { - $style = $padding ? 'info-bg' : 'info'; - $this->block($message, 'INFO', $style, ' ', $padding); + if($this->output->isVeryVerbose()) { + $style = $padding ? 'info-bg' : 'info'; + $this->block($message, 'INFO', $style, ' ', $padding); + } + } + + public function debug($message, bool $padding = false): void + { + if($this->output->isDebug()) { + $style = $padding ? 'debug-bg' : 'debug'; + $this->block($message, 'DEBUG', $style, ' ', $padding); + } } - /** - * {@inheritdoc} - */ public function exception(\Throwable $throwable, string $message = null): void { $this->error([ $message ?? 'An exception has occurred!', - '', sprintf('In %s on line %s:', $throwable->getFile(), $throwable->getLine()), $throwable->getMessage() ], true); } - /** - * {@inheritdoc} - */ public function ask(string $question, $default = null, $validator = null) { - $question = new BaseQuestion($question, $default); + $question = new Question($question, $default); $question->setValidator($validator); return $this->askQuestion($question); } - /** - * {@inheritdoc} - */ public function password(string $question, $validator = null) { - $question = new BaseQuestion($question); + $question = new Question($question); $question->setHidden(true); $question->setValidator($validator); @@ -304,42 +282,27 @@ class BaseOutputWriter implements OutputWriterInterface return $this->askQuestion($question); } - /** - * {@inheritdoc} - */ public function confirm(string $question, $default = true): bool { - return $this->askQuestion(new BaseConfirmationQuestion($question, $default)); + return $this->askQuestion(new ConfirmationQuestion($question, $default)); } - /** - * {@inheritdoc} - */ public function choice(string $question, array $choices, $default = null) { - return $this->askQuestion(new BaseChoiceQuestion($question, $choices, $default)); + return $this->askQuestion(new ChoiceQuestion($question, $choices, $default)); } - /** - * {@inheritdoc} - */ public function startProgress(int $max = 0): void { $this->progressBar = $this->createProgress($max); $this->progressBar->start(); } - /** - * {@inheritdoc} - */ public function advanceProgress(int $step = 1): void { $this->getProgressBar()->advance($step); } - /** - * {@inheritdoc} - */ public function finishProgress(): void { $this->getProgressBar()->finish(); @@ -347,25 +310,21 @@ class BaseOutputWriter implements OutputWriterInterface $this->progressBar = null; } - /** - * {@inheritdoc} - */ public function createProgress(int $max = 0): ProgressBar { $progressBar = new ProgressBar($this->output, $max); - if ('\\' !== \DIRECTORY_SEPARATOR || 'Hyper' === getenv('TERM_PROGRAM')) { - $progressBar->setEmptyBarCharacter('░'); // light shade character \u2591 - $progressBar->setProgressCharacter(''); - $progressBar->setBarCharacter('▓'); // dark shade character \u2593 - } + $progressBar->setBarCharacter('='); + $progressBar->setEmptyBarCharacter(' '); + $progressBar->setProgressCharacter('>'); + $progressBar->setBarWidth(60); + $progressBar->setFormat( + " %status%\n %current%/%max% [%bar%] %percent:3s%%\n 🏁 %estimated:-50s% %memory:20s%" + ); return $progressBar; } - /** - * {@inheritdoc} - */ public function newLine($count = 1): void { $this->output->write(str_repeat(PHP_EOL, $count)); @@ -406,10 +365,11 @@ class BaseOutputWriter implements OutputWriterInterface } /** - * @param Question $question + * @param SymfonyQuestion $question * @return mixed + * @throws \Exception */ - protected function askQuestion(Question $question) + protected function askQuestion(SymfonyQuestion $question) { if ($this->input->isInteractive()) { $this->autoPrependBlock(); @@ -421,9 +381,6 @@ class BaseOutputWriter implements OutputWriterInterface $answer = $this->questionHelper->ask($this->input, $this->output, $question); - - - if ($this->input->isInteractive()) { $this->newLine(); $this->bufferedOutput->write("\n"); @@ -480,13 +437,14 @@ class BaseOutputWriter implements OutputWriterInterface * Formats a message as a block of text. * * @param string|array $messages The message to write in the block - * @param string|null $type The block type (added in [] on first line) - * @param string|null $style The style to apply to the whole block - * @param string $prefix The prefix for the block - * @param bool $padding Whether to add vertical padding - * @param bool $escape Whether to escape the message + * @param string|null $type The block type (added in [] on first line) + * @param string|null $style The style to apply to the whole block + * @param string $prefix The prefix for the block + * @param bool $padding Whether to add vertical padding + * @param bool $escape Whether to escape the message + * @param int $verbosity */ - protected function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = true) + protected function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = true, $verbosity = OutputInterface::OUTPUT_NORMAL) { $messages = \is_array($messages) ? array_values($messages) : [$messages]; @@ -496,7 +454,7 @@ class BaseOutputWriter implements OutputWriterInterface $this->autoPrependText(); } - $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, $escape)); + $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, $escape), $verbosity); if($padding) { $this->newLine(); diff --git a/herrfristi/laravel-output-writer/src/Console/Output/OutputWriterInterface.php b/src/Console/Writer/OutputWriterInterface.php similarity index 87% rename from herrfristi/laravel-output-writer/src/Console/Output/OutputWriterInterface.php rename to src/Console/Writer/OutputWriterInterface.php index c4447eb..a3ff7c6 100644 --- a/herrfristi/laravel-output-writer/src/Console/Output/OutputWriterInterface.php +++ b/src/Console/Writer/OutputWriterInterface.php @@ -6,11 +6,11 @@ * * PHP version 7.2 * - * @package Arc\Base\Console\Output - * @author Marvin Schreurs + * @package Danmaku\Console\Writer + * @author Marvin Schreurs */ -namespace Arc\Base\Console\Output; +namespace Danmaku\Console\Writer; use Symfony\Component\Console\Helper\ProgressBar; @@ -19,8 +19,8 @@ use Symfony\Component\Console\Output\OutputInterface; /** * Interface OutputWriterInterface * - * @package Arc\Base\Console\Output - * @author Marvin Schreurs + * @package Danmaku\Console\Writer + * @author Marvin Schreurs */ interface OutputWriterInterface { @@ -62,10 +62,11 @@ interface OutputWriterInterface * Writes an unformatted line of text. * * @param string|array $message Message to display. - * @param string|null $style Style to apply to the message. + * @param string|null $style Style to apply to the message. + * @param int $verbosity Verbosity level at which this message should be printed. * @return void */ - public function text($message, string $style = null): void; + public function text($message, string $style = null, $verbosity = OutputInterface::VERBOSITY_NORMAL): void; /** * Formats a success message. @@ -112,6 +113,15 @@ interface OutputWriterInterface */ public function info($message, bool $padding = false): void; + /** + * Formats a debug message. + * + * @param string|array $message Message to display. + * @param bool $padding Render the message in a padded box. + * @return void + */ + public function debug($message, bool $padding = false): void; + /** * Formats an exception. *