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