Completed
Pull Request — master (#12)
by Harry
01:54
created

Lines::format()   B

Complexity

Conditions 6
Paths 18

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 19
cts 19
cp 1
rs 8.5125
c 0
b 0
f 0
cc 6
eloc 17
nc 18
nop 4
crap 6
1
<?php
2
3
namespace Graze\ParallelProcess;
4
5
use Graze\DiffRenderer\DiffConsoleOutput;
6
use Graze\DiffRenderer\Terminal\TerminalInterface;
7
use Symfony\Component\Console\Output\OutputInterface;
8
use Symfony\Component\Process\Exception\ProcessFailedException;
9
use Symfony\Component\Process\Process;
10
11
class Lines
12
{
13
    /** @var OutputInterface */
14
    private $output;
15
    /** @var TerminalInterface */
16
    private $terminal;
17
    /** @var Pool */
18
    private $processPool;
19
    /** @var int[] */
20
    private $maxLengths = [];
21
    /** @var bool */
22
    private $showDuration = true;
23
    /** @var bool */
24
    private $showType = true;
25
    /** @var bool */
26
    private $colourProcesses = true;
27
    /** @var string[] */
28
    private $colours = ['red', 'green', 'blue', 'yellow', 'magenta', 'white', 'cyan'];
29
30
    /**
31
     * Stream constructor.
32
     *
33
     * @param OutputInterface $output
34
     * @param Pool|null       $pool
35
     */
36 9 View Code Duplication
    public function __construct(OutputInterface $output, Pool $pool = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
37
    {
38 9
        $this->output = $output;
39 9
        if (!$output instanceof DiffConsoleOutput) {
40 3
            $this->output = new DiffConsoleOutput($output);
41 3
            $this->output->setTrim(false);
42 3
        } else {
43 9
            $this->output = $output;
44
        }
45 9
        $this->terminal = $this->output->getTerminal();
46 9
        $this->processPool = $pool ?: new Pool();
47 9
    }
48
49
    /**
50
     * Show the running duration of each process
51
     *
52
     * @param bool $showDuration
53
     *
54
     * @return $this
55
     */
56 2
    public function setShowDuration($showDuration)
57
    {
58 2
        $this->showDuration = $showDuration;
59 2
        return $this;
60
    }
61
62
    /**
63
     * @return bool
64
     */
65 1
    public function isShowDuration()
66
    {
67 1
        return $this->showDuration;
68
    }
69
70
    /**
71
     * Show the type of each output (`out` or `err`)
72
     *
73
     * @param bool $showType
74
     *
75
     * @return $this
76
     */
77 2
    public function setShowType($showType)
78
    {
79 2
        $this->showType = $showType;
80 2
        return $this;
81
    }
82
83
    /**
84
     * @return bool
85
     */
86 1
    public function isShowType()
87
    {
88 1
        return $this->showType;
89
    }
90
91
    /**
92
     * Set weather this should colour each process with a different colour
93
     *
94
     * @param bool $colourProcesses
95
     *
96
     * @return $this
97
     */
98 2
    public function setColourProcesses($colourProcesses)
99
    {
100 2
        $this->colourProcesses = $colourProcesses;
101 2
        return $this;
102
    }
103
104
    /**
105
     * Does this colour each process with a different colour
106
     *
107
     * @return bool
108
     */
109 1
    public function isColourProcesses()
110
    {
111 1
        return $this->colourProcesses;
112
    }
113
114
    /**
115
     * @param Process $process
116
     * @param array   $data
117
     */
118 6
    public function add(Process $process, array $data = [])
119
    {
120 6
        $index = $this->processPool->count();
121
        $onProgress = function (Process $process, $duration, $last, $lastType) use ($index, $data) {
122 6
            $message = ($this->showType ? sprintf('(%s) %s', $lastType, $last) : $last);
123 6
            $this->output->writeln($this->format($index, $data, $duration, $message));
124 6
        };
125
126 6
        $run = new Run(
127 6
            $process,
128
            function (Process $process, $duration) use ($index, $data) {
129 5
                $this->output->writeln($this->format($index, $data, $duration, "<info>✓ Succeeded</info>"));
130 6
            },
131
            function (Process $process, $duration) use ($index, $data) {
132 1
                $this->output->writeln(
133 1
                    $this->format(
134 1
                        $index,
135 1
                        $data,
136 1
                        $duration,
137 1
                        sprintf(
138 1
                            "<error>x Failed</error> (code: %d) %s",
139 1
                            $process->getExitCode(),
140 1
                            $process->getExitCodeText()
141 1
                        )
142 1
                    )
143 1
                );
144 1
                $this->output->writeln((new ProcessFailedException($process))->getMessage());
145 6
            },
146 6
            $onProgress,
147 6
            function (Process $process, $duration) use ($index, $data) {
148 6
                $this->output->writeln($this->format($index, $data, $duration, "<fg=blue>→ Started</>"));
149 6
            }
150 6
        );
151 6
        $run->setUpdateOnPoll(false);
152 6
        $this->processPool->add($run);
153
154 6
        $this->updateRowKeyLengths($data);
155 6
    }
156
157
    /**
158
     * Parses the rows to determine the key lengths to make a pretty table
159
     *
160
     * @param array $data
161
     */
162 6 View Code Duplication
    private function updateRowKeyLengths(array $data = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
163
    {
164 6
        $lengths = array_map('mb_strlen', $data);
165
166 6
        $keys = array_merge(array_keys($lengths), array_keys($this->maxLengths));
167
168 6
        foreach ($keys as $key) {
169 6
            if (!isset($this->maxLengths[$key])
170 6
                || (isset($lengths[$key]) && $lengths[$key] > $this->maxLengths[$key])
171 6
            ) {
172 6
                $this->maxLengths[$key] = $lengths[$key];
173 6
            }
174 6
        }
175 6
    }
176
177
    /**
178
     * @param int    $index
179
     * @param array  $data
180
     * @param float  $duration
181
     * @param string $message
182
     *
183
     * @return string
184
     */
185 6
    private function format($index, array $data, $duration, $message = '')
186
    {
187 6
        $info = [];
188 6
        foreach ($data as $key => $value) {
189 6
            $length = isset($this->maxLengths[$key]) ? '-' . $this->maxLengths[$key] : '';
190 6
            if ($this->colourProcesses) {
191 5
                $colour = $this->colours[$index % count($this->colours)];
192 5
                $valueFormat = sprintf("<options=bold;fg=%s>%{$length}s</>", $colour, $value);
193 5
            } else {
194 1
                $valueFormat = sprintf("%{$length}s", $value);
195
            }
196 6
            if (is_int($key)) {
197 1
                $info[] = $valueFormat;
198 1
            } else {
199 5
                $info[] = sprintf("<info>%s</info>: %s", $key, $valueFormat);
200
            }
201 6
        }
202 6
        $output = implode(' ', $info);
203 6
        if ($this->showDuration) {
204 5
            $output .= sprintf(' (<comment>%6.2fs</comment>)', $duration);
205 5
        }
206
207 6
        return sprintf("%s %s", $output, $this->terminal->filter($message));
208
    }
209
210
    /**
211
     * @param float $checkInterval
212
     *
213
     * @return bool true if all processes were successful
214
     */
215 6
    public function run($checkInterval = Pool::CHECK_INTERVAL)
216
    {
217 6
        return $this->processPool->run($checkInterval);
218
    }
219
}
220