Source code for hal.cvs.gits
#!/usr/bin/env python
# coding: utf-8
"""Handles main models in git repository"""
from git import Repo
from unidiff import PatchSet
from hal.cvs.versioning import Version
[docs]class Diff:
"""Git diff result"""
ADD = "added"
DEL = "removed"
def __init__(self, diff):
"""
:param diff: Diff between 2 commits
"""
self.diff = diff
def __str__(self):
totals = self.get_totals()
return "+", totals[self.ADD], " -", totals[self.DEL]
[docs] def get_totals(self):
"""Calculates total additions and deletions
:return: Dictionary with totals
"""
total_added = 0
total_removed = 0
patch = PatchSet(self.diff)
total_added += sum([
edit.added for edit in patch
])
total_removed += sum([
edit.removed for edit in patch
])
return {
self.ADD: total_added,
self.DEL: total_removed
}
[docs]class Commit:
"""Git repository commit"""
def __init__(self, commit):
"""
:param commit: Commit of repository
"""
self.commit = commit
def __str__(self, date_format="%H:%M:%S %y-%m-%d %z"):
"""
Converts to string
:param date_format: Format date and times with this format
:return: Pretty description of commit
"""
hash_value = self.commit.hexsha
date_time = self.commit.authored_datetime.strftime(date_format)
return hash_value + " at " + date_time
[docs] def get_author(self):
"""Gets author
:return: author of commit
"""
author = self.commit.author
out = ""
if author.name is not None:
out += author.name
if author.email is not None:
out += " (" + author.email + ")"
return out
[docs]class Repository:
"""Git repository"""
def __init__(self, repo_path):
"""
:param repo_path: Path to repository
"""
self.repo = Repo(repo_path)
[docs] def get_last_commit(self):
"""Gets last commit
:return: Last commit of repository
"""
return self.repo.head.commit
[docs] def get_diff_amounts(self):
"""Gets list of total diff
:return: List of total diff between 2 consecutive commits since start
"""
diffs = []
last_commit = None
for commit in self.repo.iter_commits():
if last_commit is not None:
diff = self.get_diff(commit.hexsha, last_commit.hexsha)
total_changed = diff[Diff.ADD] + diff[Diff.DEL]
diffs.append(total_changed)
last_commit = commit
return diffs
[docs] def get_diff(self, commit, other_commit):
"""Calculates total additions and deletions
:param commit: First commit
:param other_commit: Second commit
:return: dictionary: Dictionary with total additions and deletions
"""
print(other_commit, "VS", commit)
diff = self.repo.git.diff(commit, other_commit)
return Diff(diff).get_totals()
[docs] def get_version(self, diff_to_increase_ratio):
"""Gets version
:param diff_to_increase_ratio: Ratio to convert number of changes into
:return: Version of this code, based on commits diffs
"""
diffs = self.get_diff_amounts()
version = Version()
for diff in diffs:
version.increase_by_changes(diff, diff_to_increase_ratio)
return version
[docs] def get_new_version(self, last_version, last_commit,
diff_to_increase_ratio):
"""Gets new version
:param last_version: last version known
:param last_commit: hash of commit of last version
:param diff_to_increase_ratio: Ratio to convert number of changes into
:return: new version
"""
version = Version(last_version)
diff = self.get_diff(last_commit, self.get_last_commit_hash())
total_changed = diff[Diff.ADD] + diff[Diff.DEL]
version.increase_by_changes(total_changed, diff_to_increase_ratio)
return version
[docs] def get_pretty_version(self, diff_to_increase_ratio):
"""Pretty version
:param diff_to_increase_ratio: Ratio to convert number of changes into
version increases
:return: string: Pretty version of this repository
"""
version = self.get_version(diff_to_increase_ratio)
build = self.get_last_commit_hash()
return str(version) + " (" + build + ")"
[docs] def get_last_commit_hash(self):
"""Gets hash of last commit
:return: hash of last commit
"""
last = self.get_last_commit()
return str(last.hexsha)