mirror of
https://github.com/ejwa/gitinspector.git
synced 2024-11-16 00:28:25 +01:00
Support for multiple repositories is near completion (See issue #24).
Only the metrics module is lacking support. While the rest should work, please note that it is completely untested as of now and probably has some rough edges.
This commit is contained in:
parent
46b21db196
commit
98615ccbfc
5 changed files with 45 additions and 41 deletions
|
@ -148,6 +148,17 @@ class Blame(object):
|
|||
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()
|
||||
|
||||
def __add__(self, other):
|
||||
if other == None:
|
||||
return self
|
||||
|
||||
self.blames.update(other.blames)
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def is_revision(string):
|
||||
revision = re.search("([0-9a-f]{40})", string)
|
||||
|
@ -180,12 +191,3 @@ class Blame(object):
|
|||
summed_blames[i[0][0]].comments += i[1].comments
|
||||
|
||||
return summed_blames
|
||||
|
||||
__blame__ = None
|
||||
|
||||
def get(hard, useweeks, changes):
|
||||
global __blame__
|
||||
if __blame__ == None:
|
||||
__blame__ = Blame(hard, useweeks, changes)
|
||||
|
||||
return __blame__
|
||||
|
|
|
@ -23,6 +23,7 @@ import atexit
|
|||
import getopt
|
||||
import os
|
||||
import sys
|
||||
from .blame import Blame
|
||||
from .changes import Changes
|
||||
from .config import GitConfig
|
||||
from . import (basedir, clone, extensions, filtering, format, help, interval,
|
||||
|
@ -58,13 +59,16 @@ class Runner(object):
|
|||
terminal.skip_escapes(not sys.stdout.isatty())
|
||||
terminal.set_stdout_encoding()
|
||||
previous_directory = os.getcwd()
|
||||
changes = None
|
||||
summed_blames = None
|
||||
summed_changes = None
|
||||
|
||||
for repo in repos:
|
||||
os.chdir(previous_directory)
|
||||
os.chdir(repo)
|
||||
absolute_path = basedir.get_basedir_git()
|
||||
changes = Changes(self.hard) + changes
|
||||
changes = Changes(self.hard)
|
||||
summed_blames = Blame(self.hard, self.useweeks, changes) + summed_blames
|
||||
summed_changes = changes + summed_changes
|
||||
|
||||
if sys.stdout.isatty() and format.is_interactive_format():
|
||||
terminal.clear_row()
|
||||
|
@ -75,16 +79,16 @@ class Runner(object):
|
|||
outputable.output(ChangesOutput(changes))
|
||||
|
||||
if changes.get_commits():
|
||||
outputable.output(BlameOutput(changes, self.hard, self.useweeks))
|
||||
outputable.output(BlameOutput(summed_changes, summed_blames))
|
||||
|
||||
if self.timeline:
|
||||
outputable.output(TimelineOutput(changes, self.useweeks))
|
||||
outputable.output(TimelineOutput(summed_changes, self.useweeks))
|
||||
|
||||
if self.include_metrics:
|
||||
outputable.output(MetricsOutput())
|
||||
|
||||
if self.responsibilities:
|
||||
outputable.output(ResponsibilitiesOutput(changes, self.hard, self.useweeks))
|
||||
outputable.output(ResponsibilitiesOutput(summed_changes, summed_blames))
|
||||
|
||||
outputable.output(FilteringOutput())
|
||||
|
||||
|
|
|
@ -23,21 +23,20 @@ import json
|
|||
import sys
|
||||
import textwrap
|
||||
from ..localization import N_
|
||||
from .. import blame, format, gravatar, terminal
|
||||
from .. import format, gravatar, terminal
|
||||
from ..blame import Blame
|
||||
from .outputable import Outputable
|
||||
|
||||
BLAME_INFO_TEXT = N_("Below are the number of rows from each author that have survived and are still "
|
||||
"intact in the current revision")
|
||||
|
||||
class BlameOutput(Outputable):
|
||||
def __init__(self, changes, hard, useweeks):
|
||||
def __init__(self, changes, blame):
|
||||
if format.is_interactive_format():
|
||||
print("")
|
||||
|
||||
self.changes = changes
|
||||
self.hard = hard
|
||||
self.useweeks = useweeks
|
||||
blame.get(self.hard, self.useweeks, self.changes)
|
||||
self.blame = blame
|
||||
Outputable.__init__(self)
|
||||
|
||||
def output_html(self):
|
||||
|
@ -47,7 +46,7 @@ class BlameOutput(Outputable):
|
|||
_("Author"), _("Rows"), _("Stability"), _("Age"), _("% in comments"))
|
||||
blame_xml += "<tbody>"
|
||||
chart_data = ""
|
||||
blames = sorted(blame.__blame__.get_summed_blames().items())
|
||||
blames = sorted(self.blame.get_summed_blames().items())
|
||||
total_blames = 0
|
||||
|
||||
for i in blames:
|
||||
|
@ -64,7 +63,7 @@ class BlameOutput(Outputable):
|
|||
blame_xml += "<td>" + entry[0] + "</td>"
|
||||
|
||||
blame_xml += "<td>" + str(entry[1].rows) + "</td>"
|
||||
blame_xml += "<td>" + ("{0:.1f}".format(blame.Blame.get_stability(entry[0], entry[1].rows, self.changes)) + "</td>")
|
||||
blame_xml += "<td>" + ("{0:.1f}".format(Blame.get_stability(entry[0], entry[1].rows, self.changes)) + "</td>")
|
||||
blame_xml += "<td>" + "{0:.1f}".format(float(entry[1].skew) / entry[1].rows) + "</td>"
|
||||
blame_xml += "<td>" + "{0:.2f}".format(100.0 * entry[1].comments / entry[1].rows) + "</td>"
|
||||
blame_xml += "<td style=\"display: none\">" + work_percentage + "</td>"
|
||||
|
@ -99,13 +98,13 @@ class BlameOutput(Outputable):
|
|||
message_xml = "\t\t\t\"message\": \"" + _(BLAME_INFO_TEXT) + "\",\n"
|
||||
blame_xml = ""
|
||||
|
||||
for i in sorted(blame.__blame__.get_summed_blames().items()):
|
||||
for i in sorted(self.blame.get_summed_blames().items()):
|
||||
author_email = self.changes.get_latest_email_by_author(i[0])
|
||||
|
||||
name_xml = "\t\t\t\t\"name\": \"" + i[0] + "\",\n"
|
||||
gravatar_xml = "\t\t\t\t\"gravatar\": \"" + gravatar.get_url(author_email) + "\",\n"
|
||||
rows_xml = "\t\t\t\t\"rows\": " + str(i[1].rows) + ",\n"
|
||||
stability_xml = ("\t\t\t\t\"stability\": " + "{0:.1f}".format(blame.Blame.get_stability(i[0], i[1].rows,
|
||||
stability_xml = ("\t\t\t\t\"stability\": " + "{0:.1f}".format(Blame.get_stability(i[0], i[1].rows,
|
||||
self.changes)) + ",\n")
|
||||
age_xml = ("\t\t\t\t\"age\": " + "{0:.1f}".format(float(i[1].skew) / i[1].rows) + ",\n")
|
||||
percentage_in_comments_xml = ("\t\t\t\t\"percentage-in-comments\": " + "{0:.2f}".format(100.0 * i[1].comments / i[1].rows) +
|
||||
|
@ -125,10 +124,10 @@ class BlameOutput(Outputable):
|
|||
terminal.printb(terminal.ljust(_("Author"), 21) + terminal.rjust(_("Rows"), 10) + terminal.rjust(_("Stability"), 15) +
|
||||
terminal.rjust(_("Age"), 13) + terminal.rjust(_("% in comments"), 20))
|
||||
|
||||
for i in sorted(blame.__blame__.get_summed_blames().items()):
|
||||
for i in sorted(self.blame.get_summed_blames().items()):
|
||||
print(terminal.ljust(i[0], 20)[0:20 - terminal.get_excess_column_count(i[0])], end=" ")
|
||||
print(str(i[1].rows).rjust(10), end=" ")
|
||||
print("{0:.1f}".format(blame.Blame.get_stability(i[0], i[1].rows, self.changes)).rjust(14), end=" ")
|
||||
print("{0:.1f}".format(Blame.get_stability(i[0], i[1].rows, self.changes)).rjust(14), end=" ")
|
||||
print("{0:.1f}".format(float(i[1].skew) / i[1].rows).rjust(12), end=" ")
|
||||
print("{0:.2f}".format(100.0 * i[1].comments / i[1].rows).rjust(19))
|
||||
|
||||
|
@ -136,13 +135,13 @@ class BlameOutput(Outputable):
|
|||
message_xml = "\t\t<message>" + _(BLAME_INFO_TEXT) + "</message>\n"
|
||||
blame_xml = ""
|
||||
|
||||
for i in sorted(blame.__blame__.get_summed_blames().items()):
|
||||
for i in sorted(self.blame.get_summed_blames().items()):
|
||||
author_email = self.changes.get_latest_email_by_author(i[0])
|
||||
|
||||
name_xml = "\t\t\t\t<name>" + i[0] + "</name>\n"
|
||||
gravatar_xml = "\t\t\t\t<gravatar>" + gravatar.get_url(author_email) + "</gravatar>\n"
|
||||
rows_xml = "\t\t\t\t<rows>" + str(i[1].rows) + "</rows>\n"
|
||||
stability_xml = ("\t\t\t\t<stability>" + "{0:.1f}".format(blame.Blame.get_stability(i[0], i[1].rows,
|
||||
stability_xml = ("\t\t\t\t<stability>" + "{0:.1f}".format(Blame.get_stability(i[0], i[1].rows,
|
||||
self.changes)) + "</stability>\n")
|
||||
age_xml = ("\t\t\t\t<age>" + "{0:.1f}".format(float(i[1].skew) / i[1].rows) + "</age>\n")
|
||||
percentage_in_comments_xml = ("\t\t\t\t<percentage-in-comments>" + "{0:.2f}".format(100.0 * i[1].comments / i[1].rows) +
|
||||
|
|
|
@ -21,7 +21,7 @@ from __future__ import print_function
|
|||
from __future__ import unicode_literals
|
||||
import textwrap
|
||||
from ..localization import N_
|
||||
from .. import blame, format, gravatar, terminal
|
||||
from .. import format, gravatar, terminal
|
||||
from .. import responsibilities as resp
|
||||
from .outputable import Outputable
|
||||
|
||||
|
@ -31,18 +31,17 @@ RESPONSIBILITIES_INFO_TEXT = N_("The following responsibilities, by author, were
|
|||
MOSTLY_RESPONSIBLE_FOR_TEXT = N_("is mostly responsible for")
|
||||
|
||||
class ResponsibilitiesOutput(Outputable):
|
||||
def __init__(self, changes, hard, useweeks):
|
||||
def __init__(self, changes, blame):
|
||||
self.changes = changes
|
||||
self.hard = hard
|
||||
self.useweeks = useweeks
|
||||
self.blame = blame
|
||||
Outputable.__init__(self)
|
||||
|
||||
def output_text(self):
|
||||
print("\n" + textwrap.fill(_(RESPONSIBILITIES_INFO_TEXT) + ":", width=terminal.get_size()[0]))
|
||||
|
||||
for i in sorted(set(i[0] for i in blame.get(self.hard, self.useweeks, self.changes).blames)):
|
||||
for i in sorted(set(i[0] for i in self.blame.blames)):
|
||||
responsibilities = sorted(((i[1], i[0]) for i in resp.Responsibilities.get(self.changes,
|
||||
self.hard, self.useweeks, i)), reverse=True)
|
||||
self.blame, i)), reverse=True)
|
||||
if responsibilities:
|
||||
print("\n" + i, _(MOSTLY_RESPONSIBLE_FOR_TEXT) + ":")
|
||||
|
||||
|
@ -60,9 +59,9 @@ class ResponsibilitiesOutput(Outputable):
|
|||
resp_xml = "<div><div class=\"box\" id=\"responsibilities\">"
|
||||
resp_xml += "<p>" + _(RESPONSIBILITIES_INFO_TEXT) + ".</p>"
|
||||
|
||||
for i in sorted(set(i[0] for i in blame.get(self.hard, self.useweeks, self.changes).blames)):
|
||||
for i in sorted(set(i[0] for i in self.blame.blames)):
|
||||
responsibilities = sorted(((i[1], i[0]) for i in resp.Responsibilities.get(self.changes,
|
||||
self.hard, self.useweeks, i)), reverse=True)
|
||||
self.blame, i)), reverse=True)
|
||||
if responsibilities:
|
||||
resp_xml += "<div>"
|
||||
|
||||
|
@ -87,9 +86,9 @@ class ResponsibilitiesOutput(Outputable):
|
|||
message_xml = "\t\t\t\"message\": \"" + _(RESPONSIBILITIES_INFO_TEXT) + "\",\n"
|
||||
resp_xml = ""
|
||||
|
||||
for i in sorted(set(i[0] for i in blame.get(self.hard, self.useweeks, self.changes).blames)):
|
||||
for i in sorted(set(i[0] for i in self.blame.blames)):
|
||||
responsibilities = sorted(((i[1], i[0]) for i in resp.Responsibilities.get(self.changes,
|
||||
self.hard, self.useweeks, i)), reverse=True)
|
||||
self.blame, i)), reverse=True)
|
||||
if responsibilities:
|
||||
author_email = self.changes.get_latest_email_by_author(i)
|
||||
|
||||
|
@ -118,9 +117,9 @@ class ResponsibilitiesOutput(Outputable):
|
|||
message_xml = "\t\t<message>" + _(RESPONSIBILITIES_INFO_TEXT) + "</message>\n"
|
||||
resp_xml = ""
|
||||
|
||||
for i in sorted(set(i[0] for i in blame.get(self.hard, self.useweeks, self.changes).blames)):
|
||||
for i in sorted(set(i[0] for i in self.blame.blames)):
|
||||
responsibilities = sorted(((i[1], i[0]) for i in resp.Responsibilities.get(self.changes,
|
||||
self.hard, self.useweeks, i)), reverse=True)
|
||||
self.blame, i)), reverse=True)
|
||||
if responsibilities:
|
||||
author_email = self.changes.get_latest_email_by_author(i)
|
||||
|
||||
|
|
|
@ -26,10 +26,10 @@ class ResponsibiltyEntry(object):
|
|||
|
||||
class Responsibilities(object):
|
||||
@staticmethod
|
||||
def get(changes, hard, useweeks, author_name):
|
||||
def get(changes, blame, author_name):
|
||||
author_blames = {}
|
||||
|
||||
for i in blame.get(hard, useweeks, changes).blames.items():
|
||||
for i in blame.blames.items():
|
||||
if author_name == i[0][0]:
|
||||
total_rows = i[1].rows - i[1].comments
|
||||
if total_rows > 0:
|
||||
|
|
Loading…
Reference in a new issue