66
77_LOGGER = logging .getLogger (__name__ )
88
9+ def build_semver_or_none (version ):
10+ try :
11+ return Semver (version )
12+ except (RuntimeError , ValueError ):
13+ _LOGGER .error ("Invalid semver version: %s" , version )
14+ return None
15+
916class Semver (object ):
1017 """Semver class."""
1118
@@ -29,38 +36,29 @@ def __init__(self, version):
2936 self ._metadata = ""
3037 self ._parse (version )
3138
32- @classmethod
33- def build (cls , version ):
34- try :
35- self = cls (version )
36- except RuntimeError as e :
37- _LOGGER .error ("Failed to parse Semver data, incorrect data type: %s" , e )
38- return None
39-
40- return self
4139
4240 def _parse (self , version ):
4341 """
4442 Parse the string in self.version to update the other internal variables
4543 """
46- without_metadata = self ._remove_metadata_if_exists (version )
44+ without_metadata = self ._extract_metadata (version )
4745 index = without_metadata .find (self ._PRE_RELEASE_DELIMITER )
4846 if index == - 1 :
4947 self ._is_stable = True
5048 else :
5149 pre_release_data = without_metadata [index + 1 :]
5250 if pre_release_data == "" :
53- raise RuntimeError ("Pre-release is empty despite delimeter exists: " + version )
51+ raise RuntimeError ("Pre-release is empty despite delimiter exists: " + version )
5452
5553 without_metadata = without_metadata [:index ]
5654 for pre_digit in pre_release_data .split (self ._VALUE_DELIMITER ):
5755 if pre_digit .isnumeric ():
5856 pre_digit = str (int (pre_digit ))
5957 self ._pre_release .append (pre_digit )
6058
61- self ._set_major_minor_and_patch (without_metadata )
59+ self ._set_components (without_metadata )
6260
63- def _remove_metadata_if_exists (self , version ):
61+ def _extract_metadata (self , version ):
6462 """
6563 Check if there is any metadata characters in self.version.
6664
@@ -73,11 +71,11 @@ def _remove_metadata_if_exists(self, version):
7371
7472 self ._metadata = version [index + 1 :]
7573 if self ._metadata == "" :
76- raise RuntimeError ("Metadata is empty despite delimeter exists: " + version )
74+ raise RuntimeError ("Metadata is empty despite delimiter exists: " + version )
7775
7876 return version [:index ]
7977
80- def _set_major_minor_and_patch (self , version ):
78+ def _set_components (self , version ):
8179 """
8280 Set the major, minor and patch internal variables based on string passed.
8381
@@ -140,7 +138,7 @@ def compare(self, to_compare):
140138 continue
141139
142140 if self ._pre_release [i ].isnumeric () and to_compare ._pre_release [i ].isnumeric ():
143- return self ._compare_vars (int (self ._pre_release [i ]), int (to_compare ._pre_release [i ]))
141+ return self ._compare_vars (int (self ._pre_release [i ]), int (to_compare ._pre_release [i ]))
144142
145143 return self ._compare_vars (self ._pre_release [i ], to_compare ._pre_release [i ])
146144
@@ -179,7 +177,7 @@ def _build(self, raw_matcher):
179177 :type raw_matcher: dict
180178 """
181179 self ._data = raw_matcher .get ('stringMatcherData' )
182- self ._semver = Semver . build ( self . _data )
180+ self ._semver = build_semver_or_none ( raw_matcher . get ( 'stringMatcherData' ) )
183181
184182 def _match (self , key , attributes = None , context = None ):
185183 """
@@ -195,15 +193,15 @@ def _match(self, key, attributes=None, context=None):
195193 :returns: Wheter the match is successful.
196194 :rtype: bool
197195 """
198- if self ._data is None or self . _semver is None :
196+ if self ._semver is None :
199197 _LOGGER .error ("stringMatcherData is required for EQUAL_TO_SEMVER matcher type" )
200198 return False
201199
202200 matching_data = Sanitizer .ensure_string (self ._get_matcher_input (key , attributes ))
203201 if matching_data is None :
204202 return False
205203
206- matching_semver = Semver . build (matching_data )
204+ matching_semver = build_semver_or_none (matching_data )
207205 if matching_semver is None :
208206 return False
209207
@@ -228,7 +226,7 @@ def _build(self, raw_matcher):
228226 :type raw_matcher: dict
229227 """
230228 self ._data = raw_matcher .get ('stringMatcherData' )
231- self ._semver = Semver . build ( self . _data )
229+ self ._semver = build_semver_or_none ( raw_matcher . get ( 'stringMatcherData' ) )
232230
233231 def _match (self , key , attributes = None , context = None ):
234232 """
@@ -244,15 +242,15 @@ def _match(self, key, attributes=None, context=None):
244242 :returns: Wheter the match is successful.
245243 :rtype: bool
246244 """
247- if self ._data is None or self . _semver is None :
245+ if self ._semver is None :
248246 _LOGGER .error ("stringMatcherData is required for GREATER_THAN_OR_EQUAL_TO_SEMVER matcher type" )
249247 return False
250248
251249 matching_data = Sanitizer .ensure_string (self ._get_matcher_input (key , attributes ))
252250 if matching_data is None :
253251 return False
254252
255- matching_semver = Semver . build (matching_data )
253+ matching_semver = build_semver_or_none (matching_data )
256254 if matching_semver is None :
257255 return False
258256
@@ -277,7 +275,7 @@ def _build(self, raw_matcher):
277275 :type raw_matcher: dict
278276 """
279277 self ._data = raw_matcher .get ('stringMatcherData' )
280- self ._semver = Semver . build ( self . _data )
278+ self ._semver = build_semver_or_none ( raw_matcher . get ( 'stringMatcherData' ) )
281279
282280 def _match (self , key , attributes = None , context = None ):
283281 """
@@ -293,15 +291,15 @@ def _match(self, key, attributes=None, context=None):
293291 :returns: Wheter the match is successful.
294292 :rtype: bool
295293 """
296- if self ._data is None or self . _semver is None :
294+ if self ._semver is None :
297295 _LOGGER .error ("stringMatcherData is required for LESS_THAN_OR_EQUAL_TO_SEMVER matcher type" )
298296 return False
299297
300298 matching_data = Sanitizer .ensure_string (self ._get_matcher_input (key , attributes ))
301299 if matching_data is None :
302300 return False
303301
304- matching_semver = Semver . build (matching_data )
302+ matching_semver = build_semver_or_none (matching_data )
305303 if matching_semver is None :
306304 return False
307305
@@ -326,8 +324,8 @@ def _build(self, raw_matcher):
326324 :type raw_matcher: dict
327325 """
328326 self ._data = raw_matcher .get ('betweenStringMatcherData' )
329- self ._semver_start = Semver . build (self ._data ['start' ]) if self . _data . get ( 'start' ) is not None else None
330- self ._semver_end = Semver . build (self ._data ['end' ]) if self . _data . get ( 'end' ) is not None else None
327+ self ._semver_start = build_semver_or_none (self ._data ['start' ])
328+ self ._semver_end = build_semver_or_none (self ._data ['end' ])
331329
332330 def _match (self , key , attributes = None , context = None ):
333331 """
@@ -343,15 +341,15 @@ def _match(self, key, attributes=None, context=None):
343341 :returns: Wheter the match is successful.
344342 :rtype: bool
345343 """
346- if self ._data is None or self . _semver_start is None or self ._semver_end is None :
344+ if self ._semver_start is None or self ._semver_end is None :
347345 _LOGGER .error ("betweenStringMatcherData is required for BETWEEN_SEMVER matcher type" )
348346 return False
349347
350348 matching_data = Sanitizer .ensure_string (self ._get_matcher_input (key , attributes ))
351349 if matching_data is None :
352350 return False
353351
354- matching_semver = Semver . build (matching_data )
352+ matching_semver = build_semver_or_none (matching_data )
355353 if matching_semver is None :
356354 return False
357355
@@ -375,11 +373,9 @@ def _build(self, raw_matcher):
375373 :param raw_matcher: raw matcher as fetched from splitChanges response.
376374 :type raw_matcher: dict
377375 """
378- self ._data = raw_matcher .get ('whitelistMatcherData' )
379- if self ._data is not None :
380- self ._data = self ._data .get ('whitelist' )
381-
382- self ._semver_list = [Semver .build (item ) if item is not None else None for item in self ._data ] if self ._data is not None else []
376+ self ._data = raw_matcher ['whitelistMatcherData' ]['whitelist' ]
377+ semver_list = [build_semver_or_none (item ) if item is not None else None for item in self ._data ]
378+ self ._semver_list = frozenset ([item .version for item in semver_list ])
383379
384380 def _match (self , key , attributes = None , context = None ):
385381 """
@@ -395,19 +391,19 @@ def _match(self, key, attributes=None, context=None):
395391 :returns: Wheter the match is successful.
396392 :rtype: bool
397393 """
398- if self ._data is None :
394+ if self ._semver_list is None :
399395 _LOGGER .error ("whitelistMatcherData is required for IN_LIST_SEMVER matcher type" )
400396 return False
401397
402398 matching_data = Sanitizer .ensure_string (self ._get_matcher_input (key , attributes ))
403399 if matching_data is None :
404400 return False
405401
406- matching_semver = Semver . build (matching_data )
402+ matching_semver = build_semver_or_none (matching_data )
407403 if matching_semver is None :
408404 return False
409405
410- return any ([ item . version == matching_semver .version if item is not None else False for item in self ._semver_list ])
406+ return matching_semver .version in self ._semver_list
411407
412408 def __str__ (self ):
413409 """Return string Representation."""
0 commit comments