mirror of
https://github.com/ejwa/gitinspector.git
synced 2025-03-26 02:01:27 +01:00
Added --standard header, output footers for tags and branches, and --per-branch functionality
This commit is contained in:
parent
74d6f64333
commit
a7ffdced1f
5 changed files with 233 additions and 40 deletions
|
@ -235,12 +235,58 @@ class Changes(object):
|
|||
int(self.commits[-1].date[8:10]))
|
||||
|
||||
elif (branch != ""):
|
||||
asdad
|
||||
self.commits = []
|
||||
interval.set_ref("HEAD");
|
||||
git_rev_list_p = subprocess.Popen(["git", "rev-list", "--reverse", branch], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
lines = git_rev_list_p.communicate()[0].splitlines()
|
||||
git_rev_list_p.stdout.close()
|
||||
|
||||
if git_rev_list_p.returncode == 0 and len(lines) > 0:
|
||||
progress_text = _(PROGRESS_TEXT)
|
||||
if repo != None:
|
||||
progress_text = "[%s] " % repo.name + progress_text
|
||||
|
||||
chunks = len(lines) // CHANGES_PER_THREAD
|
||||
self.commits = [None] * (chunks if len(lines) % CHANGES_PER_THREAD == 0 else chunks + 1)
|
||||
first_hash = ""
|
||||
|
||||
for i, entry in enumerate(lines):
|
||||
|
||||
if i % CHANGES_PER_THREAD == CHANGES_PER_THREAD - 1:
|
||||
entry = entry.decode("utf-8", "replace").strip()
|
||||
second_hash = entry
|
||||
ChangesThread.create(hard, self, first_hash, second_hash, i)
|
||||
first_hash = entry + ".."
|
||||
|
||||
if format.is_interactive_format():
|
||||
terminal.output_progress(progress_text, i, len(lines))
|
||||
else:
|
||||
if CHANGES_PER_THREAD - 1 != i % CHANGES_PER_THREAD:
|
||||
entry = entry.decode("utf-8", "replace").strip()
|
||||
second_hash = entry
|
||||
ChangesThread.create(hard, self, first_hash, second_hash, i)
|
||||
|
||||
# Make sure all threads have completed.
|
||||
for i in range(0, NUM_THREADS):
|
||||
__thread_lock__.acquire()
|
||||
|
||||
# We also have to release them for future use.
|
||||
for i in range(0, NUM_THREADS):
|
||||
__thread_lock__.release()
|
||||
self.commits = [item for sublist in self.commits for item in sublist]
|
||||
|
||||
if len(self.commits) > 0:
|
||||
if interval.has_interval():
|
||||
interval.set_ref(self.commits[-1].sha)
|
||||
|
||||
self.first_commit_date = datetime.date(int(self.commits[0].date[0:4]), int(self.commits[0].date[5:7]),
|
||||
int(self.commits[0].date[8:10]))
|
||||
self.last_commit_date = datetime.date(int(self.commits[-1].date[0:4]), int(self.commits[-1].date[5:7]),
|
||||
int(self.commits[-1].date[8:10]))
|
||||
else:
|
||||
self.commits = []
|
||||
interval.set_ref("HEAD");
|
||||
git_rev_list_p = subprocess.Popen(filter(None, ["git", "rev-list", "--reverse", "--no-merges",
|
||||
interval.get_since(), interval.get_until(), "HEAD"]), bufsize=1,
|
||||
git_rev_list_p = subprocess.Popen(["git", "rev-list", "--reverse", "HEAD"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
lines = git_rev_list_p.communicate()[0].splitlines()
|
||||
git_rev_list_p.stdout.close()
|
||||
|
@ -263,11 +309,11 @@ class Changes(object):
|
|||
|
||||
if format.is_interactive_format():
|
||||
terminal.output_progress(progress_text, i, len(lines))
|
||||
else:
|
||||
if CHANGES_PER_THREAD - 1 != i % CHANGES_PER_THREAD:
|
||||
entry = entry.decode("utf-8", "replace").strip()
|
||||
second_hash = entry
|
||||
ChangesThread.create(hard, self, first_hash, second_hash, i)
|
||||
else:
|
||||
if CHANGES_PER_THREAD - 1 != i % CHANGES_PER_THREAD:
|
||||
entry = entry.decode("utf-8", "replace").strip()
|
||||
second_hash = entry
|
||||
ChangesThread.create(hard, self, first_hash, second_hash, i)
|
||||
|
||||
# Make sure all threads have completed.
|
||||
for i in range(0, NUM_THREADS):
|
||||
|
@ -276,7 +322,6 @@ class Changes(object):
|
|||
# We also have to release them for future use.
|
||||
for i in range(0, NUM_THREADS):
|
||||
__thread_lock__.release()
|
||||
|
||||
self.commits = [item for sublist in self.commits for item in sublist]
|
||||
|
||||
if len(self.commits) > 0:
|
||||
|
|
|
@ -152,3 +152,17 @@ def output_footer():
|
|||
print("\n\t}\n}")
|
||||
elif __selected_format__ == "xml":
|
||||
print("</gitinspector>")
|
||||
|
||||
def output_footer_per_tag_or_branch():
|
||||
if __selected_format__ == "html" or __selected_format__ == "htmlembedded":
|
||||
base = basedir.get_basedir()
|
||||
html_footer = __output_html_template__(base + "/html/html.footer")
|
||||
print(html_footer)
|
||||
elif __selected_format__ == "json":
|
||||
print("\t\t},")
|
||||
elif __selected_format__ == "xml":
|
||||
print("</gitinspector>")
|
||||
|
||||
def output_footer_end_of_tag_or_branch():
|
||||
if __selected_format__ == "json":
|
||||
print("\t\t}\n\t}\n}")
|
||||
|
|
|
@ -39,6 +39,7 @@ from .output.metricsoutput import MetricsOutput
|
|||
from .output.responsibilitiesoutput import ResponsibilitiesOutput
|
||||
from .output.responsibility_per_file_output import Responsibility_Per_File_Output
|
||||
from .output.changes_per_tag_output import Changes_Per_Tag_Output
|
||||
from .output.changes_per_branch_output import Changes_Per_Branch_Output
|
||||
from .output.timelineoutput import TimelineOutput
|
||||
|
||||
localization.init()
|
||||
|
@ -58,6 +59,7 @@ class Runner(object):
|
|||
self.per_tag = False
|
||||
self.blame = False
|
||||
self.suppress = False
|
||||
self.standard = False
|
||||
|
||||
def process(self, repos):
|
||||
localization.check_compatibility(version.__version__)
|
||||
|
@ -90,20 +92,20 @@ class Runner(object):
|
|||
os.chdir(repo.location)
|
||||
repo = repo if len(repos) > 1 else None
|
||||
#get list of branches
|
||||
|
||||
process = subprocess.Popen(['git', 'branch', '-r'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
branches = process.communicate()[0].splitlines()
|
||||
for branch in branches:
|
||||
changes = Changes(repo, self.hard, "", branch)
|
||||
summed_blames.append(Blame(repo, self.hard, self.useweeks, changes))
|
||||
summed_changes.append(changes)
|
||||
|
||||
if (branch.find("->") == -1):
|
||||
changes = Changes(repo, self.hard, "", branch.strip())
|
||||
summed_blames.append(Blame(repo, self.hard, self.useweeks, changes))
|
||||
summed_changes.append(changes)
|
||||
|
||||
else:
|
||||
os.chdir(repo.location)
|
||||
repo = repo if len(repos) > 1 else None
|
||||
summed_blames = Blame.__new__(Blame)
|
||||
summed_changes = Changes.__new__(Changes)
|
||||
changes = Changes(repo, self.hard, False, False)
|
||||
summed_blames += Blame(repo, self.hard, self.useweeks, changes)
|
||||
summed_changes += changes
|
||||
changes = Changes(repo, self.hard, "", "")
|
||||
summed_blames.append(Blame(repo, self.hard, self.useweeks, changes))
|
||||
summed_changes.append(changes)
|
||||
|
||||
if self.include_metrics:
|
||||
summed_metrics += MetricsLogic()
|
||||
|
@ -117,7 +119,7 @@ class Runner(object):
|
|||
if self.per_tag:
|
||||
i = 0
|
||||
while (i < len(summed_changes)):
|
||||
if (self.suppress == False):
|
||||
if (self.suppress == False or self.standard == True):
|
||||
outputable.output(Changes_Per_Tag_Output(summed_changes[i], tags[i]))
|
||||
if summed_changes[i].get_commits():
|
||||
if (self.suppress == False or self.blame == True):
|
||||
|
@ -139,38 +141,72 @@ class Runner(object):
|
|||
|
||||
if self.list_file_types:
|
||||
outputable.output(ExtensionsOutput())
|
||||
|
||||
format.output_footer()
|
||||
i = i + 1
|
||||
if (i < len(summed_changes)):
|
||||
format.output_footer_per_tag_or_branch()
|
||||
os.chdir(previous_directory)
|
||||
i = i + 1
|
||||
else:
|
||||
if (self.suppress == False):
|
||||
outputable.output(ChangesOutput(summed_changes))
|
||||
format.output_footer_end_of_tag_or_branch()
|
||||
|
||||
|
||||
elif self.per_branch:
|
||||
i = 0
|
||||
while (i < len(summed_changes)):
|
||||
if (self.suppress == False or self.standard == True ):
|
||||
outputable.output(Changes_Per_Branch_Output(summed_changes[i], branches[i]))
|
||||
if summed_changes[i].get_commits():
|
||||
if (self.suppress == False or self.blame == True):
|
||||
outputable.output(BlameOutput(summed_changes[i], summed_blames[i]))
|
||||
|
||||
if summed_changes.get_commits():
|
||||
if self.timeline:
|
||||
outputable.output(TimelineOutput(summed_changes[i], self.useweeks))
|
||||
|
||||
if self.include_metrics:
|
||||
outputable.output(MetricsOutput(summed_metrics))
|
||||
|
||||
if self.responsibilities:
|
||||
outputable.output(ResponsibilitiesOutput(summed_changes[i], summed_blames[i]))
|
||||
|
||||
if self.per_file:
|
||||
outputable.output(Responsibility_Per_File_Output(summed_changes[i], summed_blames[i]))
|
||||
|
||||
outputable.output(FilteringOutput())
|
||||
|
||||
if self.list_file_types:
|
||||
outputable.output(ExtensionsOutput())
|
||||
i = i + 1
|
||||
if (i < len(summed_changes)):
|
||||
format.output_footer_per_tag_or_branch()
|
||||
os.chdir(previous_directory)
|
||||
format.output_footer_end_of_tag_or_branch()
|
||||
else:
|
||||
if (self.suppress == False or self.standard == True):
|
||||
outputable.output(ChangesOutput(summed_changes[0]))
|
||||
|
||||
if summed_changes[0].get_commits():
|
||||
if (self.suppress == False or self.blame == True):
|
||||
outputable.output(BlameOutput(summed_changes, summed_blames))
|
||||
outputable.output(BlameOutput(summed_changes[0], summed_blames[0]))
|
||||
|
||||
if self.timeline:
|
||||
outputable.output(TimelineOutput(summed_changes, self.useweeks))
|
||||
outputable.output(TimelineOutput(summed_changes[0], self.useweeks))
|
||||
|
||||
if self.include_metrics:
|
||||
outputable.output(MetricsOutput(summed_metrics))
|
||||
|
||||
if self.responsibilities:
|
||||
outputable.output(ResponsibilitiesOutput(summed_changes, summed_blames))
|
||||
outputable.output(ResponsibilitiesOutput(summed_changes[0], summed_blames[0]))
|
||||
|
||||
if self.per_file:
|
||||
outputable.output(Responsibility_Per_File_Output(summed_changes, summed_blames))
|
||||
outputable.output(Responsibility_Per_File_Output(summed_changes[0], summed_blames[0]))
|
||||
|
||||
outputable.output(FilteringOutput())
|
||||
|
||||
if self.list_file_types:
|
||||
outputable.output(ExtensionsOutput())
|
||||
|
||||
|
||||
format.output_footer()
|
||||
os.chdir(previous_directory)
|
||||
|
||||
|
||||
|
||||
def __check_python_version__():
|
||||
if sys.version_info < (2, 6):
|
||||
python_version = str(sys.version_info[0]) + "." + str(sys.version_info[1])
|
||||
|
@ -206,7 +242,7 @@ def main():
|
|||
"hard:true", "help", "list-file-types:true", "localize-output:true",
|
||||
"metrics:true", "responsibilities:true", "since=", "grading:true",
|
||||
"timeline:true", "until=", "version", "weeks:true", "per-file:true", "blame:true", "suppress:false",
|
||||
"per-branch:false", "per-tag:false"])
|
||||
"per-branch:false", "per-tag:false", "standard:true"])
|
||||
repos = __get_validated_git_repos__(set(args))
|
||||
|
||||
#We need the repos above to be set before we read the git config.
|
||||
|
@ -252,6 +288,8 @@ def main():
|
|||
run.blame = True
|
||||
elif o == "--suppress":
|
||||
run.suppress = True
|
||||
elif o == "--standard":
|
||||
run.standard = True
|
||||
elif o == "--since":
|
||||
interval.set_since(a)
|
||||
elif o == "--version":
|
||||
|
|
96
gitinspector/output/changes_per_branch_output.py
Normal file
96
gitinspector/output/changes_per_branch_output.py
Normal file
|
@ -0,0 +1,96 @@
|
|||
# coding: utf-8
|
||||
#
|
||||
# Copyright © 2012-2015 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
import json
|
||||
import textwrap
|
||||
from ..localization import N_
|
||||
from .. import format, gravatar, terminal
|
||||
from .outputable import Outputable
|
||||
|
||||
HISTORICAL_INFO_TEXT = N_("The following historical commit information, by author, for this tag:was found")
|
||||
NO_COMMITED_FILES_TEXT = N_("No commited files with the specified extensions were found")
|
||||
|
||||
class Changes_Per_Branch_Output(Outputable):
|
||||
def __init__(self, changes, branch):
|
||||
self.changes = changes
|
||||
self.branch = branch
|
||||
Outputable.__init__(self)
|
||||
|
||||
def output_json(self):
|
||||
authorinfo_list = self.changes.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:
|
||||
message_json = "\t\t\t\"branch\": \"" + self.branch.strip() + "\",\n"
|
||||
changes_json = ""
|
||||
|
||||
for i in sorted(authorinfo_list):
|
||||
author_email = self.changes.get_latest_email_by_author(i)
|
||||
authorinfo = authorinfo_list.get(i)
|
||||
|
||||
percentage = 0 if total_changes == 0 else (authorinfo.insertions + authorinfo.deletions) / total_changes * 100
|
||||
name_json = "\t\t\t\t\"name\": \"" + i + "\",\n"
|
||||
email_json = "\t\t\t\t\"email\": \"" + author_email + "\",\n"
|
||||
gravatar_json = "\t\t\t\t\"gravatar\": \"" + gravatar.get_url(author_email) + "\",\n"
|
||||
commits_json = "\t\t\t\t\"commits\": " + str(authorinfo.commits) + ",\n"
|
||||
insertions_json = "\t\t\t\t\"insertions\": " + str(authorinfo.insertions) + ",\n"
|
||||
deletions_json = "\t\t\t\t\"deletions\": " + str(authorinfo.deletions) + ",\n"
|
||||
percentage_json = "\t\t\t\t\"percentage_of_changes\": " + "{0:.2f}".format(percentage) + "\n"
|
||||
|
||||
changes_json += ("\t{\n" + name_json + email_json + gravatar_json + commits_json +
|
||||
insertions_json + deletions_json + percentage_json + "\t\t\t\t}")
|
||||
changes_json += ","
|
||||
else:
|
||||
changes_json = changes_json[:-1]
|
||||
|
||||
print("\t\t\"" + self.branch.strip() + "\": {\n" + message_json + "\t\t\t\"authors\": [\n\t\t\t" + changes_json + "\n\t\t\t]\n", end="")
|
||||
else:
|
||||
print("\t\t\"exception\": \"" + "No commited files with the specified extensions were found for this branch" + self.branch + "\"")
|
||||
|
||||
def output_text(self):
|
||||
authorinfo_list = self.changes.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(textwrap.fill("The following historical commit information, by author, for this tag:" + self.branch + " was found" + ":", width=terminal.get_size()[0]) + "\n")
|
||||
terminal.printb(terminal.ljust(_("Author"), 21) + terminal.rjust(_("Commits"), 13) +
|
||||
terminal.rjust(_("Insertions"), 14) + terminal.rjust(_("Deletions"), 15) +
|
||||
terminal.rjust(_("% of changes"), 16))
|
||||
|
||||
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(terminal.ljust(i, 20)[0:20 - terminal.get_excess_column_count(i)], end=" ")
|
||||
print(str(authorinfo.commits).rjust(13), end=" ")
|
||||
print(str(authorinfo.insertions).rjust(13), end=" ")
|
||||
print(str(authorinfo.deletions).rjust(14), end=" ")
|
||||
print("{0:.2f}".format(percentage).rjust(15))
|
||||
else:
|
||||
print(_(NO_COMMITED_FILES_TEXT) + ".")
|
|
@ -43,7 +43,7 @@ class Changes_Per_Tag_Output(Outputable):
|
|||
total_changes += authorinfo_list.get(i).deletions
|
||||
|
||||
if authorinfo_list:
|
||||
message_json = "\t\t\t\"message\": \"" + "The following historical commit information, by author, for this tag:" + self.tag + " was found" + "\",\n"
|
||||
message_json = "\t\t\t\"tag\": \"" + self.tag.strip() + "\",\n"
|
||||
changes_json = ""
|
||||
|
||||
for i in sorted(authorinfo_list):
|
||||
|
@ -59,17 +59,17 @@ class Changes_Per_Tag_Output(Outputable):
|
|||
deletions_json = "\t\t\t\t\"deletions\": " + str(authorinfo.deletions) + ",\n"
|
||||
percentage_json = "\t\t\t\t\"percentage_of_changes\": " + "{0:.2f}".format(percentage) + "\n"
|
||||
|
||||
changes_json += ("{\n" + name_json + email_json + gravatar_json + commits_json +
|
||||
insertions_json + deletions_json + percentage_json + "\t\t\t}")
|
||||
changes_json += ("\t{\n" + name_json + email_json + gravatar_json + commits_json +
|
||||
insertions_json + deletions_json + percentage_json + "\t\t\t\t}")
|
||||
changes_json += ","
|
||||
else:
|
||||
changes_json = changes_json[:-1]
|
||||
|
||||
print("\t\t\"changes\": {\n" + message_json + "\t\t\t\"authors\": [\n\t\t\t" + changes_json + "]\n\t\t}", end="")
|
||||
print("\t\t\"" + self.tag.strip() + "\": {\n" + message_json + "\t\t\t\"authors\": [\n\t\t\t" + changes_json + "\n\t\t\t]\n", end="")
|
||||
else:
|
||||
print("\t\t\"exception\": \"" + _(NO_COMMITED_FILES_TEXT) + "\"")
|
||||
print("\t\t\"exception\": \"" + "No commited files with the specified extensions were found for this tag" + self.tag + "\"")
|
||||
|
||||
def output_text(self, tag):
|
||||
def output_text(self):
|
||||
authorinfo_list = self.changes.get_authorinfo_list()
|
||||
total_changes = 0.0
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue