auto-semver/semver/__init__.py
2018-05-25 14:14:29 -04:00

134 lines
4.6 KiB
Python

import re
import subprocess
try:
from configparser import ConfigParser
except ImportError:
# Python < 3
from ConfigParser import ConfigParser
version = "1.0.5"
class SemVer(object):
GET_COMMIT_MESSAGE = re.compile(r"Merge (branch|pull request) '?(.+)'? (into|from) ([\w/-]+)")
#Merge pull request #1 from RightBrain-Networks/feature/PLAT-185-versioning
def __init__(self):
self.merged_branch = None
self.main_branch = None
self.version_type = None
self.main_branches = self._setting_to_array('main_branches')
self.major_branches = self._setting_to_array('major_branches')
self.minor_branches = self._setting_to_array('minor_branches')
self.patch_branches = self._setting_to_array('patch_branches')
def _setting_to_array(self, setting):
config = ConfigParser()
config.read('./.bumpversion.cfg')
value = config.get('semver', setting)
# filter() removes empty string which is what we get if setting is blank
return list(filter(bool, [v.strip() for v in value.split(',')]))
# based on commit message see what branches are involved in the merge
def get_branches(self):
p = subprocess.Popen(['git', 'log', '-1'], stdout=subprocess.PIPE,
cwd='.')
#check current branch
b = subprocess.Popen(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], stdout=subprocess.PIPE,
cwd='.')
message = str(p.stdout.read())
br = b.stdout.read().decode('utf-8')
#remove newline
branch=br.rstrip()
print("Main branch is "+branch)
matches = self.GET_COMMIT_MESSAGE.search(message)
if matches:
if str(matches.group(4)) == branch:
self.merged_branch = matches.group(2)
else:
self.merged_branch = matches.group(4)
self.main_branch = branch
#print("group1 "+matches.group(1))
#print("group2 "+matches.group(2))
#print("group3 "+matches.group(3))
#print("group4 "+matches.group(4))
return bool(matches)
# based on branches involved see what type of versioning should be done
def get_version_type(self):
print("Merged branch is "+self.merged_branch)
for prefix in self.major_branches:
if self.merged_branch.startswith(prefix + '/'):
self.version_type = 'major'
return True
for prefix in self.minor_branches:
if self.merged_branch.startswith(prefix + '/'):
self.version_type = 'minor'
return True
for prefix in self.patch_branches:
if self.merged_branch.startswith(prefix + '/'):
self.version_type = 'patch'
return True
return False
# setup git settings so we can commit and tag
def setup_git_user(self):
# setup git user
p = subprocess.Popen(['git', 'config', 'user.email',
'"versioner@semver.com"'],
cwd='.')
p = subprocess.Popen(['git', 'config', 'user.name',
'"Semantic Versioner"'],
cwd='.')
p.wait()
return self
# use bumpversion to increment the appropriate version type
def version_repo(self):
# version repo
p = subprocess.Popen(['bumpversion', self.version_type],
cwd='.')
p.wait()
return self
def commit_and_push(self):
# push versioning commit
p = subprocess.Popen(['git', 'push', 'origin', self.main_branch],
cwd='.')
p.wait()
# push versioning tag
p = subprocess.Popen(['git', 'push', 'origin', '--tags'],
cwd='.')
p.wait()
return self
# 1) get branches from last commit message
# 2) see if we're merging into a main branch
# 3) see what type of versioning we should do
# 4) version the repo
def run(self):
if not self.get_branches():
raise Exception('No merge found')
if self.main_branch not in self.main_branches:
raise Exception('Not merging into a main branch')
if not self.get_version_type():
raise Exception('No git flow branch found')
self.setup_git_user()
self.version_repo()
self.commit_and_push()
return self
def main():
try:
SemVer().run()
except Exception as e:
print(e)
if __name__ == '__main__':
try: main()
except: raise