mirror of
https://github.com/tomgi/git_stats.git
synced 2024-12-22 13:32:17 +01:00
lazy loading and firsts tests
This commit is contained in:
parent
a2e81f6330
commit
dd228a4dd4
12 changed files with 105 additions and 71 deletions
1
.rspec
Normal file
1
.rspec
Normal file
|
@ -0,0 +1 @@
|
||||||
|
--color --format documentation
|
|
@ -6,4 +6,10 @@ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
||||||
|
|
||||||
# start up the CLI
|
# start up the CLI
|
||||||
require "git_stats/cli"
|
require "git_stats/cli"
|
||||||
GitStats::CLI.start(*ARGV)
|
|
||||||
|
begin
|
||||||
|
cli = GitStats::CLI.new
|
||||||
|
cli.start(*ARGV)
|
||||||
|
rescue => e
|
||||||
|
puts e.message
|
||||||
|
end
|
|
@ -26,4 +26,5 @@ Gem::Specification.new do |gem|
|
||||||
|
|
||||||
gem.add_development_dependency('rake')
|
gem.add_development_dependency('rake')
|
||||||
gem.add_development_dependency('pry')
|
gem.add_development_dependency('pry')
|
||||||
|
gem.add_development_dependency('rspec')
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,40 +2,11 @@ require "git_stats"
|
||||||
|
|
||||||
class GitStats::CLI
|
class GitStats::CLI
|
||||||
|
|
||||||
def self.start(*args)
|
def start(*args)
|
||||||
if args.size == 2
|
raise "Wrong number of arguments\nUsage: git_stats repo_path output_path" unless args.size == 2
|
||||||
|
|
||||||
repo_path, out_path = args
|
repo_path, out_path = args
|
||||||
validate(repo_path, out_path)
|
|
||||||
GitStats::Generator.new(repo_path, out_path).generate
|
GitStats::Generator.new(repo_path, out_path).generate
|
||||||
#Launchy.open("#{out_path}/index.html")
|
|
||||||
else
|
|
||||||
puts "Wrong number of arguments"
|
|
||||||
help
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
def self.help
|
|
||||||
puts "Usage: git_stats repo_path output_path"
|
|
||||||
exit 0
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.validate(repo_path, out_path)
|
|
||||||
validate_repo(repo_path)
|
|
||||||
validate_out(out_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.validate_repo(repo_path)
|
|
||||||
unless Dir.exists?("#{repo_path}/.git")
|
|
||||||
puts "#{repo_path} is not a git repository"
|
|
||||||
help
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.validate_out(out_path)
|
|
||||||
unless Dir.exists?("#{out_path}")
|
|
||||||
puts "#{out_path} doesn't exist"
|
|
||||||
help
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,14 +5,27 @@ module GitStats
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate
|
||||||
repo = GitData::Repo.new(@repo_path)
|
validate_paths
|
||||||
repo.gather_all_data
|
|
||||||
|
|
||||||
|
repo = GitData::Repo.new(@repo_path)
|
||||||
view_data = StatsView::ViewData.new(repo)
|
view_data = StatsView::ViewData.new(repo)
|
||||||
view_data.generate_charts
|
|
||||||
|
|
||||||
StatsView::View.render_all(view_data, @out_path)
|
StatsView::View.render_all(view_data, @out_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def validate_paths
|
||||||
|
validate_repo_path
|
||||||
|
validate_out_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_repo_path
|
||||||
|
raise ArgumentError, "#@repo_path is not a git repository" unless Dir.exists?("#@repo_path/.git")
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_out_path
|
||||||
|
raise ArgumentError, "#@out_path is not a directory" unless Dir.exists?(@out_path)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
|
@ -5,7 +5,7 @@ module GitStats
|
||||||
class Author
|
class Author
|
||||||
include HashInitializable
|
include HashInitializable
|
||||||
|
|
||||||
attr_accessor :name, :email
|
attr_reader :repo, :name, :email
|
||||||
|
|
||||||
def add_commit(commit)
|
def add_commit(commit)
|
||||||
commits << commit
|
commits << commit
|
||||||
|
@ -13,12 +13,16 @@ module GitStats
|
||||||
end
|
end
|
||||||
|
|
||||||
def commits
|
def commits
|
||||||
@commits ||= []
|
@commits ||= repo.commits.select { |hash, commit| commit.author == self }
|
||||||
end
|
end
|
||||||
|
|
||||||
def activity
|
def activity
|
||||||
@activity ||= Activity.new
|
@activity ||= commits.values.inject(Activity.new) do |activity, commit|
|
||||||
|
activity.add_commit(commit)
|
||||||
|
activity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -7,44 +7,30 @@ module GitStats
|
||||||
@path = path
|
@path = path
|
||||||
end
|
end
|
||||||
|
|
||||||
def gather_all_data
|
def authors
|
||||||
project_version
|
@authors ||= Command.new(self, 'git shortlog -se HEAD').run.lines.inject({}) do |authors, line|
|
||||||
project_name
|
name, email = line.split(/\t/)[1].strip.scan(/(.*)<(.*)>/).first.map(&:strip)
|
||||||
gather_authors
|
authors[email] = Author.new(repo: self, name: name, email: email)
|
||||||
gather_commits
|
authors
|
||||||
end
|
|
||||||
|
|
||||||
def gather_authors
|
|
||||||
Command.new(self, 'git shortlog -se HEAD').run.each_line do |author|
|
|
||||||
name, email = author.split(/\t/)[1].strip.scan(/(.*)<(.*)>/).first.map(&:strip)
|
|
||||||
authors[email] = Author.new(name: name, email: email)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def gather_commits
|
def commits
|
||||||
Command.new(self, 'git rev-list --pretty=format:"%h|%at|%ai|%aE" HEAD | grep -v commit').run.lines.each_with_index do |commit_line, i|
|
@commits ||= Command.new(self, 'git rev-list --pretty=format:"%h|%at|%ai|%aE" HEAD | grep -v commit').run.lines.inject({}) do |commits, commit_line|
|
||||||
hash, stamp, date, author_email = commit_line.split('|').map(&:strip)
|
hash, stamp, date, author_email = commit_line.split('|').map(&:strip)
|
||||||
author = authors[author_email]
|
author = authors[author_email]
|
||||||
|
|
||||||
date = DateTime.parse(date)
|
date = DateTime.parse(date)
|
||||||
commit = commits[hash] = Commit.new(repo: self, hash: hash, stamp: stamp, date: date, author: author)
|
commits[hash] = Commit.new(repo: self, hash: hash, stamp: stamp, date: date, author: author)
|
||||||
commit.gather_all_data
|
commits
|
||||||
|
|
||||||
activity.add_commit(commit)
|
|
||||||
author.add_commit(commit)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def authors
|
|
||||||
@authors ||= {}
|
|
||||||
end
|
|
||||||
|
|
||||||
def commits
|
|
||||||
@commits ||= {}
|
|
||||||
end
|
|
||||||
|
|
||||||
def activity
|
def activity
|
||||||
@activity ||= Activity.new
|
@activity ||= commits.values.inject(Activity.new) do |activity, commit|
|
||||||
|
activity.add_commit(commit)
|
||||||
|
activity
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_version
|
def project_version
|
||||||
|
@ -54,6 +40,7 @@ module GitStats
|
||||||
def project_name
|
def project_name
|
||||||
@project_name ||= Pathname(path).basename.to_s
|
@project_name ||= Pathname(path).basename.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -10,8 +10,8 @@ module GitStats
|
||||||
@repo = repo
|
@repo = repo
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_charts
|
def h
|
||||||
@h = LazyHighCharts::HighChart.new('graph') do |f|
|
@h ||= LazyHighCharts::HighChart.new('graph') do |f|
|
||||||
f.chart(type: "column")
|
f.chart(type: "column")
|
||||||
f.title(text: "Commits")
|
f.title(text: "Commits")
|
||||||
f.xAxis(categories: Date::ABBR_DAYNAMES)
|
f.xAxis(categories: Date::ABBR_DAYNAMES)
|
||||||
|
|
19
spec/cli_spec.rb
Normal file
19
spec/cli_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe GitStats::CLI do
|
||||||
|
let(:repo_path) { 'repo_path' }
|
||||||
|
let(:out_path) { 'out_path' }
|
||||||
|
|
||||||
|
it 'should invoke generator with console arguments given' do
|
||||||
|
generator = double('generator')
|
||||||
|
GitStats::Generator.should_receive(:new).with(repo_path, out_path).and_return(generator)
|
||||||
|
generator.should_receive(:generate)
|
||||||
|
|
||||||
|
subject.start(repo_path, out_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should raise error when 2 arguments are not given' do
|
||||||
|
expect { subject.start("only one argument") }.to raise_error
|
||||||
|
expect { subject.start("too", "much", "arguments") }.to raise_error
|
||||||
|
end
|
||||||
|
end
|
31
spec/generator_spec.rb
Normal file
31
spec/generator_spec.rb
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe GitStats::Generator do
|
||||||
|
let(:repo_path) { 'repo_path' }
|
||||||
|
let(:out_path) { 'out_path' }
|
||||||
|
let(:generator) { GitStats::Generator.new(repo_path, out_path) }
|
||||||
|
|
||||||
|
before { Dir.stub!(:exists? => true) }
|
||||||
|
|
||||||
|
it 'should raise exception if given repo path is not a git repository' do
|
||||||
|
Dir.should_receive(:exists?).with("#{repo_path}/.git").and_return(false)
|
||||||
|
expect { generator.generate }.to raise_error(ArgumentError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise exception if given out directory doesn't exist" do
|
||||||
|
Dir.should_receive(:exists?).with(out_path).and_return(false)
|
||||||
|
expect { generator.generate }.to raise_error(ArgumentError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should render all templates with view data for this repo' do
|
||||||
|
repo = double('repo')
|
||||||
|
GitStats::GitData::Repo.should_receive(:new).with(repo_path).and_return(repo)
|
||||||
|
|
||||||
|
view_data = double('view_data')
|
||||||
|
GitStats::StatsView::ViewData.should_receive(:new).with(repo).and_return(view_data)
|
||||||
|
|
||||||
|
GitStats::StatsView::View.should_receive(:render_all).with(view_data, out_path)
|
||||||
|
|
||||||
|
generator.generate
|
||||||
|
end
|
||||||
|
end
|
1
spec/spec_helper.rb
Normal file
1
spec/spec_helper.rb
Normal file
|
@ -0,0 +1 @@
|
||||||
|
require 'git_stats'
|
|
@ -1,4 +1,4 @@
|
||||||
%p= repo.project_name
|
%p= repo.project_name
|
||||||
%p= repo.project_version
|
%p= repo.project_version
|
||||||
|
|
||||||
= high_chart("my_id", @h)
|
= high_chart("my_id", h)
|
Loading…
Reference in a new issue