git_stats/lib/git_stats/git_data/repo.rb

145 lines
4.0 KiB
Ruby
Raw Normal View History

2012-10-23 20:37:42 +02:00
# -*- encoding : utf-8 -*-
2012-10-13 17:20:06 +02:00
require 'git_stats/hash_initializable'
2012-10-09 22:34:02 +02:00
module GitStats
module GitData
class Repo
2012-10-13 17:20:06 +02:00
include HashInitializable
attr_reader :path, :first_commit_sha, :last_commit_sha, :tree_path
2012-10-19 17:35:33 +02:00
delegate :files, :files_by_extension, :files_by_extension_count, :lines_by_extension,
2012-10-20 22:38:11 +02:00
:files_count, :binary_files, :text_files, :lines_count, to: :last_commit
2012-10-09 22:34:02 +02:00
2012-10-13 17:20:06 +02:00
def initialize(params)
super(params)
@path = File.expand_path(@path)
@tree_path ||= "."
2012-10-09 22:34:02 +02:00
end
2012-10-12 18:20:07 +02:00
def authors
@authors ||= run_and_parse("git shortlog -se #{commit_range} #{tree_path}").map do |author|
2012-10-19 16:39:39 +02:00
Author.new(repo: self, name: author[:name], email: author[:email])
end.extend(ByFieldFinder)
2012-10-09 22:34:02 +02:00
end
2012-10-12 18:20:07 +02:00
def commits
@commits ||= run_and_parse("git rev-list --pretty=format:'%h|%at|%ai|%aE' #{commit_range} #{tree_path} | grep -v commit").map do |commit_line|
2012-10-19 21:17:16 +02:00
Commit.new(
repo: self,
2012-10-20 22:38:11 +02:00
sha: commit_line[:sha],
2012-10-19 21:17:16 +02:00
stamp: commit_line[:stamp],
date: DateTime.parse(commit_line[:date]),
author: authors.by_email(commit_line[:author_email])
)
2012-10-19 20:27:41 +02:00
end.sort_by! { |e| e.date }.extend(ByFieldFinder)
end
2012-10-19 22:01:01 +02:00
def commits_period
commits.map(&:date).minmax
end
2012-10-21 18:25:11 +02:00
def commits_count_by_author(limit = 4)
Hash[authors.map { |author| [author, author.commits.size] }.sort_by { |author, commits| -commits }[0..limit]]
2012-10-21 17:34:05 +02:00
end
2012-10-21 23:53:31 +02:00
[:insertions, :deletions, :changed_lines].each do |method|
2012-10-21 22:41:54 +02:00
define_method "#{method}_by_author" do |limit = 4|
Hash[authors.map { |author| [author, author.send(method)] }.sort_by { |author, lines| -lines }[0..limit]]
end
2012-10-20 21:28:25 +02:00
end
2012-10-21 13:19:37 +02:00
def files_count_by_date
@files_count_each_day ||= Hash[commits.map { |commit|
[commit.date.to_date, commit.files_count]
}].fill_empty_days!(aggregated: true)
2012-10-20 00:30:00 +02:00
end
2012-10-21 13:19:37 +02:00
def lines_count_by_date
sum = 0
@lines_count_each_day ||= Hash[commits.map { |commit|
sum += commit.short_stat.insertions
sum -= commit.short_stat.deletions
[commit.date.to_date, sum]
}].fill_empty_days!(aggregated: true)
2012-10-20 00:30:00 +02:00
end
2012-10-19 17:35:33 +02:00
def last_commit
commits.last
end
2012-10-19 15:51:24 +02:00
def commit_range
@first_commit_sha.blank? ? last_commit_sha : "#@first_commit_sha..#{last_commit_sha}"
2012-10-19 15:51:24 +02:00
end
2012-10-20 22:38:11 +02:00
def last_commit_sha
@last_commit_sha ||= 'HEAD'
2012-10-19 15:51:24 +02:00
end
def short_stats
@short_stats ||= commits.map(&:short_stat)
2012-10-09 22:34:02 +02:00
end
def activity
2012-10-12 18:24:28 +02:00
@activity ||= Activity.new(commits)
2012-10-09 22:34:02 +02:00
end
def project_version
@project_version ||= run("git rev-parse --short #{commit_range}").strip
2012-10-09 22:34:02 +02:00
end
def tree
@tree ||= Tree.new(repo: self, relative_path: @tree_path)
end
2012-10-09 22:34:02 +02:00
def project_name
# @project_name ||= File.basename(path)
@project_name ||= (File.expand_path(File.join(path, tree_path)).sub(File.dirname(File.expand_path(path))+File::SEPARATOR,"") || File.basename(path))
2012-10-09 22:34:02 +02:00
end
2012-10-12 18:20:07 +02:00
2012-10-19 16:57:49 +02:00
def run(command)
2012-10-19 21:11:47 +02:00
result = command_runner.run(path, command)
invoke_command_observers(command, result)
result
2012-10-19 16:57:49 +02:00
end
def run_and_parse(command)
result = run(command)
command_parser.parse(command, result)
end
2012-10-19 21:11:47 +02:00
def command_runner
@command_runner ||= CommandRunner.new
end
2012-10-19 16:57:49 +02:00
def command_parser
@command_parser ||= CommandParser.new
end
2012-10-19 21:11:47 +02:00
def add_command_observer(proc=nil, &block)
command_observers << block if block_given?
command_observers << proc if proc
2012-10-19 16:57:49 +02:00
end
2012-10-13 12:38:07 +02:00
def to_s
"#{self.class} #@path"
end
2012-10-13 13:27:15 +02:00
def ==(other)
self.path == other.path
end
2012-10-19 21:11:47 +02:00
private
def command_observers
@command_observers ||= []
end
def invoke_command_observers(command, result)
command_observers.each { |o| o.call(command, result) }
end
2012-10-09 22:34:02 +02:00
end
end
2012-10-23 20:37:42 +02:00
end