Cancelled
Push — test ( 1ce7d0...4eada7 )
by Tom
02:28
created

ValidationOptions::validate()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 29
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 6
eloc 18
c 1
b 0
f 1
nc 5
nop 1
dl 0
loc 29
ccs 18
cts 18
cp 1
crap 6
rs 9.0444
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Utility;
6
7
use InvalidArgumentException;
8
use JsonSchema\Constraints\Constraint;
9
use JsonSchema\Validator;
10
use Ktomk\Pipelines\Cli\Args;
11
use Ktomk\Pipelines\Cli\Streams;
12
use Ktomk\Pipelines\File\File;
13
use Ktomk\Pipelines\Yaml\Yaml;
14
15
/**
16
 * Class ValidationOptions
17
 *
18
 * validate one or multiple bitbucket-pipelines.yml files against
19
 * the schema
20
 *
21
 * @package Ktomk\Pipelines\Utility
22
 */
23
class ValidationOptions implements Runnable
24
{
25
    /**
26
     * @var Args
27
     */
28
    private $args;
29
30
    /**
31
     * @var callable
32
     */
33
    private $output;
34
35
    /**
36
     * @var File
37
     */
38
    private $file;
39
40
    /**
41
     * bind options
42
     *
43
     * @param Args $args
44
     * @param Streams $streams
45
     * @param File $file
46
     *
47
     * @return ValidationOptions
48
     */
49 1
    public static function bind(Args $args, Streams $streams, File $file)
50
    {
51 1
        return new self($args, $streams, $file);
52
    }
53
54
    /**
55
     * FileOptions constructor.
56
     *
57
     * @param Args $args
58
     * @param callable $output
59
     * @param File $file
60
     */
61 8
    public function __construct(Args $args, $output, File $file)
62
    {
63 8
        $this->args = $args;
64 8
        $this->output = $output;
65 8
        $this->file = $file;
66 8
    }
67
68
    /**
69
     * run options
70
     *
71
     * @throws InvalidArgumentException
72
     * @throws StatusException
73
     * @throws \ReflectionException
74
     *
75
     * @return $this
76
     */
77 6
    public function run()
78
    {
79 6
        $didValidate = false;
80 6
        $allValid = true;
81
82 6
        while ($verify = $this->args->getOptionOptionalArgument('validate', true)) {
83 5
            $didValidate = true;
84 5
            list($isValid) = $this->validate($verify);
85 4
            $isValid || $allValid = false;
86
        };
87
88 5
        if ($didValidate) {
89 4
            throw new StatusException(
90 4
                sprintf('verify done%s', $allValid ? '' : ', with errors'),
91 4
                $allValid ? 0 : 1
92
            );
93
        }
94
95 1
        return $this;
96
    }
97
98
    /**
99
     * @param string|true $verify
100
     *
101
     * @throws \ReflectionException
102
     *
103
     * @return array
104
     */
105 5
    private function validate($verify)
106
    {
107 5
        if (true === $verify) {
108 1
            $result = $this->validateInternal();
109
        } else {
110 4
            $data = Yaml::file($verify);
111 4
            if (null === $data) {
112 1
                throw new \UnexpectedValueException(sprintf('not a yaml file: %s', $verify));
113
            }
114 3
            $result = $this->validateData($data);
115
        }
116
117 4
        list($isValid, $validator) = $result;
118
119 4
        if (!$isValid) {
120 2
            foreach ($validator->getErrors(Validator::ERROR_DOCUMENT_VALIDATION) as $error) {
121 2
                call_user_func(
122 2
                    $this->output,
123 2
                    sprintf(
124 2
                        '%s[%s] %s',
125 2
                        true === $verify ? '' : sprintf('%s: ', $verify),
126 2
                        $error['property'],
127 2
                        $error['message']
128
                    )
129
                );
130
            }
131
        }
132
133 4
        return array($isValid, $validator);
134
    }
135
136
    /**
137
     * @throws \ReflectionException
138
     *
139
     * @return array
140
     */
141 1
    private function validateInternal()
142
    {
143 1
        $reflection = new \ReflectionObject($this->file);
144 1
        $prop = $reflection->getProperty('array');
145 1
        $prop->setAccessible(true);
146 1
        $data = $prop->getValue($this->file);
147
148 1
        return $this->validateData($data);
149
    }
150
151
    /**
152
     * @param array $data
153
     *
154
     * @return array
155
     */
156 4
    private function validateData(array $data)
157
    {
158
        // Validate
159 4
        $validator = new \JsonSchema\Validator();
160 4
        $path = __DIR__ . '/../../lib/pipelines/schema/pipelines-schema.json';
161 4
        if (0 !== strpos($path, 'phar:///', 0)) {
162 4
            $path = 'file://' . $path;
163
        }
164
165 4
        $validator->validate(
166 4
            $data,
167 4
            (object)array('$ref' => $path),
168 4
            Constraint::CHECK_MODE_TYPE_CAST | Constraint::CHECK_MODE_DISABLE_FORMAT
169
        );
170
171 4
        $isValid = $validator->isValid();
172
173 4
        return array($isValid, $validator);
174
    }
175
}
176