ScheduleConsoleOutputSubscriber::afterSchedule()   B
last analyzed

Complexity

Conditions 7
Paths 18

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 7

Importance

Changes 0
Metric Value
eloc 21
c 0
b 0
f 0
dl 0
loc 37
ccs 22
cts 22
cp 1
rs 8.6506
cc 7
nc 18
nop 1
crap 7
1
<?php
2
3
namespace Zenstruck\ScheduleBundle\EventListener;
4
5
use Symfony\Component\Console\Style\OutputStyle;
6
use Symfony\Component\Console\Style\SymfonyStyle;
7
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
8
use Zenstruck\ScheduleBundle\Event\AfterScheduleEvent;
9
use Zenstruck\ScheduleBundle\Event\AfterTaskEvent;
10
use Zenstruck\ScheduleBundle\Event\BeforeScheduleEvent;
11
use Zenstruck\ScheduleBundle\Event\BeforeTaskEvent;
12
use Zenstruck\ScheduleBundle\Schedule\Task\Result;
13
14
/**
15
 * @author Kevin Bond <[email protected]>
16
 */
17
final class ScheduleConsoleOutputSubscriber implements EventSubscriberInterface
18
{
19
    /** @var OutputStyle */
20 12
    private $io;
21
22 12
    public function __construct(OutputStyle $io)
23 12
    {
24
        $this->io = $io;
25 12
    }
26
27
    public static function getSubscribedEvents(): array
28 12
    {
29
        return [
30
            BeforeScheduleEvent::class => 'beforeSchedule',
31
            AfterScheduleEvent::class => 'afterSchedule',
32
            BeforeTaskEvent::class => 'beforeTask',
33
            AfterTaskEvent::class => 'afterTask',
34
        ];
35 10
    }
36
37 10
    public function afterSchedule(AfterScheduleEvent $event): void
38
    {
39 10
        $context = $event->runContext();
40 1
41
        if ($context->isSkipped()) {
42 1
            $this->io->note($context->getSkipReason());
43
44
            return;
45 9
        }
46 9
47 9
        $total = \count($context->getResults());
48 9
        $successful = \count($context->getSuccessful());
49 9
        $failures = \count($context->getFailures());
50 9
        $skipped = \count($context->getSkipped());
51
        $run = \count($context->getRun());
52 9
        $messages = ["{$run}/{$total} tasks ran"];
53 1
54
        if (0 === $total) {
55
            return;
56 8
        }
57 8
58
        if ($successful > 0) {
59
            $messages[] = "{$successful} succeeded";
60 8
        }
61 1
62
        if ($skipped > 0) {
63
            $messages[] = "{$skipped} skipped";
64 8
        }
65 4
66
        if ($failures > 0) {
67
            $messages[] = "{$failures} failed";
68 8
        }
69 8
70
        $messages = \implode(', ', $messages).'.';
71 8
        $messages .= " (Duration: {$context->getFormattedDuration()}, Memory: {$context->getFormattedMemory()})";
72 8
73
        $this->io->{$context->isSuccessful() ? 'success' : 'error'}($messages);
74 10
    }
75
76 10
    public function beforeSchedule(BeforeScheduleEvent $event): void
77
    {
78 10
        $context = $event->runContext();
79 10
80
        $allTaskCount = \count($context->getSchedule()->all());
81 10
        $dueTaskCount = \count($context->dueTasks());
82 1
83
        if ($dueTaskCount > 0) {
84 1
            $this->io->{$this->io instanceof SymfonyStyle ? 'comment' : 'text'}(\sprintf(
85
                '%sRunning <info>%s</info> %stask%s. (%s total tasks)',
86
                $context->isForceRun() ? '<error>Force</error> ' : '',
87 9
                $dueTaskCount,
88 9
                $context->isForceRun() ? '' : 'due ',
89 9
                $dueTaskCount > 1 ? 's' : '',
90 9
                $allTaskCount
91 9
            ));
92 9
        }
93 9
94
        if ($this->io->isDebug()) {
95 9
            $this->io->note(\sprintf('No tasks due to run. (%s total tasks)', $allTaskCount));
96
        }
97 8
    }
98
99 8
    public function beforeTask(BeforeTaskEvent $event): void
100 8
    {
101
        $context = $event->runContext();
102 8
        $task = $context->getTask();
103 8
104 8
        $this->io->text(\sprintf(
105 8
            '%s<comment>Running %s:</comment> %s',
106 8
            $context->getScheduleRunContext()->isForceRun() ? '<error>Force</error> ' : '',
107
            $task->getType(),
108 8
            $task->getDescription()
109
        ));
110 8
    }
111
112 8
    public function afterTask(AfterTaskEvent $event): void
113
    {
114 8
        $context = $event->runContext();
115 3
116 3
        if ($this->io->isVerbose() && $output = $context->getResult()->getOutput()) {
117 3
            $this->io->text('---begin output---');
118
            $this->io->write($output);
119
            $this->io->text('---end output---');
120 8
        }
121 8
122 8
        $this->io->text(\sprintf('%s (<comment>Duration:</comment> %s, <comment>Memory:</comment> %s)',
123 8
            $this->afterTaskMessage($context->getResult()),
124
            $context->getFormattedDuration(),
125 8
            $context->getFormattedMemory()
126 8
        ));
127
        $this->io->newLine();
128 8
    }
129
130 8
    private function afterTaskMessage(Result $result): string
131 2
    {
132
        if ($result->isException()) {
133
            return "<error>Exception:</error> {$result->getDescription()}";
134 8
        }
135 2
136
        if ($result->isFailure()) {
137
            return "<error>Failure:</error> {$result->getDescription()}";
138 8
        }
139 1
140
        if ($result->isSkipped()) {
141
            return "<question>Skipped:</question> {$result->getDescription()}";
142 8
        }
143
144
        return '<info>Success.</info>';
145
    }
146
}
147