blob: af2873b138d114757e78d65ff02aa9ea8ee706ce [file] [log] [blame]
import re
from release.info import isFinalRelease
class BuildVersionsException(Exception):
pass
# Versions that match this should not be bumped
DO_NOT_BUMP_REGEX = '^\d\.\d(pre)?$'
# Regex that matches all possible versions and milestones
ANY_VERSION_REGEX =\
('(\d+\.\d[\d\.]*)' # A version number
'((a|b)\d+)?' # Might be an alpha or beta
'(esr)?' # Might be an esr
'(pre)?') # Might be a 'pre' (nightly) version
# NB: If a file could match more than one of the regexes below the behaviour
# will be undefined, because the key order will differ from system to system
# and possibly run to run. Try to avoid this.
BUMP_FILES = {
r'^.*(version.*\.txt|milestone\.txt)$': '^%(version)s$',
r'^.*confvars\.sh$': '^MOZ_APP_VERSION=%(version)s$'
}
def bumpFile(filename, contents, version):
# First, find the right regex for this file
newContents = []
for fileRegex, versionRegex in BUMP_FILES.iteritems():
if re.match(fileRegex, filename):
# Second, find the line with the version in it
for line in contents.splitlines():
regex = versionRegex % {'version': ANY_VERSION_REGEX}
match = re.match(regex, line)
# If this is the version line, and the file doesn't have
# the correct version, change it.
if match and match.group() != version:
newContents.append(
re.sub(ANY_VERSION_REGEX, version, line))
# If it's not the version line, or the version is correct,
# don't do anything
else:
newContents.append(line)
newContents = "\n".join(newContents)
# Be sure to preserve trailing newlines, if they exist
if contents.endswith("\n"):
newContents += "\n"
break
if len(newContents) == 0:
raise BuildVersionsException("Don't know how to bump %s" % filename)
return newContents
def nextVersion(version, pre=False):
"""Returns the version directly after `version', optionally with "pre"
appended to it."""
if re.match(DO_NOT_BUMP_REGEX, version):
bumped = version
else:
bumped = increment(version)
if pre:
bumped += "pre"
return bumped
# The following function was copied from http://code.activestate.com/recipes/442460/
# Written by Chris Olds
lastNum = re.compile(r'(?:[^\d]*(\d+)[^\d]*)+')
def increment(s):
""" look for the last sequence of number(s) in a string and increment """
m = lastNum.search(s)
if m:
next = str(int(m.group(1)) + 1)
start, end = m.span(1)
s = s[:max(end - len(next), start)] + next + s[end:]
return s
def getPossibleNextVersions(version):
"""Return possibly next versions for a given version.
There's a few distinct cases here:
* ESRs: The only possible next version is the next minor version.
Eg: 17.0.3esr -> 17.0.4esr
* Betas: The next beta with the same major version and also the next
major version's beta 1. Eg: 18.0b4 -> 18.0b5, 19.0b1
* Other: The next major version's .0 release and the next minor version.
Eg: 15.0 -> 15.0.1, 16.0; 17.0.2 -> 17.0.3, 18.0
Versions with 'pre' are deprecated, and explicitly not supported.
"""
ret = set()
# Get the parts we care about from the version. The last group is the 'pre'
# tag, which doesn't affect our work.
m = re.match(ANY_VERSION_REGEX, version)
if not m:
return ret
base, beta, _, esr = m.groups()[:4]
# The next major version is used in a couple of places, so we figure it out
# ahead of time. Eg: 17.0 -> 18.0 or 15.0.3 -> 16.0
nextMajorVersion = increment(base.split('.')[0]) + '.0'
# Modern ESRs have two possibilities:
# 1) Bump the second digit for a planned release and reset the third digit
# to 0.
# 2) Bump the last digit for an unexpected release
#
# Prior to ESR 24 we did #2 for all types of releases.
if esr:
# if version is like N.0esr, add an extra 0 to make it bump properly
if version.count('.') < 2:
version = version.replace('esr', '.0esr')
first, second, _ = version.split('.', 2)
if int(first) >= 24:
ret.add('%s.%s.0esr' % (first, increment(second)))
ret.add(increment(version))
# Betas are similar, except we need the next major version's beta 1, too.
elif beta:
ret.add(increment(version))
ret.add('%sb1' % nextMajorVersion)
# Other releases are a bit more complicated, because we need to handle
# going from a x.y -> x.y.z version number.
else:
ret.add(nextMajorVersion)
if isFinalRelease(version):
ret.add('%s.1' % version)
else:
ret.add(increment(version))
return ret