Completed
Push — master ( faecaf...e43139 )
by Siad
15:28
created

DefaultLogger::formatTime()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 9.0581

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 10
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 15
ccs 5
cts 11
cp 0.4545
crap 9.0581
rs 9.6111
1
<?php
2
/**
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information please see
17
 * <http://phing.info>.
18
 */
19
20
/**
21
 * Writes a build event to the console.
22
 *
23
 * Currently, it only writes which targets are being executed, and
24
 * any messages that get logged.
25
 *
26
 * @author    Andreas Aderhold <[email protected]>
27
 * @copyright 2001,2002 THYRELL. All rights reserved
28
 * @see       BuildEvent
29
 * @package   phing.listener
30
 */
31
class DefaultLogger implements StreamRequiredBuildLogger
32
{
33
34
    /**
35
     *  Size of the left column in output. The default char width is 12.
36
     *
37
     * @var int
38
     */
39
    const LEFT_COLUMN_SIZE = 12;
40
41
    /**
42
     *  The message output level that should be used. The default is
43
     *  <code>Project::MSG_VERBOSE</code>.
44
     *
45
     * @var int
46
     */
47
    protected $msgOutputLevel = Project::MSG_ERR;
48
49
    /**
50
     *  Time that the build started
51
     *
52
     * @var int
53
     */
54
    protected $startTime;
55
56
    /**
57
     * @var OutputStream Stream to use for standard output.
58
     */
59
    protected $out;
60
61
    /**
62
     * @var OutputStream Stream to use for error output.
63
     */
64
    protected $err;
65
66
    protected $emacsMode = false;
67
68
    /**
69
     *  Construct a new default logger.
70
     */
71 1
    public function __construct()
72
    {
73 1
    }
74
75
    /**
76
     *  Set the msgOutputLevel this logger is to respond to.
77
     *
78
     *  Only messages with a message level lower than or equal to the given
79
     *  level are output to the log.
80
     *
81
     *  <p> Constants for the message levels are in Project.php. The order of
82
     *  the levels, from least to most verbose, is:
83
     *
84
     *  <ul>
85
     *    <li>Project::MSG_ERR</li>
86
     *    <li>Project::MSG_WARN</li>
87
     *    <li>Project::MSG_INFO</li>
88
     *    <li>Project::MSG_VERBOSE</li>
89
     *    <li>Project::MSG_DEBUG</li>
90
     *  </ul>
91
     *
92
     *  The default message level for DefaultLogger is Project::MSG_ERR.
93
     *
94
     * @param int $level The logging level for the logger.
95
     * @see   BuildLogger#setMessageOutputLevel()
96
     */
97
    public function setMessageOutputLevel($level)
98
    {
99
        $this->msgOutputLevel = (int) $level;
100
    }
101
102
    /**
103
     * Sets the output stream.
104
     *
105
     * @param OutputStream $output
106
     * @see   BuildLogger#setOutputStream()
107
     */
108
    public function setOutputStream(OutputStream $output)
109
    {
110
        $this->out = $output;
111
    }
112
113
    /**
114
     * Sets the error stream.
115
     *
116
     * @param OutputStream $err
117
     * @see   BuildLogger#setErrorStream()
118
     */
119
    public function setErrorStream(OutputStream $err)
120
    {
121
        $this->err = $err;
122
    }
123
124
    /**
125
     * Sets this logger to produce emacs (and other editor) friendly output.
126
     *
127
     * @param bool $emacsMode <code>true</code> if output is to be unadorned so that
128
     *                  emacs and other editors can parse files names, etc.
129
     */
130
    public function setEmacsMode($emacsMode)
131
    {
132
        $this->emacsMode = $emacsMode;
133
    }
134
135
    /**
136
     *  Sets the start-time when the build started. Used for calculating
137
     *  the build-time.
138
     *
139
     * @param BuildEvent $event
140
     */
141
    public function buildStarted(BuildEvent $event)
142
    {
143
        $this->startTime = Phing::currentTimeMillis();
144
        if ($this->msgOutputLevel >= Project::MSG_INFO) {
145
            $this->printMessage(
146
                "Buildfile: " . $event->getProject()->getProperty("phing.file"),
147
                $this->out,
148
                Project::MSG_INFO
149
            );
150
        }
151
    }
152
153
    /**
154
     *  Prints whether the build succeeded or failed, and any errors that
155
     *  occurred during the build. Also outputs the total build-time.
156
     *
157
     * @param BuildEvent $event
158
     * @see   BuildEvent::getException()
159
     */
160 1
    public function buildFinished(BuildEvent $event)
161
    {
162 1
        $error = $event->getException();
163 1
        if ($error === null) {
164 1
            $msg = PHP_EOL . $this->getBuildSuccessfulMessage() . PHP_EOL;
165
        } else {
166
            $msg = PHP_EOL . $this->getBuildFailedMessage() . PHP_EOL;
167
            self::throwableMessage($msg, $error, Project::MSG_VERBOSE <= $this->msgOutputLevel);
168
        }
169 1
        $msg .= PHP_EOL . "Total time: " . static::formatTime(Phing::currentTimeMillis() - $this->startTime) . PHP_EOL;
170
171 1
        if ($error === null) {
172 1
            $this->printMessage($msg, $this->out, Project::MSG_VERBOSE);
173
        } else {
174
            $this->printMessage($msg, $this->err, Project::MSG_ERR);
175
        }
176 1
    }
177
178 3
    public static function throwableMessage(&$msg, $error, $verbose)
179
    {
180 3
        while ($error instanceof BuildException) {
181 3
            $cause = $error->getPrevious();
182 3
            if ($cause === null) {
183 3
                break;
184
            }
185 2
            $msg1 = trim($error);
186 2
            $msg2 = trim($cause);
187 2
            if (StringHelper::endsWith($msg2, $msg1)) {
188 2
                $msg .= StringHelper::substring($msg1, 0, strlen($msg1) - strlen($msg2) - 1);
189 2
                $error = $cause;
190
            } else {
191
                break;
192
            }
193
        }
194 3
        $msg .= $verbose || !$error instanceof BuildException
195
            ? $error->getMessage() . PHP_EOL . $error->getTraceAsString() . PHP_EOL
196 3
            : $error->getLocation() . ' ' . $error->getMessage() . PHP_EOL;
197 3
    }
198
199
    /**
200
     * Get the message to return when a build failed.
201
     *
202
     * @return string The classic "BUILD FAILED"
203
     */
204
    protected function getBuildFailedMessage()
205
    {
206
        return "BUILD FAILED";
207
    }
208
209
    /**
210
     * Get the message to return when a build succeeded.
211
     *
212
     * @return string The classic "BUILD FINISHED"
213
     */
214 1
    protected function getBuildSuccessfulMessage()
215
    {
216 1
        return "BUILD FINISHED";
217
    }
218
219
    /**
220
     *  Prints the current target name
221
     *
222
     * @param BuildEvent $event
223
     * @see   BuildEvent::getTarget()
224
     */
225
    public function targetStarted(BuildEvent $event)
226
    {
227
        if (
228
            Project::MSG_INFO <= $this->msgOutputLevel
229
            && $event->getTarget()->getName() != ''
230
        ) {
231
            $showLongTargets = $event->getProject()->getProperty("phing.showlongtargets");
232
            $msg = PHP_EOL . $event->getProject()->getName() . ' > ' . $event->getTarget()->getName() . ($showLongTargets ? ' [' . $event->getTarget()->getDescription() . ']' : '') . ':' . PHP_EOL;
233
            $this->printMessage($msg, $this->out, $event->getPriority());
234
        }
235
    }
236
237
    /**
238
     *  Fired when a target has finished. We don't need specific action on this
239
     *  event. So the methods are empty.
240
     *
241
     * @param BuildEvent $event
242
     * @see   BuildEvent::getException()
243
     */
244
    public function targetFinished(BuildEvent $event)
245
    {
246
    }
247
248
    /**
249
     *  Fired when a task is started. We don't need specific action on this
250
     *  event. So the methods are empty.
251
     *
252
     * @param BuildEvent $event
253
     * @see   BuildEvent::getTask()
254
     */
255
    public function taskStarted(BuildEvent $event)
256
    {
257
    }
258
259
    /**
260
     *  Fired when a task has finished. We don't need specific action on this
261
     *  event. So the methods are empty.
262
     *
263
     * @param BuildEvent $event The BuildEvent
264
     * @see   BuildEvent::getException()
265
     */
266
    public function taskFinished(BuildEvent $event)
267
    {
268
    }
269
270
    /**
271
     *  Print a message to the stdout.
272
     *
273
     * @param BuildEvent $event
274
     * @see   BuildEvent::getMessage()
275
     */
276
    public function messageLogged(BuildEvent $event)
277
    {
278
        $priority = $event->getPriority();
279
        if ($priority <= $this->msgOutputLevel) {
280
            $msg = "";
281
            if ($event->getTask() !== null && !$this->emacsMode) {
282
                $name = $event->getTask();
283
                $name = $name->getTaskName();
284
                $msg = str_pad("[$name] ", self::LEFT_COLUMN_SIZE, " ", STR_PAD_LEFT);
285
            }
286
287
            $msg .= $event->getMessage();
288
289
            if ($priority != Project::MSG_ERR) {
290
                $this->printMessage($msg, $this->out, $priority);
291
            } else {
292
                $this->printMessage($msg, $this->err, $priority);
293
            }
294
        }
295
    }
296
297
    /**
298
     *  Formats a time micro integer to human readable format.
299
     *
300
     * @param  integer The time stamp
301
     * @return string
302
     */
303 1
    public static function formatTime($micros)
304
    {
305 1
        $seconds = $micros;
306 1
        $minutes = (int) floor($seconds / 60);
307 1
        if ($minutes >= 1) {
308
            return sprintf(
309
                "%1.0f minute%s %0.2f second%s",
310
                $minutes,
311
                ($minutes === 1 ? " " : "s "),
312
                $seconds - floor($seconds / 60) * 60,
313
                ($seconds % 60 === 1 ? "" : "s")
314
            );
315
        }
316
317 1
        return sprintf("%0.4f second%s", $seconds, ($seconds % 60 === 1 ? "" : "s"));
318
    }
319
320
    /**
321
     * Prints a message to console.
322
     *
323
     * @param  string $message The message to print.
324
     *                                         Should not be
325
     *                                         <code>null</code>.
326
     * @param  OutputStream|resource $stream The stream to use for message printing.
327
     * @param  int $priority The priority of the message.
328
     *                                         (Ignored in this
329
     *                                         implementation.)
330
     * @throws IOException
331
     * @return void
332
     */
333
    protected function printMessage($message, OutputStream $stream, $priority)
0 ignored issues
show
Unused Code introduced by
The parameter $priority is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

333
    protected function printMessage($message, OutputStream $stream, /** @scrutinizer ignore-unused */ $priority)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
334
    {
335
        $stream->write($message . PHP_EOL);
336
    }
337
}
338