4 # Copyright (C) 2010-2018 CEA/DEN
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 class and utilities to define a version as MAJOR.MINOR.PATCH,
25 | Given a version number MAJOR.MINOR.PATCH separator "_" or "."
27 | MAJOR version when you make incompatible API changes,
28 | MINOR version when you add functionality in a backwards-compatible manner,
29 | PATCH version when you make backwards-compatible bug fixes.
35 verbose = False # True
37 #############################################
38 def only_numbers(aStr):
40 Remove non numericals characters from string,
42 :param aStr: string to work
43 :return: None if no number presence
45 res = ''.join([nb for nb in aStr if nb in '0123456789'])
51 #############################################
52 def remove_startswith(aStr, startsToCheck):
54 remove starting strings, if begining of aStr correspond
55 order of list startsToCheck matter
56 do the stuff only for the first correspondence in startsToCheck
58 for s in startsToCheck:
59 if aStr.startswith(s):
63 #############################################
64 def toList_majorMinorPatch(aStr, verbose=False):
66 Returns list of integer as [major, minor, patch] from a string,
68 | accepts '1.2.3' '1_2_3' 'version_1.2.3' 'version1.2.3' 'v1.2.3',
69 | completion '123' means '123.0.0', '1.2' means '1.2.0'
71 | raise exception if problem
73 if verbose: print("toList_majorMinorPatch('%s')" % aStr)
74 res = aStr.replace(" ", "")
76 res = remove_startswith(res, "version_ version v".split())
77 res = res.replace(".", "_").split("_")
79 msg = "Not a major_minor_patch correct syntax: '%s'" % aStr
82 msg = "An empty string is not a major_minor_patch syntax"
85 # complete MINOR.PATCH if not existing
94 msg = "major in major_minor_patch is not integer: '%s'" % aStr
97 msg = "major in major_minor_patch is negative integer: '%s'" % aStr
103 msg = "minor in major_minor_patch is not integer: '%s'" % aStr
106 msg = "minor in major_minor_patch is negative integer: '%s'" % aStr
112 msg = "patch in major_minor_patch is not integer: '%s'" % aStr
115 msg = "patch in major_minor_patch is negative integer: '%s'" % aStr
118 return [int(i) for i in res]
120 #############################################
121 def toCompactStr_majorMinorPatch(version):
123 parameter version is list of integer as [major, minor, patch]
125 | returns "789" for [7, 8, 9]
127 | minor, pach have to be integer less than 10
128 | raise exception for [7, 10, 11]
129 | (which returns "71011" as ambigous 710.1.1 for example)
131 if len(version) != 3:
132 msg = "version major_minor_patch is incorrect: '%s'" % version
135 aStr = '_'.join([str(i) for i in version])
136 toList_majorMinorPatch(aStr) # will raise error if problem (as too much or negative values)
138 res = "".join([str(i) for i in version])
139 if version[1] > 9 or version[2] > 9:
140 raise Exception("ambigous major_minor_patch compact representation '%s' from '%s'" % (res, version))
144 #############################################
145 def getRange_majorMinorPatch(aStr, verbose=False):
147 extract from aStr a version range, defined as
148 '*_from_aMinVersionTag_to_aMaxVersionTag' or
149 '*version_aMinVersionTag_to_aMaxVersionTag'.
151 where aMinVersionTag and aMaxVersionTag are compatible with MinorMajorPatch class syntaxes
152 '1.2.3' or '1_2_3' etc.
153 if not found '_from_' or 'version_' first then aMinVersionTag is '0.0.0'
155 :param aStr: string to work
156 :return: list [min, max], where min, max are MinorMajorPatch instances.
157 else None if not found
159 tmp1 = aStr.lower().split("_to_")
162 return None # no '_to_'
164 msg = "more than one '_to_' is incorrect for version range: '%s'" % aStr
168 # accept older syntax as 'version_1_0_0_to_2_0_0', (as '_from_1_0_0_to_2_0_0')
169 if "version_" in tmp1[0] and "_from_" not in tmp1[0]:
170 aStr_with_from = aStr.lower().replace("version_", "_from_", 1)
172 aStr_with_from = aStr.lower()
174 # print("aStr_with_from '%s' -> '%s'" % (aStr, aStr_with_from))
176 tmp0 = aStr_with_from.split("_from_")
177 tmp1 = aStr_with_from.split("_to_")
180 msg = "more than one '_from_' is incorrect for version range: '%s'" % aStr
183 tmp2 = tmp1[0].split("_from_")
191 msg = "version min '%s' and version max '%s' in version range: '%s'" % (aMin, aMax, aStr)
195 rMin = MinorMajorPatch(aMin)
196 rMax = MinorMajorPatch(aMax)
198 msg = "problem version range in '%s'" % aStr
201 print("WARNING: problem version range in '%s'" % aStr)
205 msg = "version min '%s' > version max '%s' in version range: '%s'" % (rMin, rMax, aStr)
210 #############################################
211 class MinorMajorPatch(object):
213 class to define a version as MAJOR.MINOR.PATCH
215 | Given a version number MAJOR.MINOR.PATCH separator "_" or "."
217 | MAJOR version when you make incompatible API changes,
218 | MINOR version when you add functionality in a backwards-compatible manner,
219 | PATCH version when you make backwards-compatible bug fixes.
222 def __init__(self, version):
223 if type(version) == list:
224 aStr = '_'.join([str(i) for i in version])
225 v = toList_majorMinorPatch(aStr)
227 v = toList_majorMinorPatch(version)
232 def __repr__(self, sep="_"):
233 """example is 'version_1_2_3' """
234 res = "version_%i%s%i%s%i" % (self.major, sep, self.minor, sep, self.patch)
237 def __str__(self, sep="."):
238 """example is '1.2.3' """
239 res = "%i%s%i%s%i" % (self.major, sep, self.minor, sep, self.patch)
243 """example is '1_2_3' """
244 return self.__str__(sep="_")
246 def strClassic(self):
247 """example is '1.2.3' """
248 return self.__str__(sep=".")
250 def strCompact(self):
251 """example is '123' from '1.2.3' """
252 return toCompactStr_majorMinorPatch(self.toList())
255 """example is list of integer [1, 2, 3] from '1.2.3' """
256 return [self.major, self.minor, self.patch]
258 def __lt__(self, other):
259 res = (self.toList() < other.toList())
262 def __le__(self, other):
263 res = (self.toList() <= other.toList())
266 def __gt__(self, other):
267 res = (self.toList() > other.toList())
270 def __ge__(self, other):
271 res = (self.toList() >= other.toList())
274 def __eq__(self, other):
275 res = (self.toList() == other.toList())
278 def __ne__(self, other):
279 res = (self.toList() != other.toList())