# frozen_string_literal: true require 'rugged' require_relative 'commit_info' module Booru # Provides an interface to walk through the commit history # of the application repository. class CommitHistory include Enumerable # Creates a new history walker. def initialize #noinspection RubyArgCount @repo = Rugged::Repository.new(Rails.root.to_s) end # @overload def each # Creates an enumerator to the commit history. # @return [Enumerable] An enumerator. # # @overload def each(&block) # Walks the commit history, yielding a {CommitInfo} # for each commit in turn. # @return [Enumerable] An enumerator. # # @see CommitInfo def each # Nothing to call. return self unless block_given? #noinspection RubyArgCount walker = Rugged::Walker.new(@repo) walker.sorting(Rugged::SORT_TOPO) walker.push('HEAD') walker.each do |c| # Commits with multiple parents are merge commits. # # Merge commits have multiple possible diffs, depending on which parent # tree is visited, and are mostly irrelevant to actual changes in the # state of the repository. They are ignored for the purposes of this # application. next if c.parents.size != 1 diff = c.parents[0].diff(c) _, diff_insertions, diff_deletions = diff.stat yield CommitInfo.new( id: c.oid.to_s, time: c.time, name: c.author[:name], email: c.author[:email], message: c.message, insertions: diff_insertions, deletions: diff_deletions ) end self end end end