Passed
Push — test ( 2956c8...b121f6 )
by Tom
03:07
created

Step::getEnv()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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