# frozen_string_literal: true class CommitLeaderboard attr_accessor :queue_file_path, :author_username, :auhor_avatar_url def run(args) abort 'No author username given.' if args[0].nil? abort 'No author avatar url given.' if args[1].nil? @author_username = args[0] @author_avatar_url = args[1] @queue_file_path = args[2] || '~/.renuo-commit-leaderboard.json' @queue_file_path = File.expand_path(@queue_file_path) check_required_tools check_if_repository_is_present check_if_commit_is_present append_to_queue(build_commit_payload) end private def check_required_tools return if system('git --version', out: File::NULL) abort('>> Git is not installed. Please install it first.') end def check_if_repository_is_present return if system('git rev-parse --is-inside-work-tree', out: File::NULL) abort('>> Not a git repository. Please run this command in a git repository.') end def check_if_commit_is_present return if system('git rev-parse --verify HEAD', out: File::NULL) abort('>> No commits found. Please commit your changes first.') end def build_commit_payload { sha: `git rev-parse HEAD`.strip, message: `git log -1 --pretty=%B`.strip, repository: `basename $(git rev-parse --show-toplevel)`.strip, branch: `git rev-parse --abbrev-ref HEAD`.strip, author: { username: @author_username, avatar_url: @author_avatar_url } } end def append_to_queue(payload) `echo [] > #{@queue_file_path}` unless File.exist?(@queue_file_path) commits = read_commits_from_queue(payload) puts '>> Adding commit to the queue:' print_queue_item(payload) File.open(@queue_file_path, 'w') do |file| commits << payload file.write(JSON.generate(commits)) end end def read_commits_from_queue(payload) commits = nil File.open(@queue_file_path, 'r') do |file| commits = JSON.parse(file.read) if commits.any? { |commit| commit['sha'] == payload[:sha] } abort('>> Commit has already been added to the queue') end rescue JSON::ParserError abort('>> Invalid JSON format in the queue file.') end commits end # rubocop:disable Metrics/AbcSize def print_queue_item(payload) sha = format_text_truncate(payload[:sha], COLOR_CODES[:green], 6) repository = format_text("#{payload[:repository]}##{payload[:branch]}", COLOR_CODES[:blue]) message = format_text_elipsis(payload[:message], COLOR_CODES[:yellow], 50) username = format_text(payload[:author][:username], COLOR_CODES[:magenta]) avatar_url = format_text(payload[:author][:avatar_url], COLOR_CODES[:cyan]) puts "#{sha} #{repository} - #{username} (#{avatar_url}) - #{message}" end # rubocop:enable Metrics/AbcSize def format_text(text, color) "\e[#{color}m#{text}\e[0m" end def wrap_in_color(text, color) "\e[#{color}m#{text}\e[0m" end def format_text_truncate(text, color, truncate_length) format_text(text[0..truncate_length], color) end def format_text_elipsis(text, color, truncate_length) if text.length > truncate_length format_text("#{truncate_text(text, truncate_length)}...", color) else format_text(text, color) end end def truncate_text(text, truncate_length) text[0..truncate_length] end end COLOR_CODES = { red: 31, green: 32, yellow: 33, blue: 34, magenta: 35, cyan: 36 }.freeze