Completed
Push — master ( 3e3b0a...f0448f )
by Julien
05:46 queued 03:36
created

Utils::runAndGetProcess()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 4
nop 2
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace TheAentMachine\AentDockerCompose\Command;
4
5
use Symfony\Component\Console\Output\OutputInterface;
6
use Symfony\Component\Process\Process;
7
8
class Utils
9
{
10
    /**
11
     * Delete all key/value pairs with empty value by recursively using array_filter
12
     * @param array $input
13
     * @return mixed[] array
14
     */
15
    public static function arrayFilterRec(array $input): array
16
    {
17
        foreach ($input as &$value) {
18
            if (is_array($value)) {
19
                $value = Utils::arrayFilterRec($value);
20
            }
21
        }
22
        return array_filter($input);
23
    }
24
25
    /**
26
     * @param string $payload
27
     * @return mixed[] array
28
     */
29
    public static function parsePayload(string $payload, OutputInterface $output): array
30
    {
31
        $p = json_decode($payload, true);
32
        if (!$p) {
33
            $output->writeln("   ⨯ payload error: invalid payload");
34
            exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
35
        }
36
37
        $serviceName = $p[Cst::SERVICE_NAME_KEY] ?? "";
38
        if (empty($serviceName)) {
39
            $output->writeln("   ⨯ payload error: empty " . Cst::SERVICE_NAME_KEY);
40
            exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
41
        }
42
43
        $service = $p['service'] ?? array();
44
        if (!empty($service)) {
45
            $image = $service['image'] ?? "";
46
            $dependsOn = $service['dependsOn'] ?? "";
47
48
            $ports = array();
49
            foreach ($service['ports'] ?? array() as $port) {
50
                $str = sprintf("%d:%d", $port['source'], $port['target']);
51
                $ports[] = $str;
52
            }
53
            $labels = array();
54
            foreach ($service['labels'] ?? array() as $label) {
55
                $str = $label['value'] ? sprintf("%s=%s", $label['key'], $label['value']) : $label['key'];
56
                $labels[] = $str;
57
            }
58
            $environments = array();
59
            foreach ($service['environments'] ?? array() as $env) {
60
                $str = $env['value'] ? sprintf("%s=%s", $env['key'], $env['value']) : $env['key'];
61
                $environments[] = $str;
62
            }
63
64
            $volumes = $p['volumes'] ?? array();
65
            $namedVolumes = array();
66
            foreach ($service['volumes'] ?? array() as $volume) {
67
                $type = $volume['type'] ?? "";
68
                $source = $volume['source'] ?? "";
69
70
                $formattedVolume = array(
71
                    "type" => $type,
72
                    "source" => $source,
73
                    "target" => $volume['target'] ?? "",
74
                    "read_only" => $volume['readOnly'] ?? "",
75
                );
76
                $volumes[] = $formattedVolume;
77
78
                // case it's a named volume
79
                if ($type === "volume") {
80
                    // for now we just add them without any option
81
                    $namedVolumes[$source] = null;
82
                }
83
            }
84
85
            $formattedPayload = array(
86
                "services" => Utils::arrayFilterRec(array(
87
                    $serviceName => array(
88
                        "image" => $image,
89
                        "depends_on" => $dependsOn,
90
                        "ports" => $ports,
91
                        "labels" => $labels,
92
                        "environments" => $environments,
93
                        "volumes" => $volumes,
94
                    ),
95
                )),
96
            );
97
            if (!empty($namedVolumes)) {
98
                $formattedPayload['volumes'] = $namedVolumes;
99
            }
100
101
            return $formattedPayload;
102
        } else {
103
            $output->writeln("  ⨯ payload error: empty " . Cst::SERVICE_KEY);
104
            exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
105
        }
106
107
        exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
Unused Code introduced by
ExitNode is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
108
    }
109
110
    /**
111
     * Run a process and return the exit code
112
     * @param mixed $cmd command line in a single string or an array of strings
113
     * @param OutputInterface $output
114
     * @return Process
115
     */
116
    public static function runAndGetProcess($cmd, OutputInterface $output): Process
117
    {
118
        if (!is_array($cmd)) {
119
            $cmd = explode(' ', $cmd);
120
        }
121
122
        $process = new Process($cmd);
123
124
        $process->start();
125
        foreach ($process as $type => $buffer) {
126
            $output->write($buffer);
127
        }
128
129
        return $process;
130
    }
131
}
132