Page MenuHomec4science

svn.py
No OneTemporary

File Metadata

Created
Thu, May 2, 02:13
"""
Gather info for subversion based repos
"""
__author__ = "Guillaume Anciaux, and Nicolas Richart"
__copyright__ = "Copyright (C) 2015, EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory " \
"(LSMS - Laboratoire de Simulation en Mécanique des Solides)"
__credits__ = ["Guillaume Anciaux", "Nicolas Richart"]
__license__ = "GPL"
__version__ = "1.0"
__maintainer__ = "Nicolas Richart"
__email__ = "nicolas.richart@epfl.ch"
from .. import export
import pysvn
import re
from .. import version_info
@export
class SVNInfo(version_info.VersionInfo):
"""
subversion implementation of the version info class
"""
def __init__(self, repo, filename, rev_to=None, **kwargs):
super().__init__(repo, filename, **kwargs)
self._client = pysvn.Client()
self._root_url = self._client.root_url_from_path(repo)
self._infos = self._client.info(self._filename)
if rev_to is not None:
rev_start = pysvn.Revision(pysvn.opt_revision_kind.date, rev_to.strftime('%s'))
else:
rev_start = pysvn.Revision(pysvn.opt_revision_kind.head)
self._name = self._infos.url.replace(self._root_url, '')
self._logs = self._client.log(self._filename,
strict_node_history=False,
discover_changed_paths=True,
revision_start=rev_start)
prev_name = self._name
self._logs = sorted(self._logs, key=lambda log: log["revision"].number, reverse=True)
for entry in self._logs:
d = entry["date"]
self._modification_dates.append(d)
# checking if the name as changed
old_names = [ ch_path for ch_path in entry["changed_paths"] if
(re.match("{0}.*".format(ch_path["path"]), prev_name)) ]
if len(old_names) > 0 and old_names[0]["copyfrom_path"] is not None:
m = re.match("{0}(.*)".format(old_names[0]["path"]), prev_name)
tmp_prev_name = prev_name
prev_name = "{0}{1}".format(old_names[0]["copyfrom_path"],
m.group(1) if m else "")
self._names[old_names[0]["copyfrom_revision"].number] = tmp_prev_name
self._names[0] = prev_name
# print("\n".join(["{0} {1}".format(n, r) for r, n in self._names.items() ]))
@property
def oldest_name(self):
return self._names[0]
def populate(self, author_db, rev_from=None, rev_to=None):
if rev_from is not None:
rev_end = pysvn.Revision(pysvn.opt_revision_kind.date, rev_from.strftime('%s'))
else:
rev_end = pysvn.Revision(pysvn.opt_revision_kind.number, 0)
if rev_to is not None:
rev_start = pysvn.Revision(pysvn.opt_revision_kind.date, rev_to.strftime('%s'))
else:
rev_start = pysvn.Revision(pysvn.opt_revision_kind.head)
self._logs = self._client.log(self._filename,
strict_node_history=False,
revision_start=rev_start,
revision_end=rev_end)
self._logs = sorted(self._logs, key=lambda log: log["revision"].number)
for entry in self._logs:
auth = entry["author"]
rev = entry["revision"]
d = entry["date"]
msg = entry["message"] if "message" in entry else ""
self._revisions.append(rev)
if auth not in self._author_list:
self._author_list[auth] = []
a = author_db.find_by_user_name(auth)
if not author_db.is_author_in_ignore_list(a):
self._authors.add(a)
self._author_list[auth].append((d, rev, msg))
def __find_previous_release(self, r):
revs = [ rev.number for rev in self._revisions if rev.number < r]
rev = 0 if len(revs) == 0 else max(revs)
return pysvn.Revision(pysvn.opt_revision_kind.number, rev)
def get_modifications(self, revision):
r_pre = pysvn.Revision(pysvn.opt_revision_kind.number, revision.number -1)
# self.__find_previous_release(revision.number)
relevant_rev = max([ n for n in self._names.keys() if revision.number > n ])
try:
# print("{0} r{1}:{2}".format(self._root_url + self._names[relevant_rev],
# r_pre.number,
# revision.number))
res_diff = self._client.diff("/tmp", self._root_url + self._names[relevant_rev],
revision1=r_pre,
revision2=revision,
diff_options=['-b', '-w'])
return res_diff
except Exception as e: pass
return ""
def modifications_by_author(self, author):
a = self._author_list[author]
res = []
for d, r, msg in a:
date = dt.datetime.fromtimestamp(d).strftime("%d-%m-%Y")
info = print_colored("@ {0} rev {1} msg {2}".format(date, r.number, msg), 'blue', attrs=['bold'])
modif = self.get_modifications(r)
res.append([info, modif, modif.split("\n")])
return res

Event Timeline