6 use Consolidation\Log\ConsoleLogLevel;
7 use Psr\Log\LoggerAwareTrait;
9 use Robo\Contract\ProgressIndicatorAwareInterface;
12 * Task input/output methods. TaskIO is 'used' in BaseTask, so any
13 * task that extends this class has access to all of the methods here.
14 * printTaskInfo, printTaskSuccess, and printTaskError are the three
15 * primary output methods that tasks are encouraged to use. Tasks should
16 * avoid using the IO trait output methods.
22 use VerbosityThresholdTrait;
25 * @return mixed|null|\Psr\Log\LoggerInterface
27 public function logger()
29 // $this->logger should always be set in Robo core tasks.
34 // TODO: Remove call to Robo::logger() once maintaining backwards
35 // compatibility with legacy external Robo tasks is no longer desired.
36 if (!Robo::logger()) {
40 static $gaveDeprecationWarning = false;
41 if (!$gaveDeprecationWarning) {
42 trigger_error('No logger set for ' . get_class($this) . '. Use $this->task(Foo::class) rather than new Foo() in loadTasks to ensure the builder can initialize task the task, or use $this->collectionBuilder()->taskFoo() if creating one task from within another.', E_USER_DEPRECATED);
43 $gaveDeprecationWarning = true;
45 return Robo::logger();
49 * Print information about a task in progress.
51 * With the Symfony Console logger, NOTICE is displayed at VERBOSITY_VERBOSE
52 * and INFO is displayed at VERBOSITY_VERY_VERBOSE.
54 * Robo overrides the default such that NOTICE is displayed at
55 * VERBOSITY_NORMAL and INFO is displayed at VERBOSITY_VERBOSE.
57 * n.b. We should probably have printTaskNotice for our ordinary
58 * output, and use printTaskInfo for less interesting messages.
61 * @param null|array $context
63 protected function printTaskInfo($text, $context = null)
65 // The 'note' style is used for both 'notice' and 'info' log levels;
66 // However, 'notice' is printed at VERBOSITY_NORMAL, whereas 'info'
67 // is only printed at VERBOSITY_VERBOSE.
68 $this->printTaskOutput(LogLevel::NOTICE, $text, $this->getTaskContext($context));
72 * Provide notification that some part of the task succeeded.
74 * With the Symfony Console logger, success messages are remapped to NOTICE,
75 * and displayed in VERBOSITY_VERBOSE. When used with the Robo logger,
76 * success messages are displayed at VERBOSITY_NORMAL.
79 * @param null|array $context
81 protected function printTaskSuccess($text, $context = null)
83 // Not all loggers will recognize ConsoleLogLevel::SUCCESS.
84 // We therefore log as LogLevel::NOTICE, and apply a '_level'
85 // override in the context so that this message will be
86 // logged as SUCCESS if that log level is recognized.
87 $context['_level'] = ConsoleLogLevel::SUCCESS;
88 $this->printTaskOutput(LogLevel::NOTICE, $text, $this->getTaskContext($context));
92 * Provide notification that there is something wrong, but
93 * execution can continue.
95 * Warning messages are displayed at VERBOSITY_NORMAL.
98 * @param null|array $context
100 protected function printTaskWarning($text, $context = null)
102 $this->printTaskOutput(LogLevel::WARNING, $text, $this->getTaskContext($context));
106 * Provide notification that some operation in the task failed,
107 * and the task cannot continue.
109 * Error messages are displayed at VERBOSITY_NORMAL.
111 * @param string $text
112 * @param null|array $context
114 protected function printTaskError($text, $context = null)
116 $this->printTaskOutput(LogLevel::ERROR, $text, $this->getTaskContext($context));
120 * Provide debugging notification. These messages are only
121 * displayed if the log level is VERBOSITY_DEBUG.
124 * @param null|array $context
126 protected function printTaskDebug($text, $context = null)
128 $this->printTaskOutput(LogLevel::DEBUG, $text, $this->getTaskContext($context));
132 * @param string $level
133 * One of the \Psr\Log\LogLevel constant
134 * @param string $text
135 * @param null|array $context
137 protected function printTaskOutput($level, $text, $context)
139 if (!$this->verbosityMeetsThreshold()) {
142 $logger = $this->logger();
146 // Hide the progress indicator, if it is visible.
147 $inProgress = $this->hideTaskProgress();
148 $logger->log($level, $text, $this->getTaskContext($context));
149 // After we have printed our log message, redraw the progress indicator.
150 $this->showTaskProgress($inProgress);
156 protected function hideTaskProgress()
159 if ($this instanceof ProgressIndicatorAwareInterface) {
160 $inProgress = $this->inProgress();
163 // If a progress indicator is running on this task, then we mush
164 // hide it before we print anything, or its display will be overwritten.
166 $inProgress = $this->hideProgressIndicator();
174 protected function showTaskProgress($inProgress)
177 $this->restoreProgressIndicator($inProgress);
182 * Format a quantity of bytes.
185 * @param int $precision
189 protected function formatBytes($size, $precision = 2)
194 $base = log($size, 1024);
195 $suffixes = array('', 'k', 'M', 'G', 'T');
196 return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
200 * Get the formatted task name for use in task output.
201 * This is placed in the task context under 'name', and
202 * used as the log label by Robo\Common\RoboLogStyle,
203 * which is inserted at the head of log messages by
204 * Robo\Common\CustomLogStyle::formatMessage().
206 * @param null|object $task
210 protected function getPrintedTaskName($task = null)
215 return TaskInfo::formatTaskName($task);
219 * @param null|array $context
221 * @return array with context information
223 protected function getTaskContext($context = null)
228 if (!is_array($context)) {
229 $context = ['task' => $context];
231 if (!array_key_exists('task', $context)) {
232 $context['task'] = $this;
235 return $context + TaskInfo::getTaskContext($context['task']);