Passed
Push — test ( 0c059e...cfabb2 )
by Tom
02:51
created

RunnerOptions::parseDockerClientListPackages()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 9
ccs 4
cts 4
cp 1
crap 2
rs 10
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Utility;
6
7
use Ktomk\Pipelines\Cli\Args;
8
use Ktomk\Pipelines\Cli\ArgsException;
9
use Ktomk\Pipelines\Cli\Exec;
10
use Ktomk\Pipelines\Cli\Streams;
11
use Ktomk\Pipelines\Lib;
12
use Ktomk\Pipelines\Runner\Directories;
13
use Ktomk\Pipelines\Runner\Docker\Binary\Repository;
14
use Ktomk\Pipelines\Runner\RunOpts;
15
16
/**
17
 * aggregated args parser for RunOpts / runner options
18
 *
19
 * @package Ktomk\Pipelines\Utility\Args
20
 */
21
class RunnerOptions
22
{
23
    /**
24
     * @var Args
25
     */
26
    private $args;
27
    /**
28
     * @var Streams
29
     */
30
    private $streams;
31
32
    /**
33
     * @param Args $args
34
     * @param Streams $streams
35
     *
36
     * @return RunnerOptions
37
     */
38 4
    public static function bind(Args $args, Streams $streams)
39
    {
40 4
        return new self($args, $streams);
41
    }
42
43
    /**
44
     * the repository used for listing and validation
45
     *
46
     * @return Repository
47
     */
48 3
    public static function createRepository()
49
    {
50 3
        return Repository::create(
51 3
            new Exec(),
52 3
            new Directories(Lib::env($_SERVER), 'fake')
53
        );
54
    }
55
56
    /**
57
     * list all statically available docker client package names
58
     * that ship w/ pipelines
59
     *
60
     * @param Streams $streams
61
     *
62
     * @return void
63
     */
64 1
    public static function listPackages(Streams $streams)
65
    {
66 1
        $list = self::createRepository()->listPackages();
67
68 1
        $streams->out(implode("\n", $list));
69 1
        $streams->out("\n");
70 1
    }
71
72
    /**
73
     * RunnerOptions constructor,
74
     *
75
     * @param Args $args
76
     * @param Streams $streams
77
     */
78 4
    public function __construct(Args $args, Streams $streams)
79
    {
80 4
        $this->args = $args;
81 4
        $this->streams = $streams;
82 4
    }
83
84
    /**
85
     * @throws ArgsException
86
     * @throws StatusException
87
     *
88
     * @return RunOpts
89
     */
90 4
    public function run()
91
    {
92 4
        $runOpts = RunOpts::create();
93 4
        $this->parse($this->args, $runOpts);
94
95 1
        return $runOpts;
96
    }
97
98
    /**
99
     * Parse keep arguments
100
     *
101
     * @param Args $args
102
     * @param RunOpts $runOpts
103
     *
104
     * @throws ArgsException
105
     * @throws StatusException
106
     *
107
     * @return void
108
     */
109 4
    public function parse(Args $args, RunOpts $runOpts)
110
    {
111 4
        $runOpts->setPrefix($this->parsePrefix($args));
112
113 3
        $runOpts->setBinaryPackage($this->parseDockerClient($args));
114
115 2
        $this->parseDockerClientListPackages($args);
116
117 1
        $runOpts->setSteps($args->getOptionArgument(array('step', 'steps')));
118
119 1
        $runOpts->setNoManual($args->hasOption('no-manual'));
120 1
    }
121
122
    /**
123
     * @param Args $args
124
     *
125
     * @throws ArgsException
126
     *
127
     * @return string
128
     */
129 3
    private function parseDockerClient(Args $args)
130
    {
131 3
        $default = Repository::PKG_INTEGRATE;
132 3
        $binaryClient = $args->getStringOptionArgument('docker-client', $default);
133 3
        if ($binaryClient !== $default) {
134 2
            $repository = self::createRepository();
135
136
            try {
137 2
                $repository->resolve($binaryClient);
138 1
            } catch (\InvalidArgumentException $ex) {
139 1
                $message = "--docker-client needs a valid package name, file or docker client binary path; '${binaryClient}' given";
140 1
                $message .= "\n  docker client binary packages shipping w/ pipelines:";
141 1
                $message .= "\n    - " . implode("\n    - ", $repository->listPackages());
142
143 1
                throw new ArgsException($message);
144
            }
145
        }
146
147
        return $binaryClient;
148
    }
149
150
    /**
151
     * @param Args $args
152
     *
153
     * @throws StatusException
154
     *
155
     * @return void
156
     */
157
    private function parseDockerClientListPackages(Args $args)
158
    {
159 2
        if (!$args->hasOption('docker-client-pkgs')) {
160 1
            return;
161
        }
162
163 1
        self::listPackages($this->streams);
164
165 1
        throw new StatusException('', 0);
166
    }
167
168
    /**
169
     * @param Args $args
170
     *
171
     * @throws ArgsException
172
     *
173
     * @return string
174
     */
175
    private function parsePrefix(Args $args)
176
    {
177 4
        $prefix = $args->getStringOptionArgument('prefix', App::UTILITY_NAME);
178 4
        if (!preg_match('~^[a-z]{3,}$~', $prefix)) {
179 1
            throw new ArgsException(sprintf("invalid prefix: '%s'", $prefix));
180
        }
181
182 3
        return $prefix;
183
    }
184
}
185