xref: /Lucene/dev-tools/scripts/scriptutil.py (revision 10c775785226263477e10de3ff056bfcf7d6e7f2)
18d885e4fSRyan Ernst# Licensed to the Apache Software Foundation (ASF) under one or more
28d885e4fSRyan Ernst# contributor license agreements.  See the NOTICE file distributed with
38d885e4fSRyan Ernst# this work for additional information regarding copyright ownership.
48d885e4fSRyan Ernst# The ASF licenses this file to You under the Apache License, Version 2.0
58d885e4fSRyan Ernst# (the "License"); you may not use this file except in compliance with
68d885e4fSRyan Ernst# the License.  You may obtain a copy of the License at
78d885e4fSRyan Ernst#
88d885e4fSRyan Ernst#     http://www.apache.org/licenses/LICENSE-2.0
98d885e4fSRyan Ernst#
108d885e4fSRyan Ernst# Unless required by applicable law or agreed to in writing, software
118d885e4fSRyan Ernst# distributed under the License is distributed on an "AS IS" BASIS,
128d885e4fSRyan Ernst# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138d885e4fSRyan Ernst# See the License for the specific language governing permissions and
148d885e4fSRyan Ernst# limitations under the License.
158d885e4fSRyan Ernst
168d885e4fSRyan Ernstimport argparse
178d885e4fSRyan Ernstimport re
188d885e4fSRyan Ernstimport subprocess
198d885e4fSRyan Ernstimport sys
20*10c77578SJan Høydahlfrom enum import Enum
218d885e4fSRyan Ernst
228d885e4fSRyan Ernstclass Version(object):
238d885e4fSRyan Ernst  def __init__(self, major, minor, bugfix, prerelease):
248d885e4fSRyan Ernst    self.major = major
258d885e4fSRyan Ernst    self.minor = minor
268d885e4fSRyan Ernst    self.bugfix = bugfix
278d885e4fSRyan Ernst    self.prerelease = prerelease
288d885e4fSRyan Ernst    self.previous_dot_matcher = self.make_previous_matcher()
298d885e4fSRyan Ernst    self.dot = '%d.%d.%d' % (self.major, self.minor, self.bugfix)
308d885e4fSRyan Ernst    self.constant = 'LUCENE_%d_%d_%d' % (self.major, self.minor, self.bugfix)
318d885e4fSRyan Ernst
328d885e4fSRyan Ernst  @classmethod
338d885e4fSRyan Ernst  def parse(cls, value):
348d885e4fSRyan Ernst    match = re.search(r'(\d+)\.(\d+).(\d+)(.1|.2)?', value)
358d885e4fSRyan Ernst    if match is None:
368d885e4fSRyan Ernst      raise argparse.ArgumentTypeError('Version argument must be of format x.y.z(.1|.2)?')
378d885e4fSRyan Ernst    parts = [int(v) for v in match.groups()[:-1]]
388d885e4fSRyan Ernst    parts.append({ None: 0, '.1': 1, '.2': 2 }[match.groups()[-1]])
398d885e4fSRyan Ernst    return Version(*parts)
408d885e4fSRyan Ernst
418d885e4fSRyan Ernst  def __str__(self):
428d885e4fSRyan Ernst    return self.dot
438d885e4fSRyan Ernst
448d885e4fSRyan Ernst  def make_previous_matcher(self, prefix='', suffix='', sep='\\.'):
458d885e4fSRyan Ernst    if self.is_bugfix_release():
468d885e4fSRyan Ernst      pattern = '%s%s%s%s%d' % (self.major, sep, self.minor, sep, self.bugfix - 1)
478d885e4fSRyan Ernst    elif self.is_minor_release():
488d885e4fSRyan Ernst      pattern = '%s%s%d%s\\d+' % (self.major, sep, self.minor - 1, sep)
498d885e4fSRyan Ernst    else:
508d885e4fSRyan Ernst      pattern = '%d%s\\d+%s\\d+' % (self.major - 1, sep, sep)
518d885e4fSRyan Ernst
528d885e4fSRyan Ernst    return re.compile(prefix + '(' + pattern + ')' + suffix)
538d885e4fSRyan Ernst
548d885e4fSRyan Ernst  def is_bugfix_release(self):
558d885e4fSRyan Ernst    return self.bugfix != 0
568d885e4fSRyan Ernst
578d885e4fSRyan Ernst  def is_minor_release(self):
588d885e4fSRyan Ernst    return self.bugfix == 0 and self.minor != 0
598d885e4fSRyan Ernst
608d885e4fSRyan Ernst  def is_major_release(self):
618d885e4fSRyan Ernst    return self.bugfix == 0 and self.minor == 0
628d885e4fSRyan Ernst
638d885e4fSRyan Ernst  def on_or_after(self, other):
648d885e4fSRyan Ernst    return (self.major > other.major or self.major == other.major and
658d885e4fSRyan Ernst           (self.minor > other.minor or self.minor == other.minor and
668d885e4fSRyan Ernst           (self.bugfix > other.bugfix or self.bugfix == other.bugfix and
678d885e4fSRyan Ernst           self.prerelease >= other.prerelease)))
688d885e4fSRyan Ernst
698d885e4fSRyan Ernstdef run(cmd):
708d885e4fSRyan Ernst  try:
718d885e4fSRyan Ernst    output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
728d885e4fSRyan Ernst  except subprocess.CalledProcessError as e:
738d885e4fSRyan Ernst    print(e.output.decode('utf-8'))
748d885e4fSRyan Ernst    raise e
758d885e4fSRyan Ernst  return output.decode('utf-8')
768d885e4fSRyan Ernst
778d885e4fSRyan Ernstdef update_file(filename, line_re, edit):
788d885e4fSRyan Ernst  infile = open(filename, 'r')
798d885e4fSRyan Ernst  buffer = []
808d885e4fSRyan Ernst
818d885e4fSRyan Ernst  changed = False
828d885e4fSRyan Ernst  for line in infile:
838d885e4fSRyan Ernst    if not changed:
848d885e4fSRyan Ernst      match = line_re.search(line)
858d885e4fSRyan Ernst      if match:
868d885e4fSRyan Ernst        changed = edit(buffer, match, line)
878d885e4fSRyan Ernst        if changed is None:
888d885e4fSRyan Ernst          return False
898d885e4fSRyan Ernst        continue
908d885e4fSRyan Ernst    buffer.append(line)
918d885e4fSRyan Ernst  if not changed:
928d885e4fSRyan Ernst    raise Exception('Could not find %s in %s' % (line_re, filename))
938d885e4fSRyan Ernst  with open(filename, 'w') as f:
948d885e4fSRyan Ernst    f.write(''.join(buffer))
958d885e4fSRyan Ernst  return True
968d885e4fSRyan Ernst
97*10c77578SJan Høydahl# branch types are "release", "stable" and "major"
98*10c77578SJan Høydahlclass BranchType(Enum):
99*10c77578SJan Høydahl  major   = 1
100*10c77578SJan Høydahl  stable  = 2
101*10c77578SJan Høydahl  release = 3
102*10c77578SJan Høydahl
1038d885e4fSRyan Ernstdef find_branch_type():
10470e61fd9SMike McCandless  output = subprocess.check_output('git status', shell=True)
1058d885e4fSRyan Ernst  for line in output.split(b'\n'):
10670e61fd9SMike McCandless    if line.startswith(b'On branch '):
10770e61fd9SMike McCandless      branchName = line.split(b' ')[-1]
1088d885e4fSRyan Ernst      break
1098d885e4fSRyan Ernst  else:
11070e61fd9SMike McCandless    raise Exception('git status missing branch name')
1118d885e4fSRyan Ernst
11270e61fd9SMike McCandless  if branchName == b'master':
113*10c77578SJan Høydahl    return BranchType.major
1146e446c0bSJan Høydahl  if re.match(r'branch_(\d+)x', branchName.decode('UTF-8')):
115*10c77578SJan Høydahl    return BranchType.stable
1166e446c0bSJan Høydahl  if re.match(r'branch_(\d+)_(\d+)', branchName.decode('UTF-8')):
117*10c77578SJan Høydahl    return BranchType.release
1188d885e4fSRyan Ernst  raise Exception('Cannot run bumpVersion.py on feature branch')
1198d885e4fSRyan Ernst
1208d885e4fSRyan Ernstversion_prop_re = re.compile('version\.base=(.*)')
1218d885e4fSRyan Ernstdef find_current_version():
1228d885e4fSRyan Ernst  return version_prop_re.search(open('lucene/version.properties').read()).group(1)
1238d885e4fSRyan Ernst
1248d885e4fSRyan Ernstif __name__ == '__main__':
1258d885e4fSRyan Ernst  print('This is only a support module, it cannot be run')
1268d885e4fSRyan Ernst  sys.exit(1)
127