#!/usr/bin/env ruby # frozen_string_literal: true require 'tty-table' # # ruby-quality-report # # This script outputs a CSV spreadsheet file showing the percentage # of lines of code written by each author that have been flagged as # having too high of a complexity. # def create_combined_stats(part_stats, whole_stats) part_data = make_data_set(part_stats) whole_data = make_data_set(whole_stats) whole_data.map do |label, whole_count| part_count = part_data[label] || 0 percent = float_to_percent(part_count.to_f / whole_count) { label:, part_count:, whole_count:, percent: } end end def make_data_set(two_column_data) hash = {} two_column_data.each_line do |line| count, label = line.split(' ') hash[label] = count.to_i end hash end def generate_csv(combined_stats) generate_data(combined_stats) .map { |stats| [stats[:label], stats[:percent], stats[:part_count], stats[:whole_count]].join(',') } .tap { |x| x.prepend(['Author,Percent Flagged,Flagged Lines,All Lines']) } .join("\n") end def generate_table(combined_stats) table = TTY::Table.new(header: ['Author', 'Percent Flagged', 'Flagged Lines', 'All Lines']) generate_data(combined_stats).each do |stats| next if should_skip?(stats) table << [stats[:label], "#{stats[:percent]}%", stats[:part_count], stats[:whole_count]] end table.render(:unicode, alignments: %i[left right right right]) end def generate_data(combined_stats) combined_stats .sort_by { |s| s[:percent] } end def should_skip?(stats) less_than_200_lines_total?(stats) || no_commits_in_last_60_days?(stats) end def less_than_200_lines_total?(stats) stats[:whole_count] < 200 end def no_commits_in_last_60_days?(stats) author = stats[:label] # Get the last commit timestamp in Unix epoch format last_commit = `git log -1 --format="%at" --author="#{author}"`.chomp return true if last_commit.empty? # Handle case where author has no commits # Convert Unix timestamp to Time object last_commit_time = Time.at(last_commit.to_i) sixty_days_ago = Time.now - (60 * 24 * 60 * 60) # 60 days in seconds last_commit_time < sixty_days_ago end def float_to_percent(a_float) (Float(a_float) * 100).round(1) end # # Execution begins here # PART_STATS = `ruby-author-warnings | frequency-list`.freeze WHOLE_STATS = `ruby-line-authors | frequency-list`.freeze COMBINED_STATS = create_combined_stats(PART_STATS, WHOLE_STATS) puts generate_table(COMBINED_STATS)