VersionIdentifiers::__toString()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
cc 3
nc 3
nop 0
1
<?php
2
3
namespace Hubph;
4
5
class VersionIdentifiers
6
{
7
    protected $data = [];
8
    protected $vidPattern;
9
    protected $vvalPattern;
10
    protected $preamble = 'Update to ';
11
12
    const DEFAULT_VID = '[A-Za-z_-]+ ?';
13
    const DEFAULT_VVAL = '#.#.#';
14
    const EXTRA = '(?:(stable|beta|b|RC|alpha|a|patch|pl|p)((?:[.-]?\d+)*+)?)?([.-]?dev)?';
15
    const NUMBER = '[0-9]+';
16
    const OPTIONAL_NUMBER = '[0-9]*';
17
18
    /**
19
     * VersionIdentifiers constructor
20
     */
21
    public function __construct()
22
    {
23
        $this->vidPattern = '';
24
        $this->vvalPattern = '';
25
    }
26
27
    public function getPreamble()
28
    {
29
        return $this->preamble;
30
    }
31
32
    public function setPreamble($preamble)
33
    {
34
        $this->preamble = $preamble;
35
    }
36
37
    public function getVidPattern()
38
    {
39
        return empty($this->vidPattern) ? self::DEFAULT_VID : $this->vidPattern;
40
    }
41
42
    public function setVidPattern($vidPattern)
43
    {
44
        $this->vidPattern = $vidPattern;
45
    }
46
47
    public function getVvalPattern()
48
    {
49
        return empty($this->vvalPattern) ? self::DEFAULT_VVAL : $this->vvalPattern;
50
    }
51
52
    public function setVvalPattern($vvalPattern)
53
    {
54
        $this->vvalPattern = $vvalPattern;
55
    }
56
57
    /**
58
     * Multiple provided value with our multiplier
59
     *
60
     * @param $value multiplicand
61
     * @return integer product of multiplier and multiplicand
62
     */
63
    public function add($vid, $vval)
64
    {
65
        $this->data[$vid] = $vval;
66
    }
67
68
    public function pattern()
69
    {
70
        $vidPattern = $this->getVidPattern();
71
        $vvalPattern = $this->getVvalPattern();
72
73
        $vid_vval_regex = "({$vidPattern})({$vvalPattern}[._-]?)" . self::EXTRA;
74
75
        $vid_vval_regex = str_replace('.-', '\\.?' . self::OPTIONAL_NUMBER, $vid_vval_regex);
76
        $vid_vval_regex = str_replace('.#', '\\.#', $vid_vval_regex);
77
        $vid_vval_regex = str_replace('#', self::NUMBER, $vid_vval_regex);
78
79
        return $vid_vval_regex;
80
    }
81
82
    /**
83
     * Given a simple message like "Update to WordPress 4.9.8", return the
84
     * correct vid/vval pair. In this case, the vid is "WordPress " and the
85
     * vval is "4.9.8".
86
     *
87
     * @param string $message a commit message
88
     */
89
    public function addVidsFromMessage($message)
90
    {
91
        $vid_vval_regex = $this->pattern();
92
93
        if (!preg_match_all("#$vid_vval_regex#", $message, $matches, PREG_SET_ORDER)) {
94
            throw new \Exception('Message does not contain a semver release identifier, e.g.: Update to myproject-1.2.3');
95
        }
96
        foreach ($matches as $matchset) {
97
            array_shift($matchset);
98
            $vid = array_shift($matchset);
99
            $vval = implode('', $matchset);
100
101
            // Trim trailing punctuation.
102
            $vval = preg_replace('#[^0-9a-zA-Z]*$#', '', $vval);
103
104
            $this->add($vid, $vval);
105
        }
106
    }
107
108
    /**
109
     * Check to see if a list of PR titles collectively contain all of the
110
     * vids with vvals.
111
     *
112
     * @param string[] $titles
113
     */
114
    public function allExist($titles)
115
    {
116
        // If we are empty do we return 'true' or 'false'? Maybe throw.
117
        if ($this->isEmpty()) {
118
            return false;
119
        }
120
121
        foreach ($this->all() as $value) {
122
            if (!$this->someTitleContains($titles, $value)) {
123
                return false;
124
            }
125
        }
126
127
        return true;
128
    }
129
130
    /**
131
     *  foreach ($existingPRs as $pr) {
132
     *    if (strpos($pr['title'], $value) !== false) {
133
     */
134
    protected function someTitleContains($titles, $value)
135
    {
136
        foreach ($titles as $title) {
137
            if (strpos($title, $value) !== false) {
138
                return true;
139
            }
140
        }
141
        return false;
142
    }
143
144
    public function isEmpty()
145
    {
146
        return empty($this->data);
147
    }
148
149
    public function all()
150
    {
151
        $result = [];
152
        foreach ($this->data as $vid => $vval) {
153
            $result[] = "{$vid}{$vval}";
154
        }
155
        return $result;
156
    }
157
158
    public function ids()
159
    {
160
        return array_keys($this->data);
161
    }
162
163
    public function __toString()
164
    {
165
        if ($this->isEmpty()) {
166
            return '';
167
        }
168
169
        $all = $this->all();
170
171
        $last = array_pop($all);
172
173
        if (empty($all)) {
174
            return $last;
175
        }
176
177
        return implode(', ', $all) . ", and $last";
178
    }
179
}
180