Passed
Push — test ( 7a5273...3e2008 )
by Tom
04:41
created

FileShower::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
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
            list($table, $errors) = $this->tableFileSteps($steps, $id, $table, $errors);
103
        }
104
105 2
        $this->textTable($table);
106
107 2
        return $errors ? 1 : 0;
108
    }
109
110
    /**
111
     * shows summary of the file, first pipelines then pipline services
112
     *
113
     * @return int 0 if there were no errors, 1 if there were errors
114
     */
115 5
    public function showPipelines()
116
    {
117 5
        $pipelines = $this->file->getPipelines();
118
119 5
        $errors = 0;
120 5
        $table = array(array('PIPELINE ID', 'IMAGES', 'STEPS'));
121 5
        foreach ($pipelines->getPipelineIds() as $id) {
122 5
            list($pipeline, $message) = $this->getShowPipeline($pipelines, $id);
123 5
            if ($message) {
124 3
                $table[] = array($id, 'ERROR', $message);
125 3
                $errors++;
126
127 3
                continue;
128
            }
129
130 2
            $steps = (null === $pipeline) ? null : $pipeline->getSteps();
131 2
            list($images, $names) = $this->getImagesAndNames($steps);
132
133 2
            $images = $images ? implode(', ', $images) : '';
134 2
            $steps = sprintf('%d%s', count($steps), $names ? ' ("' . implode('"; "', $names) . '")' : '');
135 2
            $table[] = array($id, $images, $steps);
136
        }
137
138 5
        $this->textTable($table);
139
140 5
        return $errors ? 1 : 0;
141
    }
142
143 5
    public function showServices()
144
    {
145 5
        $file = $this->file;
146 5
        $pipelines = $file->getPipelines();
147
148 5
        $errors = 0;
149 5
        $table = array(array('PIPELINE ID', 'STEP', 'SERVICE', 'IMAGE'));
150
151
        try {
152 5
            $serviceDefinitions = $file->getDefinitions()->getServices();
153 2
        } catch (ParseException $e) {
154 2
            $table[] = array('', '', 'ERROR', $e->getParseMessage());
155 2
            $this->textTable($table);
156
157 2
            return 1;
158
        }
159
160 3
        foreach ($pipelines->getPipelineIds() as $id) {
161 3
            list($pipeline, $message) = $this->getShowPipeline($pipelines, $id);
162 3
            if ($message) {
163 1
                $table[] = array($id, '', 'ERROR', $message);
164 1
                $errors++;
165
166 1
                continue;
167
            }
168
169
            list($table, $errors) =
170 2
                $this->tableStepsServices($pipeline->getSteps(), $serviceDefinitions, $id, $table, $errors);
171
        }
172
173 3
        $this->textTable($table);
174
175 3
        return $errors ? 1 : 0;
176
    }
177
178
    /**
179
     * @param Step[]|Steps $steps
180
     * @param string $id
181
     * @param array $table
182
     * @param int $errors
183
     *
184
     * @return array
185
     */
186 1
    private function tableFileSteps($steps, $id, array $table, $errors)
187
    {
188 1
        foreach ($steps as $index => $step) {
189
            /** @var Step $step */
190 1
            $name = $step->getName();
191 1
            null !== $name && $name = sprintf('"%s"', $name);
192 1
            null === $name && $name = 'no-name';
193
194 1
            $table[] = array($id, $index + 1, $step->getImage(), $name);
195 1
            list($table, $errors) = $this->tableFileStepsServices(
196 1
                $step->getServices()->getServiceNames(),
197
                $step,
198
                $id,
199 1
                $index + 1,
200
                $table,
201
                $errors
202
            );
203
        }
204
205 1
        return array($table, $errors);
206
    }
207
208
    /**
209
     * @param array|string[] $serviceNames
210
     * @param Step $step
211
     * @param string $id
212
     * @param int $stepNumber 1 based
213
     * @param array $table
214
     * @param int $errors
215
     *
216
     * @return array
217
     */
218 1
    private function tableFileStepsServices($serviceNames, Step $step, $id, $stepNumber, array $table, $errors)
219
    {
220 1
        foreach ($serviceNames as $serviceName) {
221
            /** @var Service $service */
222 1
            ($service = $step->getFile()->getDefinitions()->getServices()->getByName($serviceName)) || $errors++;
223 1
            $table[] = array($id, $stepNumber, $service ? $service->getImage() : 'ERROR', 'service:' . $serviceName);
224
        }
225
226 1
        return array($table, $errors);
227
    }
228
229 2
    private function tableStepsServices(Steps $steps, $serviceDefinitions, $id, array $table, $errors)
