Passed
Push — test ( 617f92...ce6411 )
by Tom
08:38
created

DockerOptions::runClean()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 8
c 0
b 0
f 0
nc 3
nop 4
dl 0
loc 14
ccs 7
cts 7
cp 1
crap 4
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\Cli\Args;
9
use Ktomk\Pipelines\Cli\Docker\ProcessManager;
10
use Ktomk\Pipelines\Cli\Exec;
11
use Ktomk\Pipelines\Cli\Streams;
12
use Ktomk\Pipelines\Value\Prefix;
13
use RuntimeException;
14
15
/**
16
 * docker specific options of the pipelines utility
17
 *
18
 * --docker-list
19
 * --docker-kill
20
 * --docker-clean
21
 * --docker-zap
22
 *
23
 * @package Ktomk\Pipelines\Utility
24
 */
25
class DockerOptions
26
{
27
    /**
28
     * @var Streams
29
     */
30
    private $streams;
31
32
    /**
33
     * @var Args
34
     */
35
    private $args;
36
37
    /**
38
     * @var Exec
39
     */
40
    private $exec;
41
42
    /**
43
     * @var string
44
     */
45
    private $prefix;
46
47
    /**
48
     * @var ProcessManager
49
     */
50
    private $ps;
51
52
    /**
53
     * @param Args $args
54
     * @param Exec $exec
55
     * @param string $prefix
56
     * @param Streams $streams
57
     *
58
     * @return DockerOptions
59
     */
60 1
    public static function bind(Args $args, Exec $exec, $prefix, Streams $streams)
61
    {
62 1
        return new self($args, $exec, $prefix, $streams, new ProcessManager($exec));
63
    }
64
65
    /**
66
     * DockerOptions constructor.
67
     *
68
     * @param Args $args
69
     * @param Exec $exec
70
     * @param string $prefix
71
     * @param Streams $streams
72
     * @param ProcessManager $ps
73
     */
74 5
    public function __construct(Args $args, Exec $exec, $prefix, Streams $streams, ProcessManager $ps)
75
    {
76 5
        $this->args = $args;
77 5
        $this->exec = $exec;
78 5
        $this->prefix = Prefix::verify($prefix);
79 5
        $this->streams = $streams;
80 5
        $this->ps = $ps;
81 5
    }
82
83
    /**
84
     * Process docker related options
85
     *
86
     * --docker-list  - list containers
87
     * --docker-kill  - kill (running) containers
88
     * --docker-clean - remove (stopped) containers
89
     *
90
     * @throws InvalidArgumentException
91
     * @throws RuntimeException
92
     * @throws StatusException
93
     *
94
     * @return void
95
     */
96 4
    public function run()
97
    {
98 4
        $this->parse($this->args, $this->prefix);
99 1
    }
100
101
    /**
102
     * @param Args $args
103
     * @param string $prefix
104
     *
105
     * @throws StatusException
106
     *
107
     * @return void
108
     */
109 4
    private function parse(Args $args, $prefix)
110
    {
111 4
        $count = 0;
112 4
        $status = 0;
113
114 4
        if ($args->hasOption('docker-list')) {
115 2
            $count++;
116 2
            $status = $this->runPs();
117
        }
118
119 4
        $hasKill = $args->hasOption('docker-kill');
120 4
        $hasClean = $args->hasOption('docker-clean');
121 4
        if ($args->hasOption('docker-zap')) {
122 1
            $hasKill = $hasClean = true;
123
        }
124
125 4
        $ids = $this->runGetIds($count, $hasClean || $hasKill, $prefix);
126
127 4
        $status = $this->runKill($status, $count, $hasKill, $prefix);
128
129 4
        $status = $this->runClean($status, $count, $hasClean, $ids);
130
131 4
        if ($count) {
132 3
            throw new StatusException('', $status);
133
        }
134 1
    }
135
136
    /**
137
     * @param string $message
138
     *
139
     * @return void
140
     */
141 2
    private function info($message)
142
    {
143 2
        $this->streams->out(
144 2
            sprintf("%s\n", $message)
145
        );
146 2
    }
147
148
    /**
149
     * @return int
150
     */
151 2
    private function runPs()
152
    {
153 2
        $prefix = $this->prefix;
154
155 2
        return $this->exec->pass(
156 2
            'docker ps -a',
157
            array(
158 2
                '--filter',
159 2
                "name=^/${prefix}[-.]",
160
            )
161
        );
162
    }
163
164
    /**
165
     * @param int $count
166
     * @param bool $flag
167
     * @param string $prefix
168
     *
169
     * @return null|array
170
     */
171
    private function runGetIds(&$count, $flag, $prefix)
172
    {
173 4
        if (!$flag) {
174 1
            return null;
175
        }
176
177 3
        $count++;
178
179 3
        return $this->ps->findAllContainerIdsByNamePrefix($prefix);
180
    }
181
182
    /**
183
     * @param int $status
184
     * @param int $count
185
     * @param bool $hasKill
186
     * @param string $prefix
187
     *
188
     * @return int
189
     */
190
    private function runKill($status, &$count, $hasKill, $prefix)
191
    {
192 4
        if ($status || !$hasKill) {
193 1
            return $status;
194
        }
195
196 3
        if (!$status && $hasKill) {
197 3
            $count++;
198 3
            $running = $this->ps->findRunningContainerIdsByNamePrefix($prefix);
199 3
            if ($running) {
200 1
                $status = $this->ps->kill($running);
201
            } else {
202 2
                $this->info('no containers to kill');
203
            }
204
        }
205
206 3
        return $status;
207
    }
208
209
    /**
210
     * @param int $status
211
     * @param int $count
212
     * @param bool $hasClean
213
     * @param array $ids
214
     *
215
     * @return int
216
     */
217
    private function runClean($status, &$count, $hasClean, array $ids = null)
218
    {
219 4
        if ($status || !$hasClean) {
220 1
            return $status;
221
        }
222
223 3
        $count++;
224 3
        if ($ids) {
225 1
            $status = $this->ps->remove($ids);
226
        } else {
227 2
            $this->info('no containers to remove');
228
        }
229
230 3
        return $status;
231
    }
232
}
233