Skip to content

Commit

Permalink
fix default regexp and add lazy calc of churn
Browse files Browse the repository at this point in the history
  • Loading branch information
felipecrp committed Apr 15, 2019
1 parent 7dad30b commit 4a38f1f
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 41 deletions.
48 changes: 28 additions & 20 deletions releasy/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(self, name, path, regexp=None):
self.release_pattern = re.compile(regexp)
self._config_ctrl.append('release_pattern')
if not self.release_pattern: # default
self.release_pattern = re.compile(r'^.*?(?:[^0-9\.])(?P<major>[0-9]+)\.(?P<minor>[0-9]+)\.(?P<patch>[0-9]+)$')
self.release_pattern = re.compile(r'^(?:.*?[^0-9\.])?(?P<major>[0-9]+)\.(?P<minor>[0-9]+)\.(?P<patch>[0-9]+)$')
# self.release_pattern = re.compile(r'^.*(?P<major>[0-9]+)[\._\-](?P<minor>[0-9]+)[\._\-](?P<patch>[0-9]+)$')

def __repr__(self):
Expand Down Expand Up @@ -156,7 +156,7 @@ def __init__(self, project, tag):
self._tails = []
self.developers = DeveloperRoleTracker(self.project)
self._base_releases = []
self.__commit_stats = CommitStats()
self.__commit_stats = None
self.__first_commit = None

def __repr__(self):
Expand Down Expand Up @@ -187,8 +187,6 @@ def base_releases(self):
def add_base_release(self, base_release):
if base_release != self and base_release not in self._base_releases:
self._base_releases.append(base_release)
stats = base_release.head.diff_stats(self.head)
self.__commit_stats += stats

@property
def tails(self):
Expand All @@ -199,10 +197,6 @@ def add_tail(self, commit):
self._tails.append(commit)
if not self.__first_commit or self.__first_commit.author_time > commit.author_time:
self.__first_commit = commit

if not commit.parents: # root commit
stats = self.head.diff_stats() #todo avaliar
self.__commit_stats += stats

@property
def typename(self):
Expand Down Expand Up @@ -266,6 +260,16 @@ def length(self):

@property
def churn(self):
if self.__commit_stats:
return self.__commit_stats.churn

self.__commit_stats = CommitStats()
if self.base_releases:
for base_release in self.base_releases:
self.__commit_stats += self.head.diff_stats(base_release.head)
else:
self.__commit_stats = self.head.diff_stats()

return self.__commit_stats.churn


Expand Down Expand Up @@ -364,17 +368,16 @@ class CommitTracker():
def __init__(self):
self._commits = {}
self._totals = {
'churn': 0,
'churn': -1,
'merges': 0
}

def add(self, commit):
if commit:
if commit not in self._commits:
self._commits[commit] = commit
self._totals['churn'] += commit.churn
if len(commit.parents) > 1:
self._totals['merges'] += 1
if len(commit.parents) > 1:
self._totals['merges'] += 1

def list(self):
return self._commits.keys()
Expand All @@ -385,11 +388,16 @@ def contains(self, commit):
def count(self):
return len(self.list())

def total(self, attribute=None):
if not attribute:
def total(self, metric=None):
if not metric:
return self.count()
elif attribute in self._totals:
return self._totals[attribute]
elif metric in self._totals:
# since churn is cpu intensive, we lazy calc them
if metric == 'churn' and self._totals[metric] == -1:
self._totals['churn'] = 0
for commit in self.list():
self._totals['churn'] += commit.churn
return self._totals[metric]
else:
return -1

Expand Down Expand Up @@ -535,8 +543,6 @@ def track_release(project: Project, release: Release):
commit_stack = [ release.head ]
while len(commit_stack):
cur_commit = commit_stack.pop()

# handle multiple tags pointing to a single commit
if not is_tracked_commit(cur_commit):
track_commit(project, release, cur_commit)

Expand All @@ -549,8 +555,10 @@ def track_release(project: Project, release: Release):
else:
track_base_release(release, cur_commit)

# release.tails = sorted(release.tails, key=lambda commit: commit.time)
# release.tails = sorted(release.tails, key=lambda commit: commit.author_time)
if release.commits.count() == 0: # releases that point to tracke commits
cur_commit = release.head
for parent_commit in cur_commit.parents:
track_base_release(release, cur_commit, parent_commit)


def track_commit(project, release, commit):
Expand Down
34 changes: 17 additions & 17 deletions releasy/model_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

from releasy.model import Project, Vcs, Tag, Commit, CommitStats

RELEASY_FT_COMMIT_CHURN = 0
RELEASY_FT_CHURN = 0

class GitVcs(Vcs):
""" Encapsulate Git Version Control System using pygit2 lib
Expand Down Expand Up @@ -110,28 +108,30 @@ def parents(self):
def stats(self) -> CommitStats:
if not self._stats:
self._stats = CommitStats()
if RELEASY_FT_COMMIT_CHURN:
if self.__raw.parents:
for raw_parent in self.__raw.parents:
diff = self.__raw.tree.diff_to_tree(raw_parent.tree)
self._stats += diff.stats
else:
diff = self.__raw.tree.diff_to_tree()
if self.__raw.parents:
for raw_parent in self.__raw.parents:
diff = self.__raw.tree.diff_to_tree(raw_parent.tree)
self._stats += diff.stats
else:
diff = self.__raw.tree.diff_to_tree()
self._stats += diff.stats
return self._stats

#todo this method is not in the best place
# consider change it to some util class
def diff_stats(self, commit=None):
""" Calculate diff stats from another commit. This method is useful to
calculate release churn """

stats = CommitStats()
if RELEASY_FT_CHURN:
if commit:
diff = self.__raw.tree.diff_to_tree(commit.__raw.tree)
else:
diff = self.__raw.tree.diff_to_tree()
stats.insertions += diff.stats.insertions
stats.deletions += diff.stats.deletions
stats.files_changed += diff.stats.files_changed
if commit:
diff = self.__raw.tree.diff_to_tree(commit.__raw.tree)
else:
diff = self.__raw.tree.diff_to_tree()
# intentionaly inverted
stats.insertions = diff.stats.deletions
stats.deletions = diff.stats.insertions
stats.files_changed = diff.stats.files_changed
return stats


Expand Down
8 changes: 4 additions & 4 deletions tests/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ def print_release_stat(project):
'release': str(release),
'time': str(release.time),
'typename': release.typename,
'churn': release.churn,
'commits': release.commits.count(),
'commits.churn': release.commits.total('churn'),
'churn': release.churn,
'rework': release.commits.total('churn') - release.churn,
'merges': release.commits.total('merges'),
'developers': release.developers.count(),
Expand All @@ -40,9 +40,9 @@ def print_release_stat(project):

# releasy.model_git.RELEASY_FT_COMMIT_CHURN = 1

# project = ProjectFactory.create(".", GitVcs())
project = ProjectFactory.create("../../repos/discourse.git", GitVcs())
#project = ProjectFactory.create("../../repos/angular", GitVcs())
project = ProjectFactory.create(".", GitVcs())
# project = ProjectFactory.create("../../repos/discourse.git", GitVcs())
# project = ProjectFactory.create("../../repos/angular", GitVcs())
# project = Project.create("local", "../repos/atom", GitVcs())
# project = Project.create("local", "../repos/mongo", GitVcs())
#project = Project.create("local", "../repos/old/puppet", GitVcs())
Expand Down

0 comments on commit 4a38f1f

Please sign in to comment.