Passed
Push — test ( 503f62...9918b9 )
by Tom
03:27
created

FileShower::annotate()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 1
nop 3
dl 0
loc 9
ccs 6
cts 6
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Utility\Show;
6
7
use InvalidArgumentException;
8
use Ktomk\Pipelines\File\Definitions\Service;
9
use Ktomk\Pipelines\File\Definitions\Services;
10
use Ktomk\Pipelines\File\File;
11
use Ktomk\Pipelines\File\ParseException;
12
use Ktomk\Pipelines\File\Pipeline\Step;
13
use Ktomk\Pipelines\File\Pipeline\Steps;
14
15
/**
16
 * Class FileShower
17
 *
18
 * Shows information about a file
19
 *
20
 * @package Ktomk\Pipelines\Utility
21
 */
22
class FileShower extends FileShowerAbstract
23
{
24
    const NO_NAME = 'no-name';
25
    const CHAR_MANUAL = 'M';
26
27
    /**
28
     * @throws InvalidArgumentException
29
     *
30
     * @return int
31
     */
32 2
    public function showImages()
33
    {
34 2
        $images = array();
35
36 2
        foreach ($this->getAllStepsWithServices($this->file) as $step) {
37 2
            $image = $step->getImage();
38 2
            $images[(string)$image] = $image;
39
        }
40
41 2
        foreach ($images as $image) {
42 2
            $this->info((string)$image);
43
        }
44
45 2
        return 0;
46
    }
47
48
    /**
49
     * @return int
50
     */
51 1
    public function showPipelineIds()
52
    {
53 1
        $pipelines = $this->file->getPipelines();
54
55 1
        foreach ($pipelines->getPipelineIds() as $id) {
56 1
            $this->info($id);
57
        }
58
59 1
        return 0;
60
    }
61
62
    /**
63
     * shows pipeline and steps
64
     *
65
     * @return int 0 if there were no errors, 1 if there were errors
66
     */
67 6
    public function showFile()
68
    {
69 6
        $pipelines = $this->file->getPipelines();
70
71 6
        $table = new FileTable(array('PIPELINE ID', 'STEP', 'IMAGE', 'NAME'));
72
73 6
        foreach ($this->tablePipelineIdsPipelines($pipelines, $table) as $id => $pipeline) {
74 5
            $steps = (null === $pipeline) ? array() : $pipeline->getSteps();
75 5
            $this->tableFileSteps($steps, $id, $table);
76
        }
77
78 5
        return $this->outputTableAndReturn($table);
79
    }
80
81
    /**
82
     * shows summary of the file, first pipelines then pipeline services
83
     *
84
     * @return int 0 if there were no errors, 1 if there were errors
85
     */
86 7
    public function showPipelines()
87
    {
88 7
        $pipelines = $this->file->getPipelines();
89
90 7
        $table = new FileTable(array('PIPELINE ID', 'IMAGES', 'STEPS'));
91
92 7
        foreach ($this->tablePipelineIdsPipelines($pipelines, $table) as $id => $pipeline) {
93 4
            $steps = (null === $pipeline) ? null : $pipeline->getSteps();
94 4
            list($images, $names, $annotations) = $this->getImagesNamesAndAnnotations($steps);
95
96 4
            $images = $images ? implode(', ', $images) : '';
97 4
            $steps = sprintf(
98 4
                '%d%s',
99 4
                count($steps),
0 ignored issues
show
Bug introduced by
It seems like $steps can also be of type null; however, parameter $value of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

99
                count(/** @scrutinizer ignore-type */ $steps),
Loading history...
100 4
                $names ? ' (' . implode('; ', $this->annotate($names, ' *', $annotations)) . ')' : ''
101
            );
102 4
            $table->addRow(array($id, $images, $steps));
103
        }
104
105 7
        return $this->outputTableAndReturn($table);
106
    }
107
108
    /**
109
     * @return int
110
     */
111 5
    public function showServices()
112
    {
113 5
        $file = $this->file;
114
115 5
        $table = new FileTable(array('PIPELINE ID', 'STEP', 'SERVICE', 'IMAGE'));
116
117
        try {
118 5
            $serviceDefinitions = $file->getDefinitions()->getServices();
119 3
            foreach ($this->tablePipelineIdsPipelines($file->getPipelines(), $table) as $id => $pipeline) {
120 2
                $this->tableStepsServices($pipeline->getSteps(), $serviceDefinitions, $id, $table);
121
            }
122 2
        } catch (ParseException $e) {
123 2
            $table->addErrorRow(array('', '', 'ERROR', $e->getParseMessage()));
124
        }
125
126 5
        return $this->outputTableAndReturn($table);
127
    }
128
129
    /**
130
     * @param array<string> $names
131
     * @param string $annotator
132
     * @param array<string> $annotations
133
     *
134
     * @return array|string[]
135
     */
136 9
    private function annotate(array $names, $annotator, array $annotations)
137
    {
138 9
        return array_map(function ($name, $annotations) use ($annotator) {
139 9
            if ($annotations) {
140 4
                $name .= $annotator . implode('', $annotations);
141
            }
142
143 9
            return $name;
144 9
        }, $names, $annotations);
145
    }
146
147
    /**
148
     * @param Step[]|Steps $steps
149
     * @param string $id
150
     * @param FileTable $table
151
     *
152
     * @return void
153
     */
154 5
    private function tableFileSteps($steps, $id, FileTable $table)
155
    {
156 5
        foreach ($steps::fullIter($steps) as $index => $step) {
157 5
            $stepNumber = (int)$index + 1;
158 5
            $name = $step->getName();
159 5
            $name = null === $name ? self::NO_NAME : sprintf('"%s"', $name);
160
161 5
            $stepNumberAnnotated = $this->annotate(
162 5
                array((string)$stepNumber),
163 5
                ' *',
164 5
                array($this->stepAnnotation($step))
165
            );
166
167 5
            $table->addRow(array($id, $stepNumberAnnotated[0], $step->getImage(), $name));
168 5
            $this->tableFileStepsCaches($step, $id, $stepNumber, $table);
169 4
            $this->tableFileStepsServices($step, $id, $stepNumber, $table);
170
        }
171 4
    }
172
173
    /**
174
     * @param Step $step
175
     * @param string $id
176
     * @param int $stepNumber 1 based
177
     * @param FileTable $table
178
     *
179
     * @return void
180
     */
181 5
    private function tableFileStepsCaches(Step $step, $id, $stepNumber, FileTable $table)
182
    {
183 5
        $caches = $step->getCaches();
184 4
        $cacheDefinitions = $step->getFile()->getDefinitions()->getCaches();
185
186 4
        foreach ($caches->getNames() as $cacheName) {
187 2
            $cacheLabel = 'cache: ' . $cacheName;
188 2
            $definition = $cacheDefinitions->getByName($cacheName);
189 2
            $cacheDescription = true === $definition ? '*internal*' : $definition;
190 2
            $table->addRow(array($id, $stepNumber, $cacheLabel, $cacheDescription));
191
        }
192 4
    }
193
194
    /**
195
     * @param Step $step
196
     * @param string $id
197
     * @param int $stepNumber 1 based
198
     * @param FileTable $table
199
     *
200
     * @return void
201
     */
202 4
    private function tableFileStepsServices(Step $step, $id, $stepNumber, FileTable $table)
203
    {
204 4
        foreach ($step->getServices()->getServiceNames() as $serviceName) {
205
            /** @var Service $service */
206 1
            $service = $step->getFile()->getDefinitions()->getServices()->getByName($serviceName);
207 1
            $table->addFlaggedRow(
208 1
                $service,
209 1
                array($id, $stepNumber, $service ? $service->getImage() : 'ERROR', 'service:' . $serviceName)
210
            );
211
        }
212 4
    }
213
214
    /**
215
     * @param Steps $steps
216
     * @param Services $serviceDefinitions
217
     * @param string $id
218
     * @param FileTable $table
219
     *
220
     * @return void
221
     */
222 2
    private function tableStepsServices(Steps $steps, Services $serviceDefinitions, $id, FileTable $table)
223
    {
224 2
        foreach ($steps as $step) {
225 2
            $serviceNames = $step->getServices()->getServiceNames();
226 2
            if (empty($serviceNames)) {
227 1
                continue;
228
            }
229
230 2
            $stepNo = $step->getIndex() + 1;
231
232 2
            foreach ($serviceNames as $name) {
233 2
                if ($service = $serviceDefinitions->getByName($name)) {
234 2
                    $table->addRow(array($id, $stepNo, $name, $service->getImage()));
235
                } else {
236 1
                    $table->addErrorRow(array($id, $stepNo, 'ERROR', sprintf('Undefined service: "%s"', $name)));
237
                }
238
            }
239
        }
240 2
    }
241
242
    /**
243
     * @param File $file
244
     *
245
     * @return Step[]
246
     */
247 2
    private function getAllSteps(File $file)
248
    {
249 2
        $return = array();
250 2
        foreach ($file->getPipelines()->getPipelines() as $id => $pipeline) {
251 2
            foreach (Steps::fullIter($pipeline->getSteps()) as $index => $step) {
252 2
                $return["${id}:/step/${index}"] = $step;
253
            }
254
        }
255
256 2
        return $return;
257
    }
258
259
    /**
260
     * step iterator w/services
261
     *
262
     * @param File $file
263
     *
264
     * @return Service[]|Step[]
265
     */
266 2
    private function getAllStepsWithServices(File $file)
267
    {
268 2
        $return = array();
269
270 2
        foreach ($this->getAllSteps($file) as $key => $step) {
271 2
            $return[$key] = $step;
272 2
            foreach ($step->getServices()->getDefinitions() as $name => $service) {
273 1
                $return["${key}/service/${name}"] = $service;
274
            }
275
        }
276
277 2
        return $return;
278
    }
279
280
    /**
281
     * @param Steps $steps
282
     *
283
     * @return array
284
     */
285 4
    private function getImagesNamesAndAnnotations(Steps $steps = null)
286
    {
287 4
        $images = array();
288 4
        $names = array();
289 4
        $annotations = array();
290
291 4
        foreach (Steps::fullIter($steps) as $step) {
292 4
            $image = $step->getImage()->getName();
293 4
            if (File::DEFAULT_IMAGE !== $image) {
294 4
                $images[] = $image;
295
            }
296 4
            $names[] = $this->stepName($step);
297 4
            $annotations[] = $this->stepAnnotation($step);
298
        }
299
300 4
        $images = array_unique($images);
301
302 4
        return array($images, $names, $annotations);
303
    }
304
305
    /**
306
     * @param Step $step
307
     *
308
     * @return string
309
     */
310 4
    private function stepName(Step $step)
311
    {
312 4
        $name = $step->getName();
313
314 4
        return null === $name ? self::NO_NAME : sprintf('"%s"', $name);
315
    }
316
317
    /**
318
     * @param Step $step
319
     *
320
     * @return array
321
     */
322 9
    private function stepAnnotation(Step $step)
323
    {
324 9
        $annotations = array();
325
326 9
        $step->isManual() && $annotations[] = self::CHAR_MANUAL;
327
328 9
        return $annotations;
329
    }
330
}
331