return self.authors_email[name] __changes__ = None def get(hard): global __changes__ if __changes__ == None: __changes__ = Changes(hard) return __changes__ HISTORICAL_INFO_TEXT = N_( "The following historical commit information, by author, was found in the repository" ) NO_COMMITED_FILES_TEXT = N_( "No commited files with the specified extensions were found") class ChangesOutput(Outputable): def __init__(self, hard): self.changes = get(hard) Outputable.__init__(self) def output_html(self): authorinfo_list = self.changes.get_authorinfo_list() total_changes = 0.0 changes_xml = "<div><div class=\"box\">" chart_data = ""
def get_eloc(file_r, extension): is_inside_comment = False eloc_counter = 0 for i in file_r: i = i.decode("utf-8", "replace") (_, is_inside_comment) = comment.handle_comment_block( is_inside_comment, extension, i) if not is_inside_comment and not comment.is_comment(extension, i): eloc_counter += 1 return eloc_counter ELOC_INFO_TEXT = N_( "The following files are suspiciously big (in order of severity)") CYCLOMATIC_COMPLEXITY_TEXT = N_( "The following files have an elevated cyclomatic complexity (in order of severity)" ) CYCLOMATIC_COMPLEXITY_DENSITY_TEXT = N_( "The following files have an elevated cyclomatic complexity density (in order of severity)" ) METRICS_MISSING_INFO_TEXT = N_( "No metrics violations were found in the repository") METRICS_VIOLATION_SCORES = [[1.0, "minimal"], [1.25, "minor"], [1.5, "medium"], [2.0, "bad"], [3.0, "severe"]] def __get_metrics_score__(ceiling, value): for i in reversed(METRICS_VIOLATION_SCORES):
class Responsibilities: @staticmethod def get(hard, author_name): author_blames = {} for i in blame.get(hard, changes.get(hard)).blames.items(): if (author_name == i[0][0]): total_rows = i[1].rows - i[1].comments if total_rows > 0: author_blames[i[0][1]] = total_rows return sorted(author_blames.items()) RESPONSIBILITIES_INFO_TEXT = N_( "The following repsonsibilties, by author, were found in the current " "revision of the repository (comments are exluded from the line count, " "if possible)") MOSTLY_RESPONSIBLE_FOR_TEXT = N_("is mostly responsible for") class ResponsibilitiesOutput(Outputable): def __init__(self, hard): self.hard = hard Outputable.__init__(self) self.changes = changes.get(hard) def output_text(self): print("\n" + textwrap.fill(_(RESPONSIBILITIES_INFO_TEXT) + ":", width=terminal.get_size()[0])) for i in sorted(
self.blamechunk_is_prior = True elif keyval[0] == "author-mail": self.blamechunk_email = keyval[1].lstrip("<").rstrip(">") elif keyval[0] == "author-time": self.blamechunk_time = datetime.date.fromtimestamp( int(keyval[1])) elif keyval[0] == "filename": self.blamechunk_is_last = True elif Blame.is_revision(keyval[0]): self.blamechunk_revision = keyval[0] __thread_lock__.release( ) # Lock controlling the number of threads running PROGRESS_TEXT = N_( "Checking how many rows belong to each author (Progress): {0:.0f}%") class Blame: def __init__(self, hard, useweeks, changes): self.blames = {} ls_tree_r = subprocess.Popen( ["git", "ls-tree", "--name-only", "-r", interval.get_ref()], bufsize=1, stdout=subprocess.PIPE).stdout lines = ls_tree_r.readlines() ls_tree_r.close() for i, row in enumerate(lines): row = row.strip().decode("unicode_escape", "ignore")
def get_eloc(file_r, extension): is_inside_comment = False eloc_counter = 0 for j in file_r.readlines(): j = j.decode("utf-8", "replace") (_, is_inside_comment) = comment.handle_comment_block( is_inside_comment, extension, j) if not is_inside_comment and not comment.is_comment(extension, j): eloc_counter += 1 return eloc_counter ELOC_INFO_TEXT = N_( "The following files are suspiciously big (in order of severity)") METRICS_MISSING_INFO_TEXT = N_( "No metrics violations were found in the repository") class Metrics(Outputable): def output_text(self): metrics_logic = MetricsLogic() if not metrics_logic.eloc: print("\n" + _(METRICS_MISSING_INFO_TEXT) + ".") else: print("\n" + _(ELOC_INFO_TEXT) + ":") for i in sorted(set([(j, i) for (i, j) in metrics_logic.eloc.items()]), reverse=True):
) / changes_in_period > max_width: return multiplier multiplier += 0.25 def is_author_in_period(self, period, author): return self.entries.get((author, period), None) != None def is_author_in_periods(self, periods, author): for period in periods: if self.is_author_in_period(period, author): return True return False TIMELINE_INFO_TEXT = N_( "The following history timeline has been gathered from the repository") MODIFIED_ROWS_TEXT = N_("Modified Rows:") def __output_row__text__(timeline_data, periods, names): print("\n" + terminal.__bold__ + terminal.ljust(_("Author"), 20), end=" ") for period in periods: print(terminal.rjust(period, 10), end=" ") print(terminal.__normal__) for name in names: if timeline_data.is_author_in_periods(periods, name[0]): print(terminal.ljust( name[0], 20)[0:20 - terminal.get_excess_column_count(name[0])],
string = string.strip() if len(string) > 0: for i in __filters__[filter_type][0]: try: if re.search(i, string) != None: __filters__[filter_type][1].add(string) return True except: raise InvalidRegExpError( _("invalid regular expression specified")) return False FILTERING_INFO_TEXT = N_( "The following files were excluded from the statistics due to the specified exclusion patterns" ) FILTERING_AUTHOR_INFO_TEXT = N_( "The following authors were excluded from the statistics due to the specified exclusion patterns" ) FILTERING_EMAIL_INFO_TEXT = N_( "The authors with the following emails were excluded from the statistics due to the specified exclusion patterns" ) class Filtering(Outputable): @staticmethod def __output_html_section__(info_string, filtered): filtering_xml = "" if filtered:
def get(): return __extensions__ def define(string): global __extensions__ __extensions__ = string.split(",") def add_located(string): if len(string) > 0: __located_extensions__.add(string) EXTENSIONS_INFO_TEXT = N_( "The extensions below were found in the repository history") EXTENSIONS_MARKED_TEXT = N_( "(extensions used during statistical analysis are marked)") class Extensions(Outputable): def output_html(self): if __located_extensions__: extensions_xml = "<div><div class=\"box\">" extensions_xml += "<p>{0} {1}.</p><p>".format( _(EXTENSIONS_INFO_TEXT), _(EXTENSIONS_MARKED_TEXT)) for i in __located_extensions__: if i in __extensions__: extensions_xml += "<strong>" + i + "</strong>" else:
string = file_name.strip() if len(string) > 0: for i in __filters__: try: if re.search(i, string) != None: __filtered_files__.add(string) return True except: raise InvalidRegExpError( _("invalid regular expression specified")) return False FILTERING_INFO_TEXT = N_( "The following files were excluded from the statistics due to the specified exclusion patterns" ) class Filtering(Outputable): def output_html(self): if __filtered_files__: filtering_xml = "<div><div class=\"box\">" filtering_xml += "<p>" + _(FILTERING_INFO_TEXT) + "." + "</p>" for i in __filtered_files__: filtering_xml += "<p>" + i + "</p>" filtering_xml += "</div></div>" print(filtering_xml)
if __checkout_missing__: subprocess.call("git checkout \"" + file_name.strip() + "\"", shell=True) else: __missing_files__.add(file_name) return True return False def set_checkout_missing(checkout): global __checkout_missing__ __checkout_missing__ = checkout MISSING_INFO_TEXT = N_( "The following files were missing in the repository and were therefore not " "completely included in the statistical analysis. To include them, you can " "either checkout manually using git or use the -c option in gitinspector") class Missing(Outputable): def output_html(self): if __missing_files__: missing_xml = "<div><div class=\"box\">" missing_xml += "<p>" + _(MISSING_INFO_TEXT) + ".</p>" for missing in __missing_files__: missing_xml += "<p class=\"error\">" + missing + "</p>" missing_xml += "</div></div>" print(missing_xml)