2019-04-08 15:33:05 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
import functools
|
2020-06-29 12:13:19 +00:00
|
|
|
import logging
|
2019-04-08 15:33:05 +00:00
|
|
|
import os
|
|
|
|
import re
|
|
|
|
|
|
|
|
|
2021-02-17 15:55:24 +00:00
|
|
|
class RepositoryBase:
|
2020-06-29 12:13:19 +00:00
|
|
|
def __init__(self, repo_path):
|
2020-07-22 01:05:46 +00:00
|
|
|
import git
|
|
|
|
|
2019-04-08 15:33:05 +00:00
|
|
|
self._repo = git.Repo(repo_path, search_parent_directories=(not repo_path))
|
|
|
|
|
2021-02-17 15:55:24 +00:00
|
|
|
# comparator of commits
|
2019-04-08 15:33:05 +00:00
|
|
|
def cmp(x, y):
|
2021-02-17 15:55:24 +00:00
|
|
|
if str(x) == str(y):
|
2019-04-08 15:33:05 +00:00
|
|
|
return 0
|
|
|
|
if self._repo.is_ancestor(x, y):
|
|
|
|
return -1
|
|
|
|
else:
|
|
|
|
return 1
|
|
|
|
self.comparator = functools.cmp_to_key(cmp)
|
|
|
|
|
|
|
|
def get_head_commit(self):
|
|
|
|
return self._repo.commit(self._default)
|
|
|
|
|
|
|
|
def iterate(self, begin, end):
|
|
|
|
rev_range = '{}...{}'.format(begin, end)
|
|
|
|
for commit in self._repo.iter_commits(rev_range, first_parent=True):
|
|
|
|
yield commit
|
|
|
|
|
2020-07-22 01:05:46 +00:00
|
|
|
|
2020-06-29 12:13:19 +00:00
|
|
|
class Repository(RepositoryBase):
|
|
|
|
def __init__(self, repo_path, remote_name, default_branch_name):
|
|
|
|
super(Repository, self).__init__(repo_path)
|
|
|
|
self._remote = self._repo.remotes[remote_name]
|
2020-07-22 01:05:46 +00:00
|
|
|
self._remote.fetch()
|
2020-06-29 12:13:19 +00:00
|
|
|
self._default = self._remote.refs[default_branch_name]
|
|
|
|
|
|
|
|
def get_release_branches(self):
|
|
|
|
'''
|
|
|
|
Returns sorted list of tuples:
|
2019-04-09 09:55:10 +00:00
|
|
|
* remote branch (git.refs.remote.RemoteReference),
|
|
|
|
* base commit (git.Commit),
|
|
|
|
* head (git.Commit)).
|
2019-04-08 15:33:05 +00:00
|
|
|
List is sorted by commits in ascending order.
|
2020-06-29 12:13:19 +00:00
|
|
|
'''
|
|
|
|
release_branches = []
|
|
|
|
|
|
|
|
RE_RELEASE_BRANCH_REF = re.compile(r'^refs/remotes/.+/\d+\.\d+$')
|
|
|
|
|
|
|
|
for branch in [r for r in self._remote.refs if RE_RELEASE_BRANCH_REF.match(r.path)]:
|
|
|
|
base = self._repo.merge_base(self._default, self._repo.commit(branch))
|
|
|
|
if not base:
|
|
|
|
logging.info('Branch %s is not based on branch %s. Ignoring.', branch.path, self._default)
|
|
|
|
elif len(base) > 1:
|
|
|
|
logging.info('Branch %s has more than one base commit. Ignoring.', branch.path)
|
|
|
|
else:
|
|
|
|
release_branches.append((os.path.basename(branch.name), base[0]))
|
|
|
|
|
|
|
|
return sorted(release_branches, key=lambda x : self.comparator(x[1]))
|
|
|
|
|
2020-07-22 01:05:46 +00:00
|
|
|
|
2020-06-29 12:13:19 +00:00
|
|
|
class BareRepository(RepositoryBase):
|
|
|
|
def __init__(self, repo_path, default_branch_name):
|
|
|
|
super(BareRepository, self).__init__(repo_path)
|
|
|
|
self._default = self._repo.branches[default_branch_name]
|
|
|
|
|
2020-05-25 11:10:14 +00:00
|
|
|
def get_release_branches(self):
|
2020-06-29 12:13:19 +00:00
|
|
|
'''
|
|
|
|
Returns sorted list of tuples:
|
|
|
|
* branch (git.refs.head?),
|
|
|
|
* base commit (git.Commit),
|
|
|
|
* head (git.Commit)).
|
|
|
|
List is sorted by commits in ascending order.
|
|
|
|
'''
|
2020-05-25 11:10:14 +00:00
|
|
|
release_branches = []
|
2019-04-08 15:33:05 +00:00
|
|
|
|
2020-06-29 12:13:19 +00:00
|
|
|
RE_RELEASE_BRANCH_REF = re.compile(r'^refs/heads/\d+\.\d+$')
|
|
|
|
|
|
|
|
for branch in [r for r in self._repo.branches if RE_RELEASE_BRANCH_REF.match(r.path)]:
|
2020-05-25 11:10:14 +00:00
|
|
|
base = self._repo.merge_base(self._default, self._repo.commit(branch))
|
2019-04-08 15:33:05 +00:00
|
|
|
if not base:
|
2020-06-29 12:13:19 +00:00
|
|
|
logging.info('Branch %s is not based on branch %s. Ignoring.', branch.path, self._default)
|
2019-04-08 15:33:05 +00:00
|
|
|
elif len(base) > 1:
|
2020-06-29 12:13:19 +00:00
|
|
|
logging.info('Branch %s has more than one base commit. Ignoring.', branch.path)
|
2019-04-08 15:33:05 +00:00
|
|
|
else:
|
2020-05-25 11:10:14 +00:00
|
|
|
release_branches.append((os.path.basename(branch.name), base[0]))
|
2019-04-08 15:33:05 +00:00
|
|
|
|
2020-05-25 11:10:14 +00:00
|
|
|
return sorted(release_branches, key=lambda x : self.comparator(x[1]))
|