1919 *
2020 * Expects version to use the following structure:
2121 *
22- * <code>Major.Minor.Patch-ReleaseType </code>
22+ * <code>Major.Minor.Patch-(Branch or release name)-(Release type: alpha, beta...) </code>
2323 *
2424 * Examples:
2525 *
4343 */
4444class VersionParser
4545{
46- const TAG_TYPE_NONE = 'none ' ;
47- const TAG_TYPE_BETA = 'beta ' ;
48- const TAG_TYPE_ALPHA = 'alpha ' ;
49- const TAG_TYPE_RELEASE_CANDIDATE = 'rc ' ;
46+ public const TAG_TYPE_NONE = 'none ' ;
47+ public const TAG_TYPE_BETA = 'beta ' ;
48+ public const TAG_TYPE_ALPHA = 'alpha ' ;
49+ public const TAG_TYPE_RELEASE_CANDIDATE = 'rc ' ;
50+ public const TAG_TYPE_SNAPSHOT = 'snapshot ' ;
5051
51- /**
52- * @var string
53- */
54- private $ version ;
55-
56- /**
57- * @var float
58- */
59- private $ buildNumber = -1 ;
52+ private string $ version ;
6053
61- /**
62- * @var string
63- */
64- private $ tag = '' ;
54+ private float $ buildNumber = -1.0 ;
6555
6656 /**
6757 * @var array<int,int>
6858 */
69- private $ parts = array ();
70-
71- /**
72- * @var string
73- */
74- private $ tagType = self ::TAG_TYPE_NONE ;
59+ private array $ parts = array ();
7560
76- /**
77- * @var integer
78- */
79- private $ tagNumber = 0 ;
80-
81- /**
82- * @var string
83- */
84- private $ branchName = '' ;
85-
86- /**
87- * @var array<string,int>
61+ private string $ tagType = self ::TAG_TYPE_NONE ;
62+ private int $ tagNumber = 0 ;
63+ private string $ branchName = '' ;
64+ private string $ separator = '- ' ;
65+ private bool $ lowercase = true ;
66+
67+ /**
68+ * @var array<string,int>|NULL
8869 */
89- private $ tagWeights = array (
90- self ::TAG_TYPE_ALPHA => 6 ,
91- self ::TAG_TYPE_BETA => 4 ,
92- self ::TAG_TYPE_RELEASE_CANDIDATE => 2 ,
93- self ::TAG_TYPE_NONE => 0
94- );
70+ private static ?array $ tagWeights = null ;
9571
9672 private function __construct (string $ version )
9773 {
9874 $ this ->version = $ version ;
9975
10076 $ this ->parse ();
101- $ this ->postParse ();
77+ }
78+
79+ public function setUppercase (bool $ uppercase =true ) : self
80+ {
81+ $ this ->lowercase = !$ uppercase ;
82+ return $ this ;
83+ }
84+
85+ public function setSeparatorChar (string $ char ) : self
86+ {
87+ $ this ->separator = $ char ;
88+ return $ this ;
10289 }
10390
10491 /**
@@ -119,7 +106,7 @@ public static function create(string $version) : VersionParser
119106 */
120107 public function getBuildNumber () : float
121108 {
122- if ($ this ->buildNumber === -1 )
109+ if ($ this ->buildNumber === -1.0 )
123110 {
124111 $ this ->calculateBuildNumber ();
125112 }
@@ -134,7 +121,7 @@ public function getBuildNumber() : float
134121 */
135122 public function getBuildNumberInt () : int
136123 {
137- return intval ($ this ->getBuildNumber () * 1000000 );
124+ return ( int ) ($ this ->getBuildNumber () * 1000000 );
138125 }
139126
140127 /**
@@ -181,9 +168,9 @@ public function getTagVersion() : string
181168 return $ version ;
182169 }
183170
184- return $ version .' - ' .$ this ->getTag ();
171+ return $ version .$ this -> separator .$ this ->getTag ();
185172 }
186-
173+
187174 /**
188175 * Retrieves only the numeric version, omitting dots
189176 * as far as possible (e.g. `1.0.0` => `1`).
@@ -192,8 +179,6 @@ public function getTagVersion() : string
192179 */
193180 public function getShortVersion () : string
194181 {
195- $ keep = array ();
196-
197182 if ($ this ->parts [2 ] > 0 )
198183 {
199184 $ keep = $ this ->parts ;
@@ -217,7 +202,29 @@ public function getShortVersion() : string
217202 */
218203 public function getTag () : string
219204 {
220- return $ this ->tag ;
205+ if ($ this ->tagType === self ::TAG_TYPE_NONE )
206+ {
207+ return $ this ->getBranchName ();
208+ }
209+
210+ $ tag = $ this ->tagType ;
211+
212+ if ($ this ->tagNumber > 1 )
213+ {
214+ $ tag .= $ this ->tagNumber ;
215+ }
216+
217+ if (!$ this ->lowercase )
218+ {
219+ $ tag = strtoupper ($ tag );
220+ }
221+
222+ if ($ this ->hasBranch ())
223+ {
224+ $ tag = $ this ->getBranchName ().$ this ->separator .$ tag ;
225+ }
226+
227+ return $ tag ;
221228 }
222229
223230 /**
@@ -227,7 +234,7 @@ public function getTag() : string
227234 */
228235 public function hasTag () : bool
229236 {
230- return ! empty ( $ this ->tag ) ;
237+ return $ this ->getTag () !== '' ;
231238 }
232239
233240 /**
@@ -314,7 +321,7 @@ private function parse() : void
314321
315322 for ($ i =0 ; $ i < 3 ; $ i ++)
316323 {
317- $ this ->parts [] = intval ( $ parts [$ i ]) ;
324+ $ this ->parts [] = ( int ) $ parts [$ i ];
318325 }
319326 }
320327
@@ -334,45 +341,19 @@ private function extractTag() : string
334341
335342 return $ version ;
336343 }
337-
338- private function postParse () : void
339- {
340- $ this ->tag = $ this ->normalizeTag ();
341- }
342-
343- private function normalizeTag () : string
344- {
345- if ($ this ->tagType === self ::TAG_TYPE_NONE )
346- {
347- return $ this ->getBranchName ();
348- }
349-
350- $ tag = $ this ->tagType ;
351-
352- if ($ this ->tagNumber > 1 )
353- {
354- $ tag .= $ this ->tagNumber ;
355- }
356-
357- if ($ this ->hasBranch ())
358- {
359- $ tag = $ this ->getBranchName ().'- ' .$ tag ;
360- }
361-
362- return $ tag ;
363- }
364-
344+
365345 private function formatTagNumber () : string
366346 {
347+ $ tagWeights = self ::getTagWeights ();
367348 $ positions = 2 * 3 ;
368- $ weight = $ this -> tagWeights [$ this ->getTagType ()];
349+ $ weight = $ tagWeights [$ this ->getTagType ()];
369350
370351 if ($ weight > 0 )
371352 {
372353 $ number = sprintf ('%0 ' .$ weight .'d ' , $ this ->tagNumber );
373- $ number = str_pad ($ number , $ positions , '0 ' , STR_PAD_RIGHT );
354+ $ number = str_pad ($ number , $ positions , '0 ' );
374355
375- $ number = intval ( str_repeat ('9 ' , $ positions )) - intval ( $ number) ;
356+ $ number = ( int ) str_repeat ('9 ' , $ positions ) - ( int ) $ number ;
376357 return '. ' .$ number ;
377358 }
378359
@@ -403,17 +384,17 @@ private function parseTagPart(string $part) : void
403384 {
404385 if (is_numeric ($ part ))
405386 {
406- $ this ->tagNumber = intval ( $ part) ;
387+ $ this ->tagNumber = ( int ) $ part ;
407388 return ;
408389 }
409390
410- $ types = array_keys ($ this -> tagWeights );
391+ $ types = array_keys (self :: getTagWeights () );
411392 $ type = '' ;
412393 $ lower = strtolower ($ part );
413394
414395 foreach ($ types as $ tagType )
415396 {
416- if (strstr ($ lower , $ tagType ))
397+ if (strpos ($ lower , $ tagType ) !== false )
417398 {
418399 $ type = $ tagType ;
419400 $ part = str_replace ($ tagType , '' , $ lower );
@@ -434,7 +415,7 @@ private function parseTagPart(string $part) : void
434415
435416 if (is_numeric ($ part ))
436417 {
437- $ this ->tagNumber = intval ( $ part) ;
418+ $ this ->tagNumber = ( int ) $ part ;
438419 }
439420 }
440421
@@ -446,11 +427,11 @@ private function calculateBuildNumber() : void
446427 sprintf ('%03d ' , $ this ->getPatchVersion ())
447428 );
448429
449- $ number = floatval ( implode ('' , $ parts) );
430+ $ number = ( float ) implode ('' , $ parts );
450431
451432 if ($ this ->tagNumber > 0 )
452433 {
453- $ number -= floatval ( $ this ->formatTagNumber () );
434+ $ number -= ( float ) $ this ->formatTagNumber ();
454435 }
455436
456437 $ this ->buildNumber = $ number ;
@@ -477,5 +458,48 @@ public function isLowerThan(VersionParser $version) : bool
477458 {
478459 return $ this ->getBuildNumberInt () < $ version ->getBuildNumberInt ();
479460 }
480- }
481461
462+ /**
463+ * Registers a tag name to look for in version strings,
464+ * in addition to the bundled tags like "beta" or "alpha".
465+ *
466+ * NOTE: Can also be used to change the weight of the
467+ * default tags.
468+ *
469+ * @param string $name
470+ * @param int $weight Used for version comparisons, like beta > alpha.
471+ * The higher the weight, the further it "sinks down", e.g.
472+ * "alpha" has a default weight of "6" and beta a weight of "4".
473+ * @return void
474+ */
475+ public static function registerTagType (string $ name , int $ weight ) : void
476+ {
477+ $ tagWeights = self ::getTagWeights ();
478+ $ tagWeights [$ name ] = $ weight ;
479+
480+ self ::$ tagWeights = $ tagWeights ;
481+ }
482+
483+ /**
484+ * @return array<string,int>
485+ */
486+ public static function getTagWeights () : array
487+ {
488+ if (!isset (self ::$ tagWeights )) {
489+ self ::$ tagWeights = array (
490+ self ::TAG_TYPE_ALPHA => 6 ,
491+ self ::TAG_TYPE_BETA => 4 ,
492+ self ::TAG_TYPE_RELEASE_CANDIDATE => 2 ,
493+ self ::TAG_TYPE_SNAPSHOT => 0 ,
494+ self ::TAG_TYPE_NONE => 0
495+ );
496+ }
497+
498+ return self ::$ tagWeights ;
499+ }
500+
501+ public static function resetTagTypes () : void
502+ {
503+ self ::$ tagWeights = null ;
504+ }
505+ }
0 commit comments