2014-09-24 16:48:57 -04:00
|
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
|
|
# this work for additional information regarding copyright ownership.
|
|
|
|
# The ASF licenses this file to You 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 argparse
|
|
|
|
import re
|
|
|
|
import subprocess
|
|
|
|
import sys
|
2019-06-11 04:17:10 -04:00
|
|
|
import os
|
2016-04-11 17:22:40 -04:00
|
|
|
from enum import Enum
|
2019-06-11 04:17:10 -04:00
|
|
|
import time
|
|
|
|
import urllib.request, urllib.error, urllib.parse
|
|
|
|
import urllib.parse
|
2014-09-24 16:48:57 -04:00
|
|
|
|
|
|
|
class Version(object):
|
|
|
|
def __init__(self, major, minor, bugfix, prerelease):
|
|
|
|
self.major = major
|
|
|
|
self.minor = minor
|
|
|
|
self.bugfix = bugfix
|
|
|
|
self.prerelease = prerelease
|
|
|
|
self.previous_dot_matcher = self.make_previous_matcher()
|
|
|
|
self.dot = '%d.%d.%d' % (self.major, self.minor, self.bugfix)
|
|
|
|
self.constant = 'LUCENE_%d_%d_%d' % (self.major, self.minor, self.bugfix)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def parse(cls, value):
|
|
|
|
match = re.search(r'(\d+)\.(\d+).(\d+)(.1|.2)?', value)
|
|
|
|
if match is None:
|
|
|
|
raise argparse.ArgumentTypeError('Version argument must be of format x.y.z(.1|.2)?')
|
|
|
|
parts = [int(v) for v in match.groups()[:-1]]
|
|
|
|
parts.append({ None: 0, '.1': 1, '.2': 2 }[match.groups()[-1]])
|
|
|
|
return Version(*parts)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.dot
|
|
|
|
|
|
|
|
def make_previous_matcher(self, prefix='', suffix='', sep='\\.'):
|
|
|
|
if self.is_bugfix_release():
|
|
|
|
pattern = '%s%s%s%s%d' % (self.major, sep, self.minor, sep, self.bugfix - 1)
|
|
|
|
elif self.is_minor_release():
|
|
|
|
pattern = '%s%s%d%s\\d+' % (self.major, sep, self.minor - 1, sep)
|
|
|
|
else:
|
|
|
|
pattern = '%d%s\\d+%s\\d+' % (self.major - 1, sep, sep)
|
|
|
|
|
|
|
|
return re.compile(prefix + '(' + pattern + ')' + suffix)
|
|
|
|
|
|
|
|
def is_bugfix_release(self):
|
|
|
|
return self.bugfix != 0
|
|
|
|
|
|
|
|
def is_minor_release(self):
|
|
|
|
return self.bugfix == 0 and self.minor != 0
|
|
|
|
|
|
|
|
def is_major_release(self):
|
|
|
|
return self.bugfix == 0 and self.minor == 0
|
|
|
|
|
|
|
|
def on_or_after(self, other):
|
|
|
|
return (self.major > other.major or self.major == other.major and
|
|
|
|
(self.minor > other.minor or self.minor == other.minor and
|
|
|
|
(self.bugfix > other.bugfix or self.bugfix == other.bugfix and
|
|
|
|
self.prerelease >= other.prerelease)))
|
|
|
|
|
2019-06-11 04:17:10 -04:00
|
|
|
def gt(self, other):
|
|
|
|
return (self.major > other.major or
|
|
|
|
(self.major == other.major and self.minor > other.minor) or
|
|
|
|
(self.major == other.major and self.minor == other.minor and self.bugfix > other.bugfix))
|
|
|
|
|
2016-06-25 14:26:42 -04:00
|
|
|
def is_back_compat_with(self, other):
|
|
|
|
if not self.on_or_after(other):
|
|
|
|
raise Exception('Back compat check disallowed for newer version: %s < %s' % (self, other))
|
|
|
|
return other.major + 1 >= self.major
|
|
|
|
|
2019-06-11 04:17:10 -04:00
|
|
|
def run(cmd, cwd=None):
|
2014-09-24 16:48:57 -04:00
|
|
|
try:
|
2019-06-11 04:17:10 -04:00
|
|
|
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, cwd=cwd)
|
2014-09-24 16:48:57 -04:00
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
print(e.output.decode('utf-8'))
|
|
|
|
raise e
|
|
|
|
return output.decode('utf-8')
|
|
|
|
|
|
|
|
def update_file(filename, line_re, edit):
|
|
|
|
infile = open(filename, 'r')
|
|
|
|
buffer = []
|
|
|
|
|
|
|
|
changed = False
|
|
|
|
for line in infile:
|
|
|
|
if not changed:
|
|
|
|
match = line_re.search(line)
|
|
|
|
if match:
|
|
|
|
changed = edit(buffer, match, line)
|
|
|
|
if changed is None:
|
|
|
|
return False
|
|
|
|
continue
|
|
|
|
buffer.append(line)
|
|
|
|
if not changed:
|
|
|
|
raise Exception('Could not find %s in %s' % (line_re, filename))
|
|
|
|
with open(filename, 'w') as f:
|
|
|
|
f.write(''.join(buffer))
|
|
|
|
return True
|
|
|
|
|
2019-06-11 04:17:10 -04:00
|
|
|
|
2016-05-13 17:06:16 -04:00
|
|
|
# branch types are "release", "stable" and "unstable"
|
2016-04-11 17:22:40 -04:00
|
|
|
class BranchType(Enum):
|
2016-05-13 17:06:16 -04:00
|
|
|
unstable = 1
|
|
|
|
stable = 2
|
|
|
|
release = 3
|
2016-04-11 17:22:40 -04:00
|
|
|
|
2014-09-24 16:48:57 -04:00
|
|
|
def find_branch_type():
|
2016-02-10 17:55:07 -05:00
|
|
|
output = subprocess.check_output('git status', shell=True)
|
2014-09-24 16:48:57 -04:00
|
|
|
for line in output.split(b'\n'):
|
2016-02-10 17:55:07 -05:00
|
|
|
if line.startswith(b'On branch '):
|
|
|
|
branchName = line.split(b' ')[-1]
|
2014-09-24 16:48:57 -04:00
|
|
|
break
|
|
|
|
else:
|
2016-02-10 17:55:07 -05:00
|
|
|
raise Exception('git status missing branch name')
|
2014-09-24 16:48:57 -04:00
|
|
|
|
2016-02-10 17:55:07 -05:00
|
|
|
if branchName == b'master':
|
2016-05-13 17:06:16 -04:00
|
|
|
return BranchType.unstable
|
2016-03-31 09:35:48 -04:00
|
|
|
if re.match(r'branch_(\d+)x', branchName.decode('UTF-8')):
|
2016-04-11 17:22:40 -04:00
|
|
|
return BranchType.stable
|
2016-03-31 09:35:48 -04:00
|
|
|
if re.match(r'branch_(\d+)_(\d+)', branchName.decode('UTF-8')):
|
2016-04-11 17:22:40 -04:00
|
|
|
return BranchType.release
|
2016-05-13 15:36:31 -04:00
|
|
|
raise Exception('Cannot run %s on feature branch' % sys.argv[0].rsplit('/', 1)[-1])
|
2014-09-24 16:48:57 -04:00
|
|
|
|
2019-06-11 04:17:10 -04:00
|
|
|
|
|
|
|
def download(name, urlString, tmpDir, quiet=False, force_clean=True):
|
|
|
|
if not quiet:
|
|
|
|
print("Downloading %s" % urlString)
|
|
|
|
startTime = time.time()
|
|
|
|
fileName = '%s/%s' % (tmpDir, name)
|
|
|
|
if not force_clean and os.path.exists(fileName):
|
|
|
|
if not quiet and fileName.find('.asc') == -1:
|
|
|
|
print(' already done: %.1f MB' % (os.path.getsize(fileName)/1024./1024.))
|
|
|
|
return
|
|
|
|
try:
|
|
|
|
attemptDownload(urlString, fileName)
|
|
|
|
except Exception as e:
|
|
|
|
print('Retrying download of url %s after exception: %s' % (urlString, e))
|
|
|
|
try:
|
|
|
|
attemptDownload(urlString, fileName)
|
|
|
|
except Exception as e:
|
|
|
|
raise RuntimeError('failed to download url "%s"' % urlString) from e
|
|
|
|
if not quiet and fileName.find('.asc') == -1:
|
|
|
|
t = time.time()-startTime
|
|
|
|
sizeMB = os.path.getsize(fileName)/1024./1024.
|
|
|
|
print(' %.1f MB in %.2f sec (%.1f MB/sec)' % (sizeMB, t, sizeMB/t))
|
|
|
|
|
|
|
|
|
|
|
|
def attemptDownload(urlString, fileName):
|
|
|
|
fIn = urllib.request.urlopen(urlString)
|
|
|
|
fOut = open(fileName, 'wb')
|
|
|
|
success = False
|
|
|
|
try:
|
|
|
|
while True:
|
|
|
|
s = fIn.read(65536)
|
|
|
|
if s == b'':
|
|
|
|
break
|
|
|
|
fOut.write(s)
|
|
|
|
fOut.close()
|
|
|
|
fIn.close()
|
|
|
|
success = True
|
|
|
|
finally:
|
|
|
|
fIn.close()
|
|
|
|
fOut.close()
|
|
|
|
if not success:
|
|
|
|
os.remove(fileName)
|
|
|
|
|
2020-10-08 15:25:51 -04:00
|
|
|
version_prop_re = re.compile(r'baseVersion\s*=\s*([\'"])(.*)\1')
|
2014-09-24 16:48:57 -04:00
|
|
|
def find_current_version():
|
2020-10-08 15:25:51 -04:00
|
|
|
script_path = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
top_level_dir = os.path.join(os.path.abspath("%s/" % script_path), os.path.pardir, os.path.pardir)
|
|
|
|
return version_prop_re.search(open('%s/build.gradle' % top_level_dir).read()).group(2).strip()
|
2014-09-24 16:48:57 -04:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
print('This is only a support module, it cannot be run')
|
|
|
|
sys.exit(1)
|