| 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 |