OLD | NEW |
1 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 # for details. All rights reserved. Use of this source code is governed by a | 2 # for details. All rights reserved. Use of this source code is governed by a |
3 # BSD-style license that can be found in the LICENSE file. | 3 # BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import re | 5 import re |
6 from functools import total_ordering | 6 from functools import total_ordering |
7 | 7 |
8 from google.appengine.ext import db | |
9 | |
10 @total_ordering | 8 @total_ordering |
11 class SemanticVersion(object): | 9 class SemanticVersion(object): |
12 """A semantic version number. See http://semver.org/.""" | 10 """A semantic version number. See http://semver.org/.""" |
13 | 11 |
14 _RE = re.compile(r""" | 12 _RE = re.compile(r""" |
15 ^ | 13 ^ |
16 (\d+)\.(\d+)\.(\d+) # Version number. | 14 (\d+)\.(\d+)\.(\d+) # Version number. |
17 (?:-([0-9a-z-]+(?:\.[0-9a-z-]+)*))? # Pre-release. | 15 (?:-([0-9a-z-]+(?:\.[0-9a-z-]+)*))? # Pre-release. |
18 (?:\+([0-9a-z-]+(?:\.[0-9a-z-]+)*))? # Build. | 16 (?:\+([0-9a-z-]+(?:\.[0-9a-z-]+)*))? # Build. |
19 $ # Consume entire string. | 17 $ # Consume entire string. |
20 """, re.VERBOSE | re.IGNORECASE) | 18 """, re.VERBOSE | re.IGNORECASE) |
21 | 19 |
22 def __init__(self, version): | 20 def __init__(self, version): |
23 """Parse a semantic version string.""" | 21 """Parse a semantic version string.""" |
24 | 22 |
25 match = SemanticVersion._RE.match(version) | 23 match = SemanticVersion._RE.match(version) |
26 if not match: raise db.BadValueError( | 24 if not match: |
27 '"%s" is not a valid semantic version.' % version) | 25 raise ValueError('"%s" is not a valid semantic version.' % version) |
28 | 26 |
29 self.major = int(match.group(1)) | 27 self.major = int(match.group(1)) |
30 self.minor = int(match.group(2)) | 28 self.minor = int(match.group(2)) |
31 self.patch = int(match.group(3)) | 29 self.patch = int(match.group(3)) |
32 self.prerelease = _split(match.group(4)) | 30 self.prerelease = _split(match.group(4)) |
33 self.build = _split(match.group(5)) | 31 self.build = _split(match.group(5)) |
34 self._text = version | 32 self._text = version |
35 | 33 |
36 @property | 34 @property |
37 def is_prerelease(self): | 35 def is_prerelease(self): |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 | 118 |
121 Specifically, splits the string on periods, then converts every section that | 119 Specifically, splits the string on periods, then converts every section that |
122 contains only numeric digits to an integer. | 120 contains only numeric digits to an integer. |
123 """ | 121 """ |
124 | 122 |
125 if string is None: return | 123 if string is None: return |
126 def maybe_make_int(substring): | 124 def maybe_make_int(substring): |
127 if re.search(r'[^0-9]', substring): return substring | 125 if re.search(r'[^0-9]', substring): return substring |
128 return int(substring) | 126 return int(substring) |
129 return map(maybe_make_int, string.split('.')) | 127 return map(maybe_make_int, string.split('.')) |
OLD | NEW |