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

Table   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 230
Duplicated Lines 11.3 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 33
lcom 1
cbo 5
dl 26
loc 230
ccs 107
cts 107
cp 1
rs 9.3999
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A setShowOutput() 0 5 1
A setShowSummary() 0 5 1
A __construct() 12 12 3
B updateRowKeyLengths() 14 14 5
B formatRow() 0 14 5
B add() 0 41 4
A getSummary() 0 17 3
A render() 0 9 3
B run() 0 20 6
A isShowOutput() 0 4 1
A isShowSummary() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * This file is part of graze/parallel-process.
4
 *
5
 * Copyright (c) 2017 Nature Delivered Ltd. <https://www.graze.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license https://github.com/graze/parallel-process/blob/master/LICENSE.md
11
 * @link    https://github.com/graze/parallel-process
12
 */
13
14
namespace Graze\ParallelProcess;
15
16
use Exception;
17
use Graze\DiffRenderer\DiffConsoleOutput;
18
use Graze\DiffRenderer\Terminal\TerminalInterface;
19
use Symfony\Component\Console\Output\OutputInterface;
20
use Symfony\Component\Process\Exception\ProcessFailedException;
21
use Symfony\Component\Process\Process;
22
23
class Table
24
{
25
    const SPINNER = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏";
26
27
    /** @var Pool */
28
    private $processPool;
29
    /** @var string[] */
30
    private $rows = [];
31
    /** @var Exception[] */
32
    private $exceptions;
33
    /** @var int[] */
34
    private $maxLengths = [];
35
    /** @var DiffConsoleOutput */
36
    private $output;
37
    /** @var TerminalInterface */
38
    private $terminal;
39
    /** @var bool */
40
    private $showOutput = true;
41
    /** @var bool */
42
    private $showSummary = true;
43
44
    /**
45
     * Table constructor.
46
     *
47
     * @param OutputInterface $output
48
     * @param Pool|null       $pool
49
     */
50 15 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...
51
    {
52 15
        $this->processPool = $pool ?: new Pool();
53 15
        if (!$output instanceof DiffConsoleOutput) {
54 3
            $this->output = new DiffConsoleOutput($output);
55 3
            $this->output->setTrim(true);
56 3
        } else {
57 15
            $this->output = $output;
58
        }
59 15
        $this->terminal = $this->output->getTerminal();
60 15
        $this->exceptions = [];
61 15
    }
62
63
    /**
64
     * Parses the rows to determine the key lengths to make a pretty table
65
     *
66
     * @param array $data
67
     */
68 12 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...
69
    {
70 12
        $lengths = array_map('mb_strlen', $data);
71
72 12
        $keys = array_merge(array_keys($lengths), array_keys($this->maxLengths));
73
74 12
        foreach ($keys as $key) {
75 12
            if (!isset($this->maxLengths[$key])
76 12
                || (isset($lengths[$key]) && $lengths[$key] > $this->maxLengths[$key])
77 12
            ) {
78 12
                $this->maxLengths[$key] = $lengths[$key];
79 12
            }
80 12
        }
81 12
    }
82
83
    /**
84
     * @param array  $data
85
     * @param string $status
86
     * @param float  $duration
87
     * @param string $extra
88
     *
89
     * @return string
90
     */
91 12
    private function formatRow(array $data, $status, $duration, $extra = '')
92
    {
93 12
        $info = [];
94 12
        foreach ($data as $key => $value) {
95 12
            $length = isset($this->maxLengths[$key]) ? '-' . $this->maxLengths[$key] : '';
96 12
            if (is_int($key)) {
97 1
                $info[] = sprintf("%{$length}s", $value);
98 1
            } else {
99 11
                $info[] = sprintf("<info>%s</info>: %{$length}s", $key, $value);
100
            }
101 12
        }
102 12
        $extra = $extra ? '  ' . $this->terminal->filter($extra) : '';
103 12
        return sprintf("%s (<comment>%6.2fs</comment>) %s%s", implode(' ', $info), $duration, $status, $extra);
104
    }
105
106
    /**
107
     * @param Process $process
108
     * @param array   $data
109
     */
110 12
    public function add(Process $process, array $data = [])
111
    {
112 12
        $index = count($this->rows);
113 12
        $this->rows[$index] = $this->formatRow($data, '', 0);
114 12
        $spinner = 0;
115
116 12
        if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
117
            $onProgress = function ($process, $duration, $last) use ($index, $data, &$spinner) {
118 9
                $this->rows[$index] = $this->formatRow(
119 9
                    $data,
120 9
                    mb_substr(static::SPINNER, $spinner++, 1),
121 9
                    $duration,
122 9
                    ($this->showOutput ? $last : '')
123 9
                );
124 9
                if ($spinner > mb_strlen(static::SPINNER) - 1) {
125 1
                    $spinner = 0;
126 1
                }
127 9
                $this->render();
128 9
            };
129 9
        } else {
130 3
            $onProgress = null;
131
        }
132
133 12
        $run = new Run(
134 12
            $process,
135
            function ($process, $duration, $last) use ($index, $data) {
136 10
                $this->rows[$index] = $this->formatRow($data, "<info>✓</info>", $duration, $last);
137 10
                $this->render($index);
138 12
            },
139 12
            function ($process, $duration, $last) use ($index, $data) {
140 3
                $this->rows[$index] = $this->formatRow($data, "<error>x</error>", $duration, $last);
141 3
                $this->render($index);
142 3
                $this->exceptions[] = new ProcessFailedException($process);
143 12
            },
144
            $onProgress
145 12
        );
146 12
        $run->setUpdateOnProcessOutput(false);
147 12
        $this->processPool->add($run);
148
149 12
        $this->updateRowKeyLengths($data);
150 12
    }
