# coding: utf-8 # # Copyright © 2012 Ejwa Software. All rights reserved. # # This file is part of gitinspector. # # gitinspector is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # gitinspector is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with gitinspector. If not, see . import extensions import os import re import terminal class FileDiff: def __init__(self, string): commit_line = string.split("|") if commit_line.__len__() == 2: self.name = commit_line[0].strip() self.insertions = commit_line[1].count("+") self.deletions = commit_line[1].count("-") @staticmethod def is_filediff_line(string): string = string.split("|") return string.__len__() == 2 and string[1].find("Bin") == -1 and ('+' in string[1] or '-' in string[1]) @staticmethod def get_extension(string): string = string.split("|")[0].strip().strip("{}") return os.path.splitext(string)[1][1:] @staticmethod def is_valid_extension(string): extension = FileDiff.get_extension(string) for i in extensions.get(): if extension == i: return True return False class Commit: def __init__(self, string): self.filediffs = [] commit_line = string.split("|") if commit_line.__len__() == 4: self.date = commit_line[0] self.sha = commit_line[1] self.author = re.sub("[^\w ]", "", commit_line[2].strip()) self.message = commit_line[3].strip() def add_filediff(self, filediff): self.filediffs.append(filediff) def get_filediffs(self): return self.filediffs @staticmethod def is_commit_line(string): return string.split("|").__len__() == 4 class AuthorInfo: insertions = 0 deletions = 0 commits = 0 class Changes: def __init__(self, hard): self.commits = [] git_log_r = os.popen("git log --pretty='%ad|%t|%aN|%s' --stat=100000 --no-merges -w " + "{0} --date=short".format("-C -C -M" if hard else "")) commit = None found_valid_extension = False lines = git_log_r.readlines() for i in lines: if Commit.is_commit_line(i) or i == lines[-1]: if found_valid_extension: self.commits.append(commit) found_valid_extension = False commit = Commit(i) if FileDiff.is_filediff_line(i): extensions.add_located(FileDiff.get_extension(i)) if FileDiff.is_valid_extension(i): found_valid_extension = True filediff = FileDiff(i) commit.add_filediff(filediff) def get_commits(self): return self.commits @staticmethod def __modify_authorinfo__(authors, key, commit): if authors.get(key, None) == None: authors[key] = AuthorInfo() authors[key].commits += 1 for j in commit.get_filediffs(): authors[key].insertions += j.insertions authors[key].deletions += j.deletions def get_authorinfo_list(self): authors = {} for i in self.commits: Changes.__modify_authorinfo__(authors, i.author, i) return authors def get_authordateinfo_list(self): authors = {} for i in self.commits: Changes.__modify_authorinfo__(authors, (i.date, i.author), i) return authors __changes__ = None def get(hard): global __changes__ if __changes__ == None: __changes__ = Changes(hard) return __changes__ def output(hard): get(hard) authorinfo_list = get(hard).get_authorinfo_list() total_changes = 0.0 for i in authorinfo_list: total_changes += authorinfo_list.get(i).insertions total_changes += authorinfo_list.get(i).deletions if authorinfo_list: print "The following historical commit information, by author, was found in the" print "repository:\n" terminal.printb("Author".ljust(21) + "Commits " + "Insertions " + "Deletions " + "% of changes") for i in sorted(authorinfo_list): authorinfo = authorinfo_list.get(i) percentage = 0 if total_changes == 0 else (authorinfo.insertions + authorinfo.deletions) / total_changes * 100 print i.ljust(20)[0:20], print str(authorinfo.commits).rjust(7), print str(authorinfo.insertions).rjust(12), print str(authorinfo.deletions).rjust(11), print "{0:.2f}".format(percentage).rjust(14) else: print "No commited files with the specified extensions were found."