Passed
Pull Request — master (#11)
by
unknown
02:44
created

NewDockerServiceInfoEventCommand::arrayFilterRec()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace TheAentMachine\AentDockerCompose\Command;
4
5
use Symfony\Component\Console\Question\ChoiceQuestion;
6
use Symfony\Component\Yaml\Yaml;
7
use TheAentMachine\AentDockerCompose\Aenthill\Enum\EventEnum;
8
use TheAentMachine\AentDockerCompose\DockerCompose\DockerComposeService;
9
use TheAentMachine\AentDockerCompose\YamlTools\YamlTools;
10
use TheAentMachine\Hercule;
11
use TheAentMachine\JsonEventCommand;
12
use TheAentMachine\Service\Enum\VolumeTypeEnum;
13
use TheAentMachine\Service\Service;
14
15
class NewDockerServiceInfoEventCommand extends JsonEventCommand
16
{
17
18
    protected function getEventName(): string
19
    {
20
        return EventEnum::NEW_DOCKER_SERVICE_INFO;
21
    }
22
23
    protected function executeJsonEvent(array $payload): void
24
    {
25
        Hercule::setHandledEvents(EventEnum::getHandledEvents());
26
27
        $service = Service::parsePayload($payload);
28
        $formattedPayload = $this->dockerComposeServiceSerialize($service);
29
30
        // $this->log->debug(json_encode($formattedPayload, JSON_PRETTY_PRINT));
31
32
        $yml = Yaml::dump($formattedPayload, 256, 4, Yaml::DUMP_OBJECT_AS_MAP);
33
        file_put_contents(YamlTools::TMP_YAML_FILE, $yml);
34
35
        $dockerComposeService = new DockerComposeService($this->log);
36
        $dockerComposeFilePathnames = $dockerComposeService->getDockerComposePathnames();
37
        if (count($dockerComposeFilePathnames) === 1) {
38
            $toMerge = $dockerComposeFilePathnames;
39
        } else {
40
            $helper = $this->getHelper('question');
41
            $question = new ChoiceQuestion(
42
                'Please choose the docker-compose file(s) in which the service will be added (e.g. 0,1) : ',
43
                $dockerComposeFilePathnames,
44
                null
45
            );
46
            $question->setMultiselect(true);
47
48
            $toMerge = $helper->ask($this->input, $this->output, $question);
49
        }
50
51
        foreach ($toMerge as $file) {
52
            YamlTools::merge($file, YamlTools::TMP_YAML_FILE, $file);
53
        }
54
55
        unlink(YamlTools::TMP_YAML_FILE);
56
    }
57
58
    /**
59
     * @param Service $service
60
     * @return mixed[]
61
     */
62
    public function dockerComposeServiceSerialize(Service $service): array
63
    {
64
        $portMap = function (array $port): string {
65
            return $port['source'] . ':' . $port['target'];
66
        };
67
        $labelMap = function (string $key, array $label): string {
68
            return $key . '=' . $label['value'];
69
        };
70
        $envMap = function (string $key, array $env): string {
71
            return $key . '=' . $env['value'];
72
        };
73
        $jsonSerializeMap = function (\JsonSerializable $obj): array {
74
            return $obj->jsonSerialize();
75
        };
76
        $dockerService = array(
77
            'services' => self::arrayFilterRec(array(
78
                $service->getServiceName() => [
79
                    'image' => $service->getImage(),
80
                    'depends_on' => $service->getDependsOn(),
81
                    'ports' => array_map($portMap, $service->getPorts()),
82
                    'labels' => array_map($labelMap, $service->getLabels()),
83
                    'environment' => array_map($envMap, $service->getEnvironment()),
84
                    'volumes' => array_map($jsonSerializeMap, $service->getVolumes()),
85
                ],
86
            )),
87
        );
88
        $namedVolumes = array();
89
        foreach ($dockerService['services']['volumes'] as $volume) {
90
            if ($volume['type'] === VolumeTypeEnum::NAMED_VOLUME) {
91
                // for now we just add them without any option
92
                $namedVolumes[$volume['source']] = null;
93
            }
94
        }
95
        if (!empty($namedVolumes)) {
96
            $dockerService['volumes'] = $namedVolumes;
97
        }
98
        return $dockerService;
99
    }
100
101
    /**
102
     * Delete all key/value pairs with empty value by recursively using array_filter
103
     * @param array $input
104
     * @return mixed[] array
105
     */
106
    private static function arrayFilterRec(array $input): array
107
    {
108
        foreach ($input as &$value) {
109
            if (\is_array($value)) {
110
                $value = self::arrayFilterRec($value);
111
            }
112
        }
113
        return array_filter($input);
114
    }
115
}
116