Added --standard header, output footers for tags and branches, and --per-branch functionality

This commit is contained in:
Matthew 2021-08-21 19:13:52 -04:00
parent 74d6f64333
commit a7ffdced1f
5 changed files with 233 additions and 40 deletions

View File

@ -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:

View File

@ -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}")

View File

@ -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":

View 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) + ".")

View File

@ -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