230
    {
231 2
        foreach ($steps as $step) {
232
            /** @var Step $step */
233 2
            $serviceNames = $step->getServices()->getServiceNames();
234 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...
235 1
                continue;
236
            }
237
238 2
            $stepNo = $step->getIndex() + 1;
239
240 2
            foreach ($serviceNames as $name) {
241 2
                if (!$service = $serviceDefinitions->getByName($name)) {
242 1
                    $table[] = array($id, $stepNo, 'ERROR', sprintf('Undefined service: "%s"', $name));
243 1
                    $errors++;
244
                } else {
245 2
                    $table[] = array($id, $stepNo, $name, $service->getImage());
246
                }
247
            }
248
        }
249
250 2
        return array($table, $errors);
251
    }
252
253
    /**
254
     * @param File $file
255
     *
256
     * @return Step[]
257
     */
258 2
    private function getAllSteps(File $file)
259
    {
260 2
        $return = array();
261 2
        foreach ($file->getPipelines()->getPipelines() as $id => $pipeline) {
262 2
            foreach (Steps::fullIter($pipeline->getSteps()) as $index => $step) {
263 2
                $return["${id}:/step/${index}"] = $step;
264
            }
265
        }
266
267 2
        return $return;
268
    }
269
270
    /**
271
     * step iterator w/services
272
     *
273
     * @param File $file
274
     *
275
     * @return Service[]|Step[]
276
     */
277
    private function getAllStepsWithServices(File $file)
278
    {
279 2
        $return = array();
280
281 2
        foreach ($this->getAllSteps($file) as $key => $step) {
282 2
            $return[$key] = $step;
283 2
            foreach ($step->getServices()->getDefinitions() as $name => $service) {
284 1
                $return["${key}/service/${name}"] = $service;
285
            }
286
        }
287
288 2
        return $return;
289
    }
290
291
    /**
292
     * @param Pipelines $pipelines
293
     * @param string $id
294
     *
295
     * @return array
296
     */
297
    private function getShowPipeline(Pipelines $pipelines, $id)
298
    {
299 10
        $pipeline = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $pipeline is dead and can be removed.
Loading history...
300 10
        $message = null;
301
302
        try {
303 10
            $pipeline = $pipelines->getById($id);
304 5
        } catch (ParseException $exception) {
305 4
            $message = $exception->getParseMessage();
306 1
        } catch (InvalidArgumentException $exception) {
307 1
            $message = $exception->getMessage();
308
        }
309
310 10
        return array($pipeline, $message);
311
    }
312
313
    /**
314
     * @param array $table
315
     *
316
     * @return void
317
     */
318
    private function textTable(array $table)
319
    {
320 12
        $sizes = $this->textTableGetSizes($table);
321
322 12
        foreach ($table as $row) {
323 12
            $line = $this->textTableGetRow($row, $sizes);
324 12
            $this->info($line);
325
        }
326 12
    }
327
328
    /**
329
     * @param string $message
330
     *
331
     * @return void
332
     */
333
    private function info($message)
334
    {
335 15
        call_user_func($this->output, $message);
336 15
    }
337
338
    /**
339
     * @param Steps $steps
340
     *
341
     * @return array
342
     */
343
    private function getImagesAndNames(Steps $steps = null)
344
    {
345 2
        $images = array();
346 2
        $names = array();
347
348 2
        foreach (Steps::fullIter($steps) as $step) {
349 2
            $image = $step->getImage()->getName();
350 2
            if (File::DEFAULT_IMAGE !== $image) {
351 2
                $images[] = $image;
352
            }
353 2
            $name = $step->getName();
354 2
            (null !== $name) && $names[] = $name;
355
        }
356
357 2
        $images = array_unique($images);
358
359 2
        return array($images, $names);
360
    }
361
362
    /**
363
     * get max sizes for each column in array table
364
     *
365
     * @param array $table
366
     *
367
     * @return array|int[] sizes
368
     */
369
    private function textTableGetSizes(array $table)
370
    {
371 12
        $sizes = array();
372 12
        foreach ($table[0] as $index => $cell) {
373 12
            $sizes[$index] = 0;
374
        }
375
376 12
        foreach ($table as $row) {
377 12
            foreach ($row as $index => $column) {
378 12
                $sizes[$index] = max($sizes[$index], strlen($column));
379
            }
380
        }
381
382 12
        return $sizes;
383
    }
384
385
    /**
386
     * @param array|string[] $row
387
     * @param array|int[] $sizes
388
     *
389
     * @return string
390
     */
391
    private function textTableGetRow(array $row, array $sizes)
392
    {
393 12
        $line = '';
394 12
        foreach ($row as $index => $column) {
395 12
            $len = strlen($column);
396 12
            $index && $line .= '    ';
397 12
            $line .= $column;
398 12
            $line .= str_repeat(' ', $sizes[$index] - $len);
399
        }
400
401 12
        return $line;
402
    }
403
}
404