From 1cc31989551727ec365918abe70e1da929dff580 Mon Sep 17 00:00:00 2001 From: Israel Revert Date: Sun, 30 Mar 2014 08:01:39 +0200 Subject: [PATCH 1/2] Implement git statistics on git trees (directories) The current statistics refer to the complete git repository. With this commit it is possible to generate statistics on a given tree. --- .gitmodules | 3 + config/locales/en.yml | 3 +- lib/git_stats/base.rb | 1 + lib/git_stats/cli.rb | 3 +- lib/git_stats/generator.rb | 4 +- lib/git_stats/git_data/commit.rb | 6 +- lib/git_stats/git_data/repo.rb | 15 +- lib/git_stats/git_data/short_stat.rb | 2 +- lib/git_stats/git_data/tree.rb | 25 ++++ spec/factories.rb | 8 ++ spec/git_data/commit_range_spec.rb | 4 +- spec/git_data/commit_spec.rb | 2 +- spec/git_data/generator_spec.rb | 4 +- spec/git_data/repo_spec.rb | 4 +- spec/git_data/short_stat_spec.rb | 2 +- spec/git_data/tree_spec.rb | 41 ++++++ spec/integration/shared.rb | 91 +++++++++++++ spec/integration/test_repo_tree | 1 + spec/integration/tree_spec.rb | 197 +++++++++++++++++++++++++++ templates/general.haml | 3 + 20 files changed, 399 insertions(+), 20 deletions(-) create mode 100644 lib/git_stats/git_data/tree.rb create mode 100644 spec/git_data/tree_spec.rb create mode 160000 spec/integration/test_repo_tree create mode 100644 spec/integration/tree_spec.rb diff --git a/.gitmodules b/.gitmodules index 437ea32b8..74b19503d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "spec/integration/test_repo"] path = spec/integration/test_repo url = git://github.com/tomgi/git_stats_test_repo.git +[submodule "spec/integration/test_repo_tree"] + path = spec/integration/test_repo_tree + url = git://github.com/irevert/git_stats_test_repo_tree diff --git a/config/locales/en.yml b/config/locales/en.yml index 41c44a929..5b86ac490 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,6 +1,7 @@ en: project_name: Project name project_version: Project version + tree_path: Tree path generated_at: Generated at generator: Generator report_period: Report period @@ -57,4 +58,4 @@ en: details: Details insertions_by_date: Lines added by date deletions_by_date: Lines deleted by date - changed_lines_by_date: Changed lines by date \ No newline at end of file + changed_lines_by_date: Changed lines by date diff --git a/lib/git_stats/base.rb b/lib/git_stats/base.rb index 314b2f5b7..cdec51f05 100644 --- a/lib/git_stats/base.rb +++ b/lib/git_stats/base.rb @@ -18,6 +18,7 @@ require 'git_stats/git_data/command_runner' require 'git_stats/git_data/commit' require 'git_stats/git_data/repo' require 'git_stats/git_data/short_stat' +require 'git_stats/git_data/tree' require 'git_stats/stats_view/template' require 'git_stats/stats_view/view' diff --git a/lib/git_stats/cli.rb b/lib/git_stats/cli.rb index edbb624b2..ac317c6f9 100644 --- a/lib/git_stats/cli.rb +++ b/lib/git_stats/cli.rb @@ -9,11 +9,12 @@ class GitStats::CLI < Thor option :from, :aliases => :f, :desc => 'Commit from where statistics should start.' option :to, :aliases => :t, :default => 'HEAD', :desc => 'Commit where statistics should stop.' option :silent, :aliases => :s, :type => :boolean, :desc => 'Silent mode. Don\'t output anything.' + option :tree, :aliases => :d, :default => '.', :desc => 'Tree where statistics should be generated.' desc 'generate', 'Generates the statistics of a repository' def generate I18n.locale = options[:language] - GitStats::Generator.new(options[:path], options[:output], options[:from], options[:to]) { |g| + GitStats::Generator.new(options[:path], options[:output], options[:from], options[:to], options[:tree]) { |g| g.add_command_observer { |command, result| puts "#{command}" } unless options[:silent] }.render_all end diff --git a/lib/git_stats/generator.rb b/lib/git_stats/generator.rb index 60b13b84d..b3a87f03f 100644 --- a/lib/git_stats/generator.rb +++ b/lib/git_stats/generator.rb @@ -4,10 +4,10 @@ module GitStats delegate :add_command_observer, to: :@repo delegate :render_all, to: :@view - def initialize(repo_path, out_path, first_commit_sha = nil, last_commit_sha = "HEAD") + def initialize(repo_path, out_path, first_commit_sha = nil, last_commit_sha = "HEAD", tree_path = ".") validate_repo_path(repo_path) - @repo = GitData::Repo.new(path: repo_path, first_commit_sha: first_commit_sha, last_commit_sha: last_commit_sha) + @repo = GitData::Repo.new(path: repo_path, first_commit_sha: first_commit_sha, last_commit_sha: last_commit_sha, tree_path: tree_path) view_data = StatsView::ViewData.new(@repo) @view = StatsView::View.new(view_data, out_path) diff --git a/lib/git_stats/git_data/commit.rb b/lib/git_stats/git_data/commit.rb index 146cd56cd..d8c6ee2db 100644 --- a/lib/git_stats/git_data/commit.rb +++ b/lib/git_stats/git_data/commit.rb @@ -9,7 +9,7 @@ module GitStats attr_reader :repo, :sha, :stamp, :date, :author def files - @files ||= repo.run_and_parse("git ls-tree -r #{self.sha}").map do |file| + @files ||= repo.run_and_parse("git ls-tree -r #{self.sha} -- #{repo.tree_path}").map do |file| Blob.new(repo: repo, filename: file[:filename], sha: file[:sha]) end.extend(ByFieldFinder) end @@ -37,11 +37,11 @@ module GitStats end def files_count - @files_count ||= repo.run("git ls-tree -r --name-only #{self.sha} | wc -l").to_i + @files_count ||= repo.run("git ls-tree -r --name-only #{self.sha} -- #{repo.tree_path}| wc -l").to_i end def lines_count - @lines_count ||= repo.run("git diff --shortstat `git hash-object -t tree /dev/null` #{self.sha}").lines.map do |line| + @lines_count ||= repo.run("git diff --shortstat `git hash-object -t tree /dev/null` #{self.sha} -- #{repo.tree_path}").lines.map do |line| line[/(\d+) insertions?/, 1].to_i end.sum end diff --git a/lib/git_stats/git_data/repo.rb b/lib/git_stats/git_data/repo.rb index e81d479d0..a68a86912 100644 --- a/lib/git_stats/git_data/repo.rb +++ b/lib/git_stats/git_data/repo.rb @@ -6,7 +6,7 @@ module GitStats class Repo include HashInitializable - attr_reader :path, :first_commit_sha, :last_commit_sha + attr_reader :path, :first_commit_sha, :last_commit_sha, :tree_path delegate :files, :files_by_extension, :files_by_extension_count, :lines_by_extension, :files_count, :binary_files, :text_files, :lines_count, to: :last_commit @@ -14,16 +14,17 @@ module GitStats def initialize(params) super(params) @path = File.expand_path(@path) + @tree_path ||= "." end def authors - @authors ||= run_and_parse("git shortlog -se #{commit_range}").map do |author| + @authors ||= run_and_parse("git shortlog -se #{commit_range} #{tree_path}").map do |author| Author.new(repo: self, name: author[:name], email: author[:email]) end.extend(ByFieldFinder) end def commits - @commits ||= run_and_parse("git rev-list --pretty=format:'%h|%at|%ai|%aE' #{commit_range} | grep -v commit").map do |commit_line| + @commits ||= run_and_parse("git rev-list --pretty=format:'%h|%at|%ai|%aE' #{commit_range} #{tree_path} | grep -v commit").map do |commit_line| Commit.new( repo: self, sha: commit_line[:sha], @@ -87,8 +88,13 @@ module GitStats @project_version ||= run("git rev-parse --short #{commit_range}").strip end + def tree + @tree ||= Tree.new(repo: self, relative_path: @tree_path) + end + def project_name - @project_name ||= File.basename(path) + # @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)) end def run(command) @@ -132,6 +138,7 @@ module GitStats command_observers.each { |o| o.call(command, result) } end + end end end diff --git a/lib/git_stats/git_data/short_stat.rb b/lib/git_stats/git_data/short_stat.rb index a02897665..33604c90c 100644 --- a/lib/git_stats/git_data/short_stat.rb +++ b/lib/git_stats/git_data/short_stat.rb @@ -19,7 +19,7 @@ module GitStats private def calculate_stat - stat_line = commit.repo.run("git show --shortstat --oneline #{commit.sha}").lines.to_a[1] + stat_line = commit.repo.run("git show --shortstat --oneline #{commit.sha} -- #{commit.repo.tree_path}").lines.to_a[1] if stat_line.blank? @files_changed = @insertions = @deletions = 0 else diff --git a/lib/git_stats/git_data/tree.rb b/lib/git_stats/git_data/tree.rb new file mode 100644 index 000000000..a0ad1786a --- /dev/null +++ b/lib/git_stats/git_data/tree.rb @@ -0,0 +1,25 @@ +# -*- encoding : utf-8 -*- +require 'git_stats/hash_initializable' + +module GitStats + module GitData + class Tree + include HashInitializable + attr_reader :repo, :relative_path + def initialize(params) + super(params) + end + + def authors + @authors ||= run_and_parse("git shortlog -se #{commit_range}").map do |author| + Author.new(repo: self, name: author[:name], email: author[:email]) + end.extend(ByFieldFinder) + end + + def ==(other) + ((self.repo == other.repo) && (self.relative_path == other.relative_path)) + end + + end + end +end diff --git a/spec/factories.rb b/spec/factories.rb index 3b2518abd..4bc4eb2e5 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -7,6 +7,9 @@ FactoryGirl.define do factory :test_repo do path 'spec/integration/test_repo' end + factory :test_repo_tree do + path 'spec/integration/test_repo_tree' + end end factory :author, class: GitStats::GitData::Author do @@ -22,4 +25,9 @@ FactoryGirl.define do association :repo, strategy: :build association :author, strategy: :build end + + factory :tree, class: GitStats::GitData::Tree do + association :repo, strategy: :build + end + end diff --git a/spec/git_data/commit_range_spec.rb b/spec/git_data/commit_range_spec.rb index 79c13411c..b4096795b 100644 --- a/spec/git_data/commit_range_spec.rb +++ b/spec/git_data/commit_range_spec.rb @@ -28,12 +28,12 @@ describe GitStats::GitData::Repo do let(:repo) { build(:repo, first_commit_sha: 'abc', last_commit_sha: 'def') } it 'should affect authors command' do - repo.should_receive(:run).with('git shortlog -se abc..def').and_return("") + repo.should_receive(:run).with('git shortlog -se abc..def .').and_return("") repo.authors end it 'should affect commits command' do - repo.should_receive(:run).with("git rev-list --pretty=format:'%h|%at|%ai|%aE' abc..def | grep -v commit").and_return("") + repo.should_receive(:run).with("git rev-list --pretty=format:'%h|%at|%ai|%aE' abc..def . | grep -v commit").and_return("") repo.commits end diff --git a/spec/git_data/commit_spec.rb b/spec/git_data/commit_spec.rb index 879de4321..6ed1b55ac 100644 --- a/spec/git_data/commit_spec.rb +++ b/spec/git_data/commit_spec.rb @@ -7,7 +7,7 @@ describe GitStats::GitData::Commit do describe 'git output parsing' do context 'parsing git ls-tree output' do before { - commit.repo.should_receive(:run).with('git ls-tree -r abc').and_return("100644 blob 5ade7ad51a75ee7db4eb06cecd3918d38134087d lib/git_stats/git_data/commit.rb + commit.repo.should_receive(:run).with('git ls-tree -r abc -- .').and_return("100644 blob 5ade7ad51a75ee7db4eb06cecd3918d38134087d lib/git_stats/git_data/commit.rb 100644 blob db01e94677a8f72289848e507a52a43de2ea109a lib/git_stats/git_data/repo.rb 100644 blob 1463eacb3ac9f95f21f360f1eb935a84a9ee0895 templates/index.haml 100644 blob 31d8b960a67f195bdedaaf9e7aa70b2389f3f1a8 templates/assets/bootstrap/css/bootstrap.min.css diff --git a/spec/git_data/generator_spec.rb b/spec/git_data/generator_spec.rb index c70e9e1de..7aead81ca 100644 --- a/spec/git_data/generator_spec.rb +++ b/spec/git_data/generator_spec.rb @@ -15,7 +15,7 @@ describe GitStats::Generator do it 'should pass command observer to repo' do repo = double('repo') - GitStats::GitData::Repo.should_receive(:new).with(path: repo_path, first_commit_sha: nil, last_commit_sha: "HEAD").and_return(repo) + GitStats::GitData::Repo.should_receive(:new).with(path: repo_path, first_commit_sha: nil, last_commit_sha: "HEAD", tree_path: ".").and_return(repo) generator = GitStats::Generator.new(repo_path, out_path) @@ -27,7 +27,7 @@ describe GitStats::Generator do it 'should render all templates with view data for this repo' do repo = double('repo') - GitStats::GitData::Repo.should_receive(:new).with(path: repo_path, first_commit_sha: nil, last_commit_sha: "HEAD").and_return(repo) + GitStats::GitData::Repo.should_receive(:new).with(path: repo_path, first_commit_sha: nil, last_commit_sha: "HEAD", tree_path: ".").and_return(repo) view_data = double('view_data') GitStats::StatsView::ViewData.should_receive(:new).with(repo).and_return(view_data) diff --git a/spec/git_data/repo_spec.rb b/spec/git_data/repo_spec.rb index ebf6a1855..c6f8375cb 100644 --- a/spec/git_data/repo_spec.rb +++ b/spec/git_data/repo_spec.rb @@ -7,7 +7,7 @@ describe GitStats::GitData::Repo do describe 'git output parsing' do context 'invoking authors command' do before do - repo.should_receive(:run).with('git shortlog -se HEAD').and_return(" 156 John Doe + repo.should_receive(:run).with('git shortlog -se HEAD .').and_return(" 156 John Doe 53 Joe Doe ") end @@ -19,7 +19,7 @@ describe GitStats::GitData::Repo do end it 'should parse git revlist output to date sorted commits array' do - repo.should_receive(:run).with("git rev-list --pretty=format:'%h|%at|%ai|%aE' HEAD | grep -v commit").and_return( + repo.should_receive(:run).with("git rev-list --pretty=format:'%h|%at|%ai|%aE' HEAD . | grep -v commit").and_return( "e4412c3|1348603824|2012-09-25 22:10:24 +0200|john.doe@gmail.com ce34874|1347482927|2012-09-12 22:48:47 +0200|joe.doe@gmail.com 5eab339|1345835073|2012-08-24 21:04:33 +0200|john.doe@gmail.com diff --git a/spec/git_data/short_stat_spec.rb b/spec/git_data/short_stat_spec.rb index 1abc6d737..57efa675e 100644 --- a/spec/git_data/short_stat_spec.rb +++ b/spec/git_data/short_stat_spec.rb @@ -14,7 +14,7 @@ describe GitStats::GitData::ShortStat do {content: '', expect: [0, 0, 0]}, ].each do |test| it "#{test[:content]} parsing" do - commit.repo.should_receive(:run).with("git show --shortstat --oneline abc").and_return("abc some commit\n#{test[:content]}") + commit.repo.should_receive(:run).with("git show --shortstat --oneline abc -- .").and_return("abc some commit\n#{test[:content]}") commit.short_stat.should be_a(GitStats::GitData::ShortStat) diff --git a/spec/git_data/tree_spec.rb b/spec/git_data/tree_spec.rb new file mode 100644 index 000000000..bd88b4338 --- /dev/null +++ b/spec/git_data/tree_spec.rb @@ -0,0 +1,41 @@ +# -*- encoding : utf-8 -*- +require 'spec_helper' + +describe GitStats::GitData::Tree do + let(:repo) { build(:test_repo_tree, tree_path: '.') } + let(:repo_tree) { build(:test_repo_tree, tree_path: './subdir_with_1_commit') } + let(:tree) { build(:tree, repo: repo_tree, relative_path: './subdir_with_1_commit') } + + describe 'tree git output parsing' do + it 'should return . by default' do + repo.tree.should == GitStats::GitData::Tree.new(repo: repo, relative_path: '.') + end + + it 'should return relative_path given by parameter' do + repo_tree.tree.should == GitStats::GitData::Tree.new(repo: repo, relative_path: './subdir_with_1_commit') + repo_tree.tree.relative_path.should == './subdir_with_1_commit' + tree.relative_path.should == './subdir_with_1_commit' + end + + context 'invoking authors command' do + before do + repo_tree.should_receive(:run).with('git shortlog -se HEAD ./subdir_with_1_commit').and_return(" 3 Israel Revert +") + end + + it 'should parse git shortlog output to authors hash' do + repo_tree.authors.should == [ build(:author, repo: repo_tree, name: "Israel Revert", email:"israelrevert@gmail.com") ] + end + + it 'should parse git revlist output to date sorted commits array' do + repo_tree.should_receive(:run). + with("git rev-list --pretty=format:'%h|%at|%ai|%aE' HEAD ./subdir_with_1_commit | grep -v commit"). + and_return("10d1814|1395407506|2014-03-21 14:11:46 +0100|israelrevert@gmail.com") + repo_tree.commits.should == + [ GitStats::GitData::Commit.new( repo: repo, sha: "10d1814", stamp: "1395407506", + date: DateTime.parse("2014-03-21 14:11:46 +0100"), + author: repo.authors.by_email("israelrevert@gmail.com"))] + end + end + end +end diff --git a/spec/integration/shared.rb b/spec/integration/shared.rb index e4c37f9dd..0744d140a 100644 --- a/spec/integration/shared.rb +++ b/spec/integration/shared.rb @@ -44,3 +44,94 @@ shared_context "shared" do build(:author, repo: repo, name: "John Doe", email: "john.doe@gmail.com"), ] } end + + +shared_context "tree_subdir_with_1_commit" do + let(:repo) { build(:test_repo_tree, last_commit_sha: 'HEAD', tree_path: './subdir_with_1_commit') } + let(:commit_dates) { [ + DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:12:23 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100'), + ] } + let(:commit_dates_with_empty) {[ + Date.new(2014, 03, 21), + Date.new(2014, 03, 21), + Date.new(2014, 03, 21), + ]} + let(:tg_commit_dates) { [ + DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:12:23 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100'), + ] } + let(:jd_commit_dates) { [ + DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:12:23 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100'), + ] } + + let(:expected_authors) { [ + build(:author, repo: repo, name: "Israel Revert", email: "israelrevert@gmail.com"), + ] } +end + +shared_context "tree_subdir_with_2_commit" do + let(:repo) { build(:test_repo_tree, last_commit_sha: 'HEAD', tree_path: './subdir_with_2_commits') } + let(:commit_dates) { [ + DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:12:23 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100'), + ] } + let(:commit_dates_with_empty) {[ + Date.new(2014, 03, 21), + Date.new(2014, 03, 21), + Date.new(2014, 03, 21), + ]} + let(:tg_commit_dates) { [ + DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:12:23 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100'), + ] } + let(:jd_commit_dates) { [ + DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:12:23 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100'), + ] } + + let(:expected_authors) { [ + build(:author, repo: repo, name: "Israel Revert", email: "israelrevert@gmail.com"), + ] } +end + + + +# 5fd0f5e|1395407567|2014-03-21 14:12:47 +0100|israelrevert@gmail.com +# 435e0ef|1395407543|2014-03-21 14:12:23 +0100|israelrevert@gmail.com +# 10d1814|1395407506|2014-03-21 14:11:46 +0100|israelrevert@gmail.com + +shared_context "tree" do + let(:repo) { build(:test_repo_tree, last_commit_sha: 'HEAD') } + let(:commit_dates) { [ + DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:12:23 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100'), + ] } + let(:commit_dates_with_empty) {[ + Date.new(2014, 03, 21), + Date.new(2014, 03, 21), + Date.new(2014, 03, 21), + ]} + let(:tg_commit_dates) { [ + DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:12:23 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100'), + ] } + let(:jd_commit_dates) { [ + DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:12:23 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100'), + ] } + + let(:expected_authors) { [ + build(:author, repo: repo, name: "Israel Revert", email: "israelrevert@gmail.com"), + ] } +end diff --git a/spec/integration/test_repo_tree b/spec/integration/test_repo_tree new file mode 160000 index 000000000..5fd0f5ea9 --- /dev/null +++ b/spec/integration/test_repo_tree @@ -0,0 +1 @@ +Subproject commit 5fd0f5ea90e0ef34a0214ec9c170728913525ff4 diff --git a/spec/integration/tree_spec.rb b/spec/integration/tree_spec.rb new file mode 100644 index 000000000..bbb740aef --- /dev/null +++ b/spec/integration/tree_spec.rb @@ -0,0 +1,197 @@ +# -*- encoding : utf-8 -*- +require 'integration/shared' + +describe GitStats::GitData::Tree do + include_context "tree" + + it 'should gather all authors' do + repo.authors.should =~ expected_authors + end + + it 'should calculate correct commits period' do + repo.commits_period.should == [DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100')] + end + + it 'should gather all commits sorted by date' do + repo.commits.map(&:sha).should =~ %w(10d1814 435e0ef 5fd0f5e) + end + + it 'should return project name from dir' do + repo.project_name.should == 'test_repo_tree' + end + + it 'should return project version as last commit hash' do + repo.project_version.should == '5fd0f5e' + end + + it 'should count files in repo' do + repo.files_count.should == 4 + end + + it 'should count files by date' do + repo.files_count_by_date.keys == Hash[commit_dates_with_empty.zip [2, 3, 4]] + end + + it 'should count lines by date' do + repo.files_count_by_date.values == Hash[commit_dates_with_empty.zip [1, 2, 2]] + end + + it 'should count all lines in repo' do + repo.lines_count.should == 0 + end + + it 'should count files by extension in repo' do + repo.files_by_extension_count.should == {'' => 4} + end + + it 'should count lines by extension in repo' do + repo.lines_by_extension.should == {} + end + + it 'should count commits_count_by_author' do + repo.commits_count_by_author.keys.should == expected_authors + repo.commits_count_by_author.values.should == [3] + end + + it 'should count lines_added_by_author' do + repo.insertions_by_author.keys.should == expected_authors + repo.insertions_by_author.values.should == [0] + end + + it 'should count lines_deleted_by_author' do + repo.deletions_by_author.keys.should == expected_authors + repo.deletions_by_author.values.should == [0] + end + +end + +describe GitStats::GitData::Tree do + include_context "tree_subdir_with_1_commit" + + it 'should gather all authors' do + repo.authors.should =~ expected_authors + end + + it 'should calculate correct commits period' do + repo.commits_period.should == [DateTime.parse('2014-03-21 14:11:46 +0100'), + DateTime.parse('2014-03-21 14:11:46 +0100')] + end + + it 'should gather all commits sorted by date' do + repo.commits.map(&:sha).should =~ %w(10d1814) + end + + it 'should return project name from dir' do + repo.project_name.should == 'test_repo_tree/subdir_with_1_commit' + end + + it 'should return project version as last commit hash' do + repo.project_version.should == '5fd0f5e' + end + + it 'should count files in repo' do + repo.files_count.should == 2 + end + + it 'should count files by date' do + repo.files_count_by_date.keys == Hash[commit_dates_with_empty.zip [2]] + end + + it 'should count lines by date' do + repo.files_count_by_date.values == Hash[commit_dates_with_empty.zip [1]] + end + + it 'should count all lines in repo' do + repo.lines_count.should == 0 + end + + it 'should count files by extension in repo' do + repo.files_by_extension_count.should == {'' => 2} + end + + it 'should count lines by extension in repo' do + repo.lines_by_extension.should == {} + end + + it 'should count commits_count_by_author' do + repo.commits_count_by_author.keys.should == expected_authors + repo.commits_count_by_author.values.should == [1] + end + + it 'should count lines_added_by_author' do + repo.insertions_by_author.keys.should == expected_authors + repo.insertions_by_author.values.should == [0] + end + + it 'should count lines_deleted_by_author' do + repo.deletions_by_author.keys.should == expected_authors + repo.deletions_by_author.values.should == [0] + end + +end + +describe GitStats::GitData::Tree do + include_context "tree_subdir_with_2_commit" + + it 'should gather all authors' do + repo.authors.should =~ expected_authors + end + + it 'should calculate correct commits period' do + repo.commits_period.should == [DateTime.parse('2014-03-21 14:12:23 +0100'), + DateTime.parse('2014-03-21 14:12:47 +0100')] + end + + it 'should gather all commits sorted by date' do + repo.commits.map(&:sha).should =~ %w(435e0ef 5fd0f5e) + end + + it 'should return project name from dir' do + repo.project_name.should == 'test_repo_tree/subdir_with_2_commits' + end + + it 'should return project version as last commit hash' do + repo.project_version.should == '5fd0f5e' + end + + it 'should count files in repo' do + repo.files_count.should == 2 + end + + it 'should count files by date' do + repo.files_count_by_date.keys == Hash[commit_dates_with_empty.zip [1, 2]] + end + + it 'should count lines by date' do + repo.files_count_by_date.values == Hash[commit_dates_with_empty.zip [2, 2]] + end + + it 'should count all lines in repo' do + repo.lines_count.should == 0 + end + + it 'should count files by extension in repo' do + repo.files_by_extension_count.should == {'' => 2} + end + + it 'should count lines by extension in repo' do + repo.lines_by_extension.should == {} + end + + it 'should count commits_count_by_author' do + repo.commits_count_by_author.keys.should == expected_authors + repo.commits_count_by_author.values.should == [2] + end + + it 'should count lines_added_by_author' do + repo.insertions_by_author.keys.should == expected_authors + repo.insertions_by_author.values.should == [0] + end + + it 'should count lines_deleted_by_author' do + repo.deletions_by_author.keys.should == expected_authors + repo.deletions_by_author.values.should == [0] + end + +end diff --git a/templates/general.haml b/templates/general.haml index c4f0680b6..383d8a787 100644 --- a/templates/general.haml +++ b/templates/general.haml @@ -5,6 +5,9 @@ %tr %td= :project_version.t %td= repo.project_version + %tr + %td= :tree_path.t + %td= repo.tree_path %tr %td= :generated_at.t %td= I18n.localize(DateTime.now, format: :long) From 98228f0c796a3bae5e9d27607122d8a0c44051c6 Mon Sep 17 00:00:00 2001 From: Tomasz Gieniusz Date: Sun, 22 Jun 2014 14:23:34 +0200 Subject: [PATCH 2/2] updated readme with information about --tree option --- README.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c566e169a..83336177e 100644 --- a/README.md +++ b/README.md @@ -34,16 +34,20 @@ It browses the repository and outputs html page with statistics. git_stats generate Options: - p, [--path=PATH] # Path to repository from which statistics should be generated. - # Default: . - o, [--output=OUTPUT] # Output path where statistics should be written. - # Default: ./git_stats - l, [--language=LANGUAGE] # Language of written statistics. - # Default: en - f, [--from=FROM] # Commit from where statistics should start. - t, [--to=TO] # Commit where statistics should stop. - # Default: HEAD - s, [--silent] # Silent mode. Don't output anything. + p, [--path=PATH] # Path to repository from which statistics should be generated. + # Default: . + o, [--output=OUTPUT] # Output path where statistics should be written. + # Default: ./git_stats + l, [--language=LANGUAGE] # Language of written statistics. + # Default: en + f, [--from=FROM] # Commit from where statistics should start. + t, [--to=TO] # Commit where statistics should stop. + # Default: HEAD + s, [--silent], [--no-silent] # Silent mode. Don't output anything. + d, [--tree=TREE] # Tree where statistics should be generated. + # Default: . + + #### Start generator with default settings