Passed
Push — test ( dfd7ea...847752 )
by Tom
02:54
created

FileShower::getShowPipeline()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 9
c 0
b 0
f 0
nc 3
nop 2
dl 0
loc 14
ccs 8
cts 8
cp 1
crap 3
rs 9.9666
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Utility;
6
7
use InvalidArgumentException;
8
use Ktomk\Pipelines\File\Definitions\Service;
9
use Ktomk\Pipelines\File\File;
10
use Ktomk\Pipelines\File\ParseException;
11
use Ktomk\Pipelines\File\Pipeline\Step;
12
use Ktomk\Pipelines\File\Pipeline\Steps;
13
use Ktomk\Pipelines\File\Pipelines;
14
15
/**
16
 * Class FileShower
17
 *
18
 * Shows information about a file
19
 *
20
 * @package Ktomk\Pipelines\Utility
21
 */
22
class FileShower
23
{
24
    /**
25
     * @var callable
26
     */
27
    private $output;
28
29
    /**
30
     * @var File
31
     */
32
    private $file;
33
34
    /**
35
     * FileInfo constructor.
36
     *
37
     * @param callable $output
38
     * @param File $file
39
     */
40 16
    public function __construct($output, File $file)
41
    {
42 16
        $this->output = $output;
43 16
        $this->file = $file;
44 16
    }
45
46
    /**
47
     * @throws InvalidArgumentException
48
     *
49
     * @return int
50
     */
51 2
    public function showImages()
52
    {
53 2
        $images = array();
54
55 2
        foreach ($this->getAllStepsWithServices($this->file) as $step) {
56 2
            $image = $step->getImage();
57 2
            $images[(string)$image] = $image;
58
        }
59
60 2
        foreach ($images as $image) {
61 2
            $this->info($image);
62
        }
63
64 2
        return 0;
65
    }
66
67
    /**
68
     * @return int
69
     */
70 1
    public function showPipelineIds()
71
    {
72 1
        $pipelines = $this->file->getPipelines();
73
74 1
        foreach ($pipelines->getPipelineIds() as $id) {
75 1
            $this->info($id);
76
        }
77
78 1
        return 0;
79
    }
80
81
    /**
82
     * shows pipeline and steps
83
     *
84
     * @return int 0 if there were no errors, 1 if there were errors
85
     */
86 2
    public function showFile()
87
    {
88 2
        $pipelines = $this->file->getPipelines();
89
90 2
        $errors = 0;
91 2
        $table = array(array('PIPELINE ID', 'STEP', 'IMAGE', 'NAME'));
92 2
        foreach ($pipelines->getPipelineIds() as $id) {
93 2
            list($pipeline, $message) = $this->getShowPipeline($pipelines, $id);
94 2
            if ($message) {
95 1
                $table[] = array($id, 'ERROR', $message, '');
96 1
                $errors++;
97
98 1
                continue;
99
            }
100
101 1
            $steps = (null === $pipeline) ? array() : $pipeline->getSteps();
102 1
            foreach ($steps as $index => $step) {
103
                /** @var Step $step */
104 1
                $name = $step->getName();
105 1
                null !== $name && $name = sprintf('"%s"', $name);
106 1
                null === $name && $name = 'no-name';
107 1
                $table[] = array($id, $index + 1, $step->getImage(), $name);
108 1
                foreach ($step->getServices()->getServiceNames() as $serviceName) {
109
                    /** @var Service $service */
110 1
                    ($service = $step->getFile()->getDefinitions()->getServices()->getByName($serviceName)) || $errors++;
111 1
                    $table[] = array($id, $index + 1, $service ? $service->getImage() : 'ERROR', 'service:' . $serviceName);
112
                }
113
            }
114
        }
115
116 2
        $this->textTable($table);
117
118 2
        return $errors ? 1 : 0;
119
    }
120
121
    /**
122
     * shows summary of the file, first pipelines then pipline services
123
     *
124
     * @return int 0 if there were no errors, 1 if there were errors
125
     */
126 5
    public function showPipelines()
127
    {
128 5
        $pipelines = $this->file->getPipelines();
129
130 5
        $errors = 0;
131 5
        $table = array(array('PIPELINE ID', 'IMAGES', 'STEPS'));
132 5
        foreach ($pipelines->getPipelineIds() as $id) {
133 5
            list($pipeline, $message) = $this->getShowPipeline($pipelines, $id);
134 5
            if ($message) {
135 3
                $table[] = array($id, 'ERROR', $message);
136 3
                $errors++;
137
138 3
                continue;
139
            }
140
141 2
            $steps = (null === $pipeline) ? null : $pipeline->getSteps();
142 2
            list($images, $names) = $this->getImagesAndNames($steps);
143
144 2
            $images = $images ? implode(', ', $images) : '';
145 2
            $steps = sprintf('%d%s', count($steps), $names ? ' ("' . implode('"; "', $names) . '")' : '');
146 2
            $table[] = array($id, $images, $steps);
147
        }
148
149 5
        $this->textTable($table);
150
151 5
        return $errors ? 1 : 0;
152
    }
153
154 5
    public function showServices()
155
    {
156 5
        $file = $this->file;
157 5
        $pipelines = $file->getPipelines();
158
159 5
        $errors = 0;
160 5
        $table = array(array('PIPELINE ID', 'STEP', 'SERVICE', 'IMAGE'));
161
162 5
        $serviceDefinitions = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $serviceDefinitions is dead and can be removed.
Loading history...
163
164
        try {
165 5
            $serviceDefinitions = $file->getDefinitions()->getServices();
166 2
        } catch (ParseException $e) {
167 2
            $table[] = array('', '', 'ERROR', $e->getParseMessage());
168 2
            $this->textTable($table);
169
170 2
            return 1;
171
        }
172
173 3
        foreach ($pipelines->getPipelineIds() as $id) {
174 3
            list($pipeline, $message) = $this->getShowPipeline($pipelines, $id);
175 3
            if ($message) {
176 1
                $table[] = array($id, '', 'ERROR', $message);
177 1
                $errors++;
178
179 1
                continue;
180
            }
181
182 2
            foreach ($pipeline->getSteps() as $step) {
183
                /** @var Step $step */
184 2
                $serviceNames = $step->getServices()->getServiceNames();
185 2
                if (!$serviceNames) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $serviceNames of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
186 1
                    continue;
187
                }
188
189 2
                $stepNo = $step->getIndex() + 1;
190
191 2
                foreach ($serviceNames as $name) {
192 2
                    if (!$serviceDefinitions || !$service = $serviceDefinitions->getByName($name)) {
193 1
                        $table[] = array($id, $stepNo, 'ERROR', sprintf('Undefined service: "%s"', $name));
194 1
                        $errors++;
195
                    } else {
196 2
                        $table[] = array($id, $stepNo, $name, $service->getImage());
197
                    }
198
                }
199
            }
200
        }
201
202 3
        $this->textTable($table);
203
204 3
        return $errors ? 1 : 0;
205
    }