151
152
    /**
153
     * @return string
154
     */
155 2
    private function getSummary()
156
    {
157 2
        if ($this->processPool->hasStarted()) {
158 2
            if ($this->processPool->isRunning()) {
159 2
                return sprintf(
160 2
                    '<comment>Total</comment>: %2d, <comment>Running</comment>: %2d, <comment>Waiting</comment>: %2d',
161 2
                    $this->processPool->count(),
162 2
                    count($this->processPool->getRunning()),
163 2
                    count($this->processPool->getWaiting())
164 2
                );
165
            } else {
166 2
                return '';
167
            }
168
        } else {
169 1
            return 'waiting...';
170
        }
171
    }
172
173
    /**
174
     * Render a specific row
175
     *
176
     * @param int $row
177
     */
178 12
    private function render($row = 0)
179
    {
180 12
        if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
181 9
            $rows = ($this->showSummary ? array_merge($this->rows, [$this->getSummary()]) : $this->rows);
182 9
            $this->output->reWrite($rows, !$this->showSummary);
183 9
        } else {
184 3
            $this->output->writeln($this->rows[$row]);
185
        }
186 12
    }
187
188
    /**
189
     * @param float $checkInterval
190
     *
191
     * @return bool true if all processes were successful
192
     * @throws Exception
193
     */
194 12
    public function run($checkInterval = Pool::CHECK_INTERVAL)
195
    {
196 12
        if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
197 9
            $this->render();
198 9
        }
199 12
        $output = $this->processPool->run($checkInterval);
200 12
        if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE && $this->showSummary) {
201 2
            $this->render();
202 2
        }
203
204 12
        if (count($this->exceptions) > 0) {
205 3
            foreach ($this->exceptions as $exception) {
206 3
                $this->output->writeln($exception->getMessage());
207 3
            }
208
209 3
            throw reset($this->exceptions);
210
        }
211
212 9
        return $output;
213
    }
214
215
    /**
216
     * @return bool
217
     */
218 1
    public function isShowOutput()
219
    {
220 1
        return $this->showOutput;
221
    }
222
223
    /**
224
     * @param bool $showOutput
225
     *
226
     * @return $this
227
     */
228 11
    public function setShowOutput($showOutput)
229
    {
230 11
        $this->showOutput = $showOutput;
231 11
        return $this;
232
    }
233
234
    /**
235
     * @return bool
236
     */
237 1
    public function isShowSummary()
238
    {
239 1
        return $this->showSummary;
240
    }
241
242
    /**
243
     * @param bool $showSummary
244
     *
245
     * @return $this
246
     */
247 13
    public function setShowSummary($showSummary)
248
    {
249 13
        $this->showSummary = $showSummary;
250 13
        return $this;
251
    }
252
}
253