# frozen_string_literal: true require "chronic" require "active_support/core_ext/numeric/time" require_relative "../github/base" module Neetob class CLI module Users class Commits < Github::Base include ActionView::Helpers::DateHelper attr_accessor :sandbox, :apps, :author, :duration def initialize(author, duration, apps = ["*"], sandbox = false) super() @sandbox = sandbox @apps = apps @author = author @duration = duration end def run table_rows = build_commit_rows html_content = build_html_content(table_rows) create_html_file(html_content) open_html_file_in_default_system_application end private def build_commit_rows commits = find_all_matching_apps_or_repos(apps, :github, sandbox, true).map do |app| commits = commits_within_range(app) if commits&.empty? ui.info("No commits found in \"#{app}\" for the given author and duration.") next end ui.success("Commits found in \"#{app}\".\n") commits end sorted_commits = commits.compact.flatten.sort_by { |obj| obj.dig(:commit, :author, :date) }.reverse build_table_rows(sorted_commits) end def commits_within_range(app) fetch_commits(app, 1) end def build_table_rows(commits) commits.map do |commit| app = commit[:html_url].split("/")[4] commit_id = commit[:sha] email = commit.dig(:commit, :author, :email) time = distance_of_time_in_words(commit.dig(:commit, :author, :date), Time.current) + " ago" date = commit.dig(:commit, :author, :date).strftime("%B %d, %Y") title = commit.dig(:commit, :message).split("\n")[0] html_table_row(app, commit_id, email, time, date, title) end end def app_name_without_org_suffix(app) app.split("/")[1] end def html_table_row(app, commit_id, email, time, date, title) starting_7_characters_of_commit = commit_id[0..6] " #{starting_7_characters_of_commit} #{app} #{time} #{title} #{date} #{email} " end def build_html_content(table_rows) "
Github user id: #{author}
Duration: #{duration}
#{table_rows&.compact&.empty? ? "" : table_rows.join}
Commit Repo Created at Title Commited on Email
No commits found in the given duration
" end def create_html_file(html_content) commits_file = File.new("commits.html", "w") commits_file.puts(html_content) commits_file.close end def open_html_file_in_default_system_application `open ./commits.html` end def since_duration(duration) Chronic.parse(duration.split(".").join(" ") + " ago")&.iso8601 end def fetch_commits(app, page = 1) begin commits = client.commits( app, "main", { author:, since: since_duration(duration), per_page: 100, page: }) rescue => exception ui.error(exception.message) commits = [] end if commits.length == 100 commits + fetch_commits(app, page + 1) else commits end end end end end end