206
207
    /**
208
     * @param File $file
209
     *
210
     * @return Step[]
211
     */
212 2
    private function getAllSteps(File $file)
213
    {
214 2
        $return = array();
215 2
        foreach ($file->getPipelines()->getPipelines() as $id => $pipeline) {
216 2
            foreach (Steps::fullIter($pipeline->getSteps()) as $index => $step) {
217 2
                $return["${id}:/step/${index}"] = $step;
218
            }
219
        }
220
221 2
        return $return;
222
    }
223
224
    /**
225
     * step iterator w/services
226
     *
227
     * @param File $file
228
     *
229
     * @return Service[]|Step[]
230
     */
231
    private function getAllStepsWithServices(File $file)
232
    {
233 2
        $return = array();
234
235 2
        foreach ($this->getAllSteps($file) as $key => $step) {
236 2
            $return[$key] = $step;
237 2
            foreach ($step->getServices()->getDefinitions() as $name => $service) {
238 1
                $return["${key}/service/${name}"] = $service;
239
            }
240
        }
241
242 2
        return $return;
243
    }
244
245
    /**
246
     * @param Pipelines $pipelines
247
     * @param string $id
248
     *
249
     * @return array
250
     */
251
    private function getShowPipeline(Pipelines $pipelines, $id)
252
    {
253 10
        $pipeline = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $pipeline is dead and can be removed.
Loading history...
254 10
        $message = null;
255
256
        try {
257 10
            $pipeline = $pipelines->getById($id);
258 5
        } catch (ParseException $exception) {
259 4
            $message = $exception->getParseMessage();
260 1
        } catch (InvalidArgumentException $exception) {
261 1
            $message = $exception->getMessage();
262
        }
263
264 10
        return array($pipeline, $message);
265
    }
266
267
    /**
268
     * @param array $table
269
     *
270
     * @return void
271
     */
272
    private function textTable(array $table)
273
    {
274 12
        $sizes = $this->textTableGetSizes($table);
275
276 12
        foreach ($table as $row) {
277 12
            $line = $this->textTableGetRow($row, $sizes);
278 12
            $this->info($line);
279
        }
280 12
    }
281
282
    /**
283
     * @param string $message
284
     *
285
     * @return void
286
     */
287
    private function info($message)
288
    {
289 15
        call_user_func($this->output, $message);
290 15
    }
291
292
    /**
293
     * @param Steps $steps
294
     *
295
     * @return array
296
     */
297
    private function getImagesAndNames(Steps $steps = null)
298
    {
299 2
        $images = array();
300 2
        $names = array();
301
302 2
        foreach (Steps::fullIter($steps) as $step) {
303 2
            $image = $step->getImage()->getName();
304 2
            if (File::DEFAULT_IMAGE !== $image) {
305 2
                $images[] = $image;
306
            }
307 2
            $name = $step->getName();
308 2
            (null !== $name) && $names[] = $name;
309
        }
310
311 2
        $images = array_unique($images);
312
313 2
        return array($images, $names);
314
    }
315
316
    /**
317
     * get max sizes for each column in array table
318
     *
319
     * @param array $table
320
     *
321
     * @return array|int[] sizes
322
     */
323
    private function textTableGetSizes(array $table)
324
    {
325 12
        $sizes = array();
326 12
        foreach ($table[0] as $index => $cell) {
327 12
            $sizes[$index] = 0;
328
        }
329
330 12
        foreach ($table as $row) {
331 12
            foreach ($row as $index => $column) {
332 12
                $sizes[$index] = max($sizes[$index], strlen($column));
333
            }
334
        }
335
336 12
        return $sizes;
337
    }
338
339
    /**
340
     * @param array|string[] $row
341
     * @param array|int[] $sizes
342
     *
343
     * @return string
344
     */
345
    private function textTableGetRow(array $row, array $sizes)
346
    {
347 12
        $line = '';
348 12
        foreach ($row as $index => $column) {
349 12
            $len = strlen($column);
350 12
            $index && $line .= '    ';
351 12
            $line .= $column;
352 12
            $line .= str_repeat(' ', $sizes[$index] - $len);
353
        }
354
355 12
        return $line;
356
    }
357
}
358