109 lines
3.9 KiB
Python
109 lines
3.9 KiB
Python
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import itertools
|
|
|
|
|
|
def try_int(val):
|
|
try:
|
|
return int(val)
|
|
except ValueError:
|
|
return val
|
|
|
|
|
|
def parse_version(v):
|
|
parts = v.split('.')
|
|
if len(parts) < 3:
|
|
parts.append('0')
|
|
return [try_int(p) for p in parts]
|
|
|
|
|
|
def format_version(v):
|
|
return '.'.join(str(p) for p in v)
|
|
|
|
|
|
def _compute_next(actual):
|
|
"Given one field of a version, compute the next value."
|
|
try:
|
|
expected = actual + 1
|
|
except TypeError:
|
|
# The patch level is a string, not an int, meaning it is
|
|
# likely an alpha or beta release. Pull the prefix digits off
|
|
# and convert those to an int, defaulting to 0 if there is no
|
|
# prefix.
|
|
prefix = ''.join(itertools.takewhile(lambda x: x.isdigit(),
|
|
actual))
|
|
expected = int(prefix or 0) + 1
|
|
return expected
|
|
|
|
|
|
def sanity_check_version(new_version, existing_versions):
|
|
warnings = []
|
|
if not existing_versions:
|
|
if new_version[0] != 0:
|
|
warnings.append(
|
|
'first version in repository does not start with 0'
|
|
)
|
|
if new_version in existing_versions:
|
|
warnings.append(
|
|
'version %r already exists in repository' %
|
|
format_version(new_version)
|
|
)
|
|
same_minor = same_major = None
|
|
for v in existing_versions:
|
|
# Look for other numbers in the series
|
|
if v[:2] == new_version[:2]:
|
|
print('%r in same minor series as %r' %
|
|
(format_version(v), format_version(new_version)))
|
|
if not same_minor or v > same_minor:
|
|
same_minor = v
|
|
if v[:1] == new_version[:1]:
|
|
print('%r in same major series as %r' %
|
|
(format_version(v), format_version(new_version)))
|
|
if not same_major or v > same_major:
|
|
same_major = v
|
|
if same_minor is not None:
|
|
print('last version in minor series %r' %
|
|
format_version(same_minor))
|
|
expected = _compute_next(same_minor[2])
|
|
actual = new_version[2]
|
|
if actual > expected:
|
|
warnings.append(
|
|
'new version %r increments patch version more than one over %r'
|
|
% (format_version(new_version), format_version(same_minor))
|
|
)
|
|
if same_major is not None and same_major != same_minor:
|
|
print('last version in major series %r' %
|
|
format_version(same_major))
|
|
if new_version > same_major:
|
|
expected = _compute_next(same_major[1])
|
|
actual = new_version[1]
|
|
if actual > expected:
|
|
warnings.append(
|
|
('new version %r increments minor '
|
|
'version more than one over %r') %
|
|
(format_version(new_version), format_version(same_major))
|
|
)
|
|
if new_version[2] != 0:
|
|
warnings.append(
|
|
'new version %r increments minor version and patch version'
|
|
% format_version(new_version)
|
|
)
|
|
if existing_versions:
|
|
latest_version = existing_versions[-1]
|
|
if new_version[0] > latest_version[0]:
|
|
warnings.append(
|
|
'%r is a major version increment over %r' %
|
|
(format_version(new_version), format_version(latest_version))
|
|
)
|
|
return warnings
|