Passed
Push — test ( c1378c...0ec91e )
by Tom
04:31
created

Pipelines::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\File;
6
7
use Ktomk\Pipelines\Runner\Reference;
8
9
/**
10
 * Class Pipelines
11
 *
12
 * @package Ktomk\Pipelines\File
13
 */
14
class Pipelines
15
{
16
    /**
17
     * @var null|File
18
     */
19
    protected $file;
20
21
    /**
22
     * @var array
23
     */
24
    protected $references;
25
26
    /**
27
     * @var array
28
     */
29
    protected $array;
30
31
    /**
32
     * Pipelines constructor.
33
     *
34
     * @param array $array
35
     * @param null|File $file
36
     */
37 18
    public function __construct(array $array, File $file = null)
38
    {
39 18
        $this->file = $file;
40
41 18
        $this->references = $this->parsePipelineReferences($array);
42
43 14
        $this->array = $array;
44 14
    }
45
46
    /**
47
     * @return null|Pipeline
48
     */
49 2
    public function getDefault()
50
    {
51 2
        return PipelinesReferences::byId($this, 'default');
52
    }
53
54
    /**
55
     * returns the id of the default pipeline in file or null if there is none
56
     *
57
     * @return null|string
58
     */
59 2
    public function getIdDefault()
60
    {
61 2
        return PipelinesReferences::idDefault($this);
62
    }
63
64
    /**
65
     * @return array
66
     */
67 3
    public function getPipelineIds()
68
    {
69 3
        return array_keys($this->references);
70
    }
71
72
    /**
73
     * @param string $id
74
     *
75
     * @throws \InvalidArgumentException
76
     * @throws ParseException
77
     *
78
     * @return null|Pipeline
79
     */
80 8
    public function getById($id)
81
    {
82 8
        return PipelinesReferences::byId($this, $id);
83
    }
84
85
    /**
86
     * get id of a pipeline
87
     *
88
     * @param Pipeline $pipeline
89
     *
90
     * @return null|string
91
     */
92 2
    public function getId(Pipeline $pipeline)
93
    {
94 2
        return PipelinesReferences::id($this, $pipeline);
95
    }
96
97
    /**
98
     * Searches a reference
99
     *
100
     * @param Reference $reference
101
     *
102
     * @throws ParseException
103
     * @throws \UnexpectedValueException
104
     * @throws \InvalidArgumentException
105
     *
106
     * @return null|Pipeline
107
     */
108 7
    public function searchReference(Reference $reference)
109
    {
110 7
        if (null === $type = $reference->getPipelinesType()) {
111 2
            return $this->getDefault();
112
        }
113
114 5
        return $this->searchTypeReference($type, $reference->getName());
115
    }
116
117
    /**
118
     * Searches a reference within type, returns found one, if
119
     * none is found, the default pipeline or null if there is
120
     * no default pipeline.
121
     *
122
     * @param string $type of pipeline, can be branches, tags or bookmarks
123
     * @param null|string $reference
124
     *
125
     * @throws ParseException
126
     * @throws \UnexpectedValueException
127
     * @throws \InvalidArgumentException
128
     *
129
     * @return null|Pipeline
130
     */
131 8
    public function searchTypeReference($type, $reference)
132
    {
133 8
        $id = $this->searchIdByTypeReference($type, $reference);
134
135 7
        return null !== $id ? $this->getById($id) : null;
136
    }
137
138
    /**
139
     * Searches the pipeline that matches the reference
140
     *
141
     * @param Reference $reference
142
     *
143
     * @throws \UnexpectedValueException
144
     * @throws \InvalidArgumentException
145
     *
146
     * @return null|string id if found, null otherwise
147
     */
148 1
    public function searchIdByReference(Reference $reference)
149
    {
150 1
        if (null === $reference->getType()) {
151 1
            return $this->getIdDefault();
152
        }
153
154 1
        return $this->searchIdByTypeReference(
155 1
            $reference->getPipelinesType(),
156 1
            $reference->getName()
157
        );
158
    }
159
160
    /**
161
     * @return File
162
     */
163 1
    public function getFile()
164
    {
165 1
        if ($this->file instanceof File) {
166 1
            return $this->file;
167
        }
168
169 1
        throw new \BadMethodCallException('Unassociated node');
170
    }
171
172
    /**
173
     * @throws \InvalidArgumentException
174
     * @throws ParseException
175
     *
176
     * @return array|Pipeline[]
177
     */
178 2
    public function getPipelines()
179
    {
180 2
        $pipelines = array();
181
182 2
        foreach ($this->getPipelineIds() as $id) {
183 2
            if (!ReferenceTypes::isValidId($id)) {
184 1
                throw new ParseException(sprintf("invalid pipeline id '%s'", $id));
185
            }
186 1
            $pipelines[$id] = $this->getById($id);
187
        }
188
189 1
        return $pipelines;
190
    }
191
192
    /**
193
     * Index all pipelines as references array map by id
194
     *
195
     * a reference is array($section (or default), $pattern (or null for default), &$arrayFileParseData)
196
     * references are keyed by their pipeline id
197
     *
198
     * @param array $array
199
     *
200
     * @throws ParseException
201
     *
202
     * @return array
203
     */
204 18
    private function parsePipelineReferences(array &$array)
205
    {
206 18
        $this->parseValidatePipelines($array);
207
208 16
        $references = $this->referencesDefault($array);
209
210 15
        $references = $this->referencesAddSections($references, $array);
211
212 14
        return $references;
213
    }
214
215
    /**
216
     * quick validation of pipeline sections (default pipeline + sections)
217
     *
218
     * there must be at least one pipeline in the file
219
     *
220
     * NOTE: the check is incomplete, as it assumes any section contains at
221
     *       least one pipeline which is unchecked
222
     *
223
     * @param array $array
224
     */
225 18
    private function parseValidatePipelines(array $array)
226
    {
227 18
        $sections = ReferenceTypes::getSections();
228 18
        $count = 0;
229 18
        foreach ($sections as $section) {
230 18
            if (isset($array[$section])) {
231 12
                $count++;
232
            }
233
        }
234 18
        if (!$count && !isset($array['default'])) {
235 2
            $middle = implode(', ', array_slice($sections, 0, -1));
236
237 2
            throw new ParseException("'pipelines' requires at least a default, ${middle} or custom section");
238
        }
239
    }
240
241
    /**
242
     * create references by default pipeline
243
     *
244
     * @param array $array
245
     *
246
     * @return array
247
     */
248
    private function referencesDefault(array &$array)
249
    {
250 16
        $references = array();
251
252 16
        $default = 'default';
253
254 16
        if (!isset($array[$default])) {
255 5
            return $references;
256
        }
257
258 11
        if (!is_array($array[$default])) {
259 1
            throw new ParseException("'${default}' requires a list of steps");
260
        }
261
262 10
        $references[$default] = array(
263 10
            $default,
264
            null,
265 10
            &$array[$default],
266
        );
267
268 10
        return $references;
269
    }
270
271
    /**
272
     * add section pipelines to references
273
     *
274
     * @param array $references
275
     * @param array $array
276
     *
277
     * @return array
278
     */
279
    private function referencesAddSections(array $references, array &$array)
280
    {
281
        // reference section pipelines
282 15
        $sections = ReferenceTypes::getSections();
283
284 15
        foreach ($array as $section => $refs) {
285 15
            if (!in_array($section, $sections, true)) {
286 10
                continue; // not a section for references
287
            }
288 12
            if (!is_array($refs)) {
289 1
                throw new ParseException("'${section}' requires a list");
290
            }
291 11
            foreach ($refs as $pattern => $pipeline) {
292 11
                $references["${section}/${pattern}"] = array(
293 11
                    (string)$section,
294 11
                    (string)$pattern,
295 11
                    &$array[$section][$pattern],
296
                );
297
            }
298
        }
299
300 14
        return $references;
301
    }
302
303
    /**
304
     * @param null|string $type
305
     * @param null|string $reference
306
     *
307
     * @throws \UnexpectedValueException
308
     * @throws \InvalidArgumentException
309
     *
310
     * @return null|string
311
     */
312
    private function searchIdByTypeReference($type, $reference)
313
    {
314 5
        return PipelinesReferences::idByTypeReference($this, $type, $reference);
315
    }
316
}
317