Files
popsu-d9/old.vendor/consolidation/robo/src/Common/TaskIO.php
2022-04-27 11:30:43 +02:00

269 lines
8.0 KiB
PHP

<?php
namespace Robo\Common;
use Robo\Robo;
use Robo\TaskInfo;
use Consolidation\Log\ConsoleLogLevel;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Robo\Contract\ProgressIndicatorAwareInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Task input/output methods. TaskIO is 'used' in BaseTask, so any
* task that extends this class has access to all of the methods here.
* printTaskInfo, printTaskSuccess, and printTaskError are the three
* primary output methods that tasks are encouraged to use. Tasks should
* avoid using the IO trait output methods.
*/
trait TaskIO
{
use ConfigAwareTrait;
use VerbosityThresholdTrait;
use OutputAwareTrait;
protected $logger;
protected $output;
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
$this->resetLoggerOutput();
}
public function setOutput(OutputInterface $output)
{
$this->output = $output;
$this->resetLoggerOutput();
}
private function resetLoggerOutput()
{
if (isset($this->output) && isset($this->logger) && ($this->logger instanceof \Robo\Log\Logger)) {
$this->logger->setErrorStream(null);
$this->logger->setOutputStream($this->output);
}
}
/**
* @return null|\Psr\Log\LoggerInterface
*
* @deprecated
*/
public function logger()
{
// $this->logger should always be set in Robo core tasks.
if ($this->logger) {
return $this->logger;
}
// TODO: Remove call to Robo::logger() once maintaining backwards
// compatibility with legacy external Robo tasks is no longer desired.
if (!Robo::logger()) {
return null;
}
static $gaveDeprecationWarning = false;
if (!$gaveDeprecationWarning) {
trigger_error('No logger set for ' . get_class($this) . '. Use $this->task(Foo::class) rather than new Foo() in Tasks to ensure the builder can initialize task the task, or use $this->collectionBuilder()->taskFoo() if creating one task from within another.', E_USER_DEPRECATED);
$gaveDeprecationWarning = true;
}
return Robo::logger();
}
/**
* Print information about a task in progress.
*
* With the Symfony Console logger, NOTICE is displayed at VERBOSITY_VERBOSE
* and INFO is displayed at VERBOSITY_VERY_VERBOSE.
*
* Robo overrides the default such that NOTICE is displayed at
* VERBOSITY_NORMAL and INFO is displayed at VERBOSITY_VERBOSE.
*
* n.b. We should probably have printTaskNotice for our ordinary
* output, and use printTaskInfo for less interesting messages.
*
* @param string $text
* @param null|array $context
*/
protected function printTaskInfo($text, $context = null)
{
// The 'note' style is used for both 'notice' and 'info' log levels;
// However, 'notice' is printed at VERBOSITY_NORMAL, whereas 'info'
// is only printed at VERBOSITY_VERBOSE.
$this->printTaskOutput(LogLevel::NOTICE, $text, $this->getTaskContext($context));
}
/**
* Provide notification that some part of the task succeeded.
*
* With the Symfony Console logger, success messages are remapped to NOTICE,
* and displayed in VERBOSITY_VERBOSE. When used with the Robo logger,
* success messages are displayed at VERBOSITY_NORMAL.
*
* @param string $text
* @param null|array $context
*/
protected function printTaskSuccess($text, $context = null)
{
// Not all loggers will recognize ConsoleLogLevel::SUCCESS.
// We therefore log as LogLevel::NOTICE, and apply a '_level'
// override in the context so that this message will be
// logged as SUCCESS if that log level is recognized.
$context['_level'] = ConsoleLogLevel::SUCCESS;
$this->printTaskOutput(LogLevel::NOTICE, $text, $this->getTaskContext($context));
}
/**
* Provide notification that there is something wrong, but
* execution can continue.
*
* Warning messages are displayed at VERBOSITY_NORMAL.
*
* @param string $text
* @param null|array $context
*/
protected function printTaskWarning($text, $context = null)
{
$this->printTaskOutput(LogLevel::WARNING, $text, $this->getTaskContext($context));
}
/**
* Provide notification that some operation in the task failed,
* and the task cannot continue.
*
* Error messages are displayed at VERBOSITY_NORMAL.
*
* @param string $text
* @param null|array $context
*/
protected function printTaskError($text, $context = null)
{
$this->printTaskOutput(LogLevel::ERROR, $text, $this->getTaskContext($context));
}
/**
* Provide debugging notification. These messages are only
* displayed if the log level is VERBOSITY_DEBUG.
*
* @param string$text
* @param null|array $context
*/
protected function printTaskDebug($text, $context = null)
{
$this->printTaskOutput(LogLevel::DEBUG, $text, $this->getTaskContext($context));
}
/**
* @param string $level
* One of the \Psr\Log\LogLevel constant
* @param string $text
* @param null|array $context
*
* @deprecated
*/
protected function printTaskOutput($level, $text, $context)
{
if (!$this->verbosityMeetsThreshold()) {
return;
}
$logger = $this->logger();
if (!$logger) {
return;
}
// Hide the progress indicator, if it is visible.
$inProgress = $this->hideTaskProgress();
$logger->log($level, $text, $this->getTaskContext($context));
// After we have printed our log message, redraw the progress indicator.
$this->showTaskProgress($inProgress);
}
/**
* @return bool
*/
protected function hideTaskProgress()
{
$inProgress = false;
if ($this instanceof ProgressIndicatorAwareInterface) {
$inProgress = $this->inProgress();
}
// If a progress indicator is running on this task, then we mush
// hide it before we print anything, or its display will be overwritten.
if ($inProgress) {
$inProgress = $this->hideProgressIndicator();
}
return $inProgress;
}
/**
* @param bool $inProgress
*/
protected function showTaskProgress($inProgress)
{
if ($inProgress) {
$this->restoreProgressIndicator($inProgress);
}
}
/**
* Format a quantity of bytes.
*
* @param int $size
* @param int $precision
*
* @return string
*/
protected function formatBytes($size, $precision = 2)
{
if ($size === 0) {
return 0;
}
$base = log($size, 1024);
$suffixes = array('', 'k', 'M', 'G', 'T');
return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
}
/**
* Get the formatted task name for use in task output.
* This is placed in the task context under 'name', and
* used as the log label by Robo\Common\RoboLogStyle,
* which is inserted at the head of log messages by
* Robo\Common\CustomLogStyle::formatMessage().
*
* @param null|object $task
*
* @return string
*/
protected function getPrintedTaskName($task = null)
{
if (!$task) {
$task = $this;
}
return TaskInfo::formatTaskName($task);
}
/**
* @param null|array $context
*
* @return array
* Context information.
*/
protected function getTaskContext($context = null)
{
if (!$context) {
$context = [];
}
if (!is_array($context)) {
$context = ['task' => $context];
}
if (!array_key_exists('task', $context)) {
$context['task'] = $this;
}
return $context + TaskInfo::getTaskContext($context['task']);
}
}