Passed
Push — master ( a18808...143631 )
by Tom
04:16
created

Step::parseScript()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 6
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\File\Pipeline;
6
7
use Ktomk\Pipelines\File\Artifacts;
8
use Ktomk\Pipelines\File\Image;
9
use Ktomk\Pipelines\File\ParseException;
10
use Ktomk\Pipelines\File\Pipeline;
11
12
class Step
13
{
14
    /**
15
     * @var array
16
     */
17
    private $step;
18
19
    /**
20
     * @var int number of the step, starting at one
21
     */
22
    private $index;
23
24
    /**
25
     * @var Pipeline
26
     */
27
    private $pipeline;
28
29
    /**
30
     * @var array step environment variables
31
     *   BITBUCKET_PARALLEL_STEP - zero-based index of the current step in the group, e.g. 0, 1, 2, ...
32
     *   BITBUCKET_PARALLEL_STEP_COUNT - total number of steps in the group, e.g. 5.
33
     */
34
    private $env;
35
36
    /**
37
     * Step constructor.
38
     *
39
     * @param Pipeline $pipeline
40
     * @param int $index
41
     * @param array $step
42
     * @param array $env [optional] environment variables in array notation for the new step
43
     */
44 19
    public function __construct(Pipeline $pipeline, $index, array $step, array $env = array())
45
    {
46
        // quick validation: image name
47 19
        Image::validate($step);
48
49
        // quick validation: trigger
50 18
        $this->validateTrigger($step, (bool)$env);
51
52
        // quick validation: script + after-script
53 18
        $this->parseScript($step);
54 15
        $this->parseAfterScript($step);
55
56 15
        $this->pipeline = $pipeline;
57 15
        $this->index = $index;
58 15
        $this->step = $step;
59 15
        $this->env = $env;
60 15
    }
61
62
    /**
63
     * @throws \Ktomk\Pipelines\File\ParseException
64
     * @return null|Artifacts
65
     */
66 3
    public function getArtifacts()
67
    {
68 3
        return isset($this->step['artifacts'])
69 1
            ? new Artifacts($this->step['artifacts'])
70 3
            : null;
71
    }
72
73
    /**
74
     * @throws \Ktomk\Pipelines\File\ParseException
75
     * @return Image
76
     */
77 3
    public function getImage()
78
    {
79 3
        return isset($this->step['image'])
80 1
            ? new Image($this->step['image'])
81 3
            : $this->pipeline->getFile()->getImage();
82
    }
83
84
    /**
85
     * @return null|string
86
     */
87 3
    public function getName()
88
    {
89 3
        return isset($this->step['name'])
90 1
            ? (string)$this->step['name']
91 3
            : null;
92
    }
93
94
    /**
95
     * @return StepServices
96
     */
97 1
    public function getServices()
98
    {
99 1
        $services = isset($this->step['services']) ? $this->step['services'] : array();
100
101 1
        return new StepServices($this, $services);
102
    }
103
104
    /**
105
     * @return array|string[]
106
     */
107 2
    public function getScript()
108
    {
109 2
        return $this->step['script'];
110
    }
111
112
    /**
113
     * @return array|string[]
114
     */
115 1
    public function getAfterScript()
116
    {
117 1
        if (isset($this->step['after-script'])) {
118 1
            return $this->step['after-script'];
119
        }
120
121 1
        return array();
122
    }
123
124
    /**
125
     * @return bool
126
     */
127 1
    public function isManual()
128
    {
129 1
        if (0 === $this->index) {
130 1
            return false;
131
        }
132
133 1
        return (isset($this->step['trigger']) && 'manual' === $this->step['trigger']);
134
    }
135
136
    /**
137
     * Specify data which should be serialized to JSON
138
     *
139
     * @return array
140
     */
141 1
    public function jsonSerialize()
142
    {
143 1
        $image = $this->getImage();
144 1
        $image = null === $image ? '' : $image->jsonSerialize();
145
146
        return array(
147 1
            'name' => $this->getName(),
148 1
            'image' => $image,
149 1
            'script' => $this->getScript(),
150 1
            'artifacts' => $this->getArtifacts(),
151
        );
152
    }
153
154
    /**
155
     * @return int
156
     */
157 1
    public function getIndex()
158
    {
159 1
        return $this->index;
160
    }
161
162
    /**
163
     * @return Pipeline
164
     * @codeCoverageIgnore
165
     */
166
    public function getPipeline()
167
    {
168
        return $this->pipeline;
169
    }
170
171
    /**
172
     * @return array step container environment variables (e.g. parallel a step)
173
     */
174 1
    public function getEnv()
175
    {
176 1
        return $this->env;
177
    }
178
179
    /**
180
     *
181
     *
182
     * @param array $array
183
     * @param bool $isPrallelStep
184
     */
185 18
    private function validateTrigger(array $array, $isPrallelStep)
186
    {
187 18
        if (!array_key_exists('trigger', $array)) {
188 18
            return;
189
        }
190
191 2
        $trigger = $array['trigger'];
192 2
        if ($isPrallelStep) {
193 1
            ParseException::__("Unexpected property 'trigger' in parallel step");
194
        }
195
196 2
        if (!in_array($trigger, array('manual', 'automatic'), true)) {
197 1
            ParseException::__("'trigger' expects either 'manual' or 'automatic'");
198
        }
199 2
    }
200
201
    /**
202
     * Parse a step script section
203
     *
204
     * @param array $step
205
     *
206
     * @throws \Ktomk\Pipelines\File\ParseException
207
     */
208 18
    private function parseScript(array $step)
209
    {
210 18
        if (!isset($step['script'])) {
211 1
            ParseException::__("'step' requires a script");
212
        }
213 17
        $this->parseNamedScript('script', $step);
214 15
    }
215
216 15
    private function parseAfterScript(array $step)
217
    {
218 15
        if (isset($step['after-script'])) {
219 1
            $this->parseNamedScript('after-script', $step);
220
        }
221 15
    }
222
223
    /**
224
     * @param $script
225
     * @param mixed $name
226
     */
227 17
    private function parseNamedScript($name, array $script)
228
    {
229 17
        if (!is_array($script[$name]) || !count($script[$name])) {
230 1
            ParseException::__("'${name}' requires a list of commands");
231
        }
232
233
        foreach ($script[$name] as $index => $line) {
234
            $this->parseNamedScriptLine($name, $index, $line);
235
        }
236
    }
237
238
    private function parseNamedScriptLine($name, $index, $line)
239
    {
240 16
        $standard = is_scalar($line) || null === $line;
241 16
        $pipe = is_array($line) && isset($line['pipe']) && is_string($line['pipe']);
242
243 16
        if (!($standard || ('script' === $name && $pipe))) {
244 1
            ParseException::__(sprintf(
245 1
                "'%s' requires a list of commands, step #%d is not a command",
246
                $name,
247
                $index
248
            ));
249
        }
250 16
    }
251
}
252