git_statistics 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -0
- data/Gemfile.lock +33 -11
- data/README.md +8 -3
- data/git_statistics.gemspec +2 -0
- data/lib/git_statistics/blob.rb +5 -0
- data/lib/git_statistics/collector.rb +320 -68
- data/lib/git_statistics/commits.rb +65 -66
- data/lib/git_statistics/initialize.rb +12 -0
- data/lib/git_statistics/version.rb +1 -1
- data/lib/git_statistics.rb +3 -2
- metadata +50 -20
- data/spec/collector_spec.rb +0 -6
- data/spec/commits_spec.rb +0 -381
- data/spec/fixtures/many_authors.json +0 -62
- data/spec/fixtures/single_author.json +0 -26
- data/spec/fixtures/single_author_unpretty.json +0 -1
@@ -1,112 +1,112 @@
|
|
1
1
|
module GitStatistics
|
2
2
|
class Commits < Hash
|
3
3
|
|
4
|
-
attr_accessor :
|
4
|
+
attr_accessor :stats, :author_list, :language_list, :totals
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
super
|
8
|
+
@stats = Hash.new(0)
|
9
|
+
@author_list = []
|
10
|
+
@language_list = []
|
11
|
+
@totals = Hash.new(0)
|
12
|
+
@totals[:languages] = {}
|
8
13
|
end
|
9
14
|
|
10
|
-
def
|
11
|
-
author_list = []
|
15
|
+
def identify_authors
|
12
16
|
self.each do |key,value|
|
13
|
-
if not author_list.include?(value[:author])
|
14
|
-
author_list << value[:author]
|
17
|
+
if not @author_list.include?(value[:author])
|
18
|
+
@author_list << value[:author]
|
15
19
|
end
|
16
20
|
end
|
17
|
-
return author_list
|
18
21
|
end
|
19
22
|
|
20
|
-
def
|
21
|
-
author_list = []
|
23
|
+
def identify_authors_email
|
22
24
|
self.each do |key,value|
|
23
|
-
if not author_list.include?(value[:author_email])
|
24
|
-
author_list << value[:author_email]
|
25
|
+
if not @author_list.include?(value[:author_email])
|
26
|
+
@author_list << value[:author_email]
|
25
27
|
end
|
26
28
|
end
|
27
|
-
return author_list
|
28
29
|
end
|
29
30
|
|
30
|
-
def
|
31
|
+
def author_top_n_type(type, n=0)
|
32
|
+
n = 0 if n < 0
|
33
|
+
return nil if @stats == nil || !@stats.first[1].has_key?(type)
|
34
|
+
return @stats.sorted_hash {|a,b| b[1][type.to_sym] <=> a[1][type]}.to_a[0..n-1]
|
35
|
+
end
|
36
|
+
|
37
|
+
def calculate_statistics(email, merge)
|
31
38
|
|
32
39
|
# Identify authors and author type
|
33
40
|
if email
|
34
|
-
|
41
|
+
identify_authors_email
|
35
42
|
type = :author_email
|
36
43
|
else
|
37
|
-
|
44
|
+
identify_authors
|
38
45
|
type = :author
|
39
46
|
end
|
40
47
|
|
41
48
|
# Initialize the stats hash
|
42
|
-
stats = Hash.new
|
43
49
|
@author_list.each do |author|
|
44
|
-
stats[author] = Hash.new
|
45
|
-
stats[author][:
|
46
|
-
stats[author][:insertions] = 0
|
47
|
-
stats[author][:deletions] = 0
|
48
|
-
stats[author][:creates] = 0
|
49
|
-
stats[author][:deletes] = 0
|
50
|
-
stats[author][:renames] = 0
|
51
|
-
stats[author][:copies] = 0
|
52
|
-
stats[author][:merges] = 0
|
50
|
+
@stats[author] = Hash.new(0)
|
51
|
+
@stats[author][:languages] = {}
|
53
52
|
end
|
54
53
|
|
55
|
-
# Collect the stats
|
54
|
+
# Collect the stats from each commit
|
56
55
|
self.each do |key,value|
|
57
56
|
if not merge and value[:merge]
|
58
57
|
next
|
59
58
|
else
|
60
|
-
stats[value[type]][:merges] += 1 if value[:merge]
|
61
|
-
stats[value[type]][:commits] += 1
|
62
|
-
stats[value[type]][:insertions] += value[:insertions]
|
63
|
-
stats[value[type]][:deletions] += value[:deletions]
|
64
|
-
stats[value[type]][:creates] += value[:creates]
|
65
|
-
stats[value[type]][:deletes] += value[:deletes]
|
66
|
-
stats[value[type]][:renames] += value[:renames]
|
67
|
-
stats[value[type]][:copies] += value[:copies]
|
68
|
-
end
|
69
|
-
end
|
70
|
-
return stats
|
71
|
-
end
|
72
59
|
|
73
|
-
|
74
|
-
n = 0 if n < 0
|
60
|
+
author = (@stats[value[type]] ||= Hash.new(0))
|
75
61
|
|
76
|
-
|
77
|
-
|
78
|
-
else
|
79
|
-
data = @data_authors
|
80
|
-
end
|
62
|
+
# Collect language stats
|
63
|
+
value[:files].each do |file|
|
81
64
|
|
82
|
-
|
83
|
-
|
84
|
-
end
|
65
|
+
# Add to author's languages
|
66
|
+
add_language_stats(author, file)
|
85
67
|
|
86
|
-
|
68
|
+
# Add to repository's languages
|
69
|
+
add_language_stats(@totals, file)
|
87
70
|
|
88
|
-
|
89
|
-
|
90
|
-
|
71
|
+
# Add language to language list if not encountered before
|
72
|
+
if not @language_list.include?(file[:language])
|
73
|
+
@language_list << file[:language]
|
74
|
+
end
|
75
|
+
end
|
91
76
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
else
|
98
|
-
@totals[:merges] += 1 if value[:merge]
|
99
|
-
@totals[:commits] += 1
|
100
|
-
@totals[:insertions] += value[:insertions]
|
101
|
-
@totals[:deletions] += value[:deletions]
|
102
|
-
@totals[:creates] += value[:creates]
|
103
|
-
@totals[:deletes] += value[:deletes]
|
104
|
-
@totals[:renames] += value[:renames]
|
105
|
-
@totals[:copies] += value[:copies]
|
77
|
+
# Add commit stats to author
|
78
|
+
add_commit_stats(author, value)
|
79
|
+
|
80
|
+
# Add commit stats to repository
|
81
|
+
add_commit_stats(@totals, value)
|
106
82
|
end
|
107
83
|
end
|
108
84
|
end
|
109
85
|
|
86
|
+
def add_language_stats(data, file)
|
87
|
+
# Add stats to data's languages
|
88
|
+
if data[:languages][file[:language].to_sym] == nil
|
89
|
+
data[:languages][file[:language].to_sym] = Hash.new(0)
|
90
|
+
end
|
91
|
+
data[:languages][file[:language].to_sym][:additions] += file[:additions]
|
92
|
+
data[:languages][file[:language].to_sym][:deletions] += file[:deletions]
|
93
|
+
if file[:status] != nil || file[:status] == "submodule"
|
94
|
+
data[:languages][file[:language].to_sym][file[:status].to_sym] += 1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_commit_stats(data, commit)
|
99
|
+
# Add commit stats to author
|
100
|
+
data[:merges] += 1 if commit[:merge]
|
101
|
+
data[:commits] += 1
|
102
|
+
data[:additions] += commit[:additions]
|
103
|
+
data[:deletions] += commit[:deletions]
|
104
|
+
data[:create] += commit[:create] if commit[:create] != nil
|
105
|
+
data[:delete] += commit[:delete] if commit[:delete] != nil
|
106
|
+
data[:rename] += commit[:rename] if commit[:rename] != nil
|
107
|
+
data[:copy] += commit[:copy] if commit[:copy] != nil
|
108
|
+
end
|
109
|
+
|
110
110
|
def load(file)
|
111
111
|
self.merge!(JSON.parse(File.read(file), :symbolize_names => true))
|
112
112
|
end
|
@@ -121,7 +121,6 @@ module GitStatistics
|
|
121
121
|
end
|
122
122
|
|
123
123
|
class Hash < Hash
|
124
|
-
|
125
124
|
def sorted_hash(&block)
|
126
125
|
self.class[sort(&block)]
|
127
126
|
end
|
@@ -1,3 +1,15 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'trollop'
|
3
|
+
require 'grit'
|
4
|
+
require 'linguist'
|
5
|
+
require 'pathname'
|
6
|
+
|
7
|
+
# Custom Blob for Grit to enable Linguist
|
8
|
+
# This must load before other modules
|
9
|
+
module Grit
|
10
|
+
class Blob
|
11
|
+
include Linguist::BlobHelper
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
3
15
|
Dir.glob(File.dirname(__FILE__) + '/*.rb') {|file| require file}
|
data/lib/git_statistics.rb
CHANGED
@@ -10,14 +10,15 @@ module GitStatistics
|
|
10
10
|
opt :pretty, "Pretty print saved commits (larger file size)", :default => false
|
11
11
|
opt :load, "Load commits.json instead of re-collecting data", :default => false
|
12
12
|
opt :update, "Update commits.json with new data (same as save and load together)", :default => false
|
13
|
-
opt :sort, "Sort authors by {commits,
|
13
|
+
opt :sort, "Sort authors by {commits, additions, deletions, create, delete, rename, copy, merges}", :default => "commits"
|
14
14
|
opt :top, "Show the top N authors in results", :default => 0
|
15
15
|
opt :branch, "Use current branch for statistics (otherwise all branches)", :default => false
|
16
|
+
opt :verbose, "Verbose output (shows progress)", :default => false
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
20
|
def execute
|
20
|
-
collector = Collector.new
|
21
|
+
collector = Collector.new(@opts[:verbose])
|
21
22
|
|
22
23
|
# Collect commit data
|
23
24
|
if @opts[:load] || @opts[:update]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git_statistics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,31 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: trollop
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: grit
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
28
49
|
none: false
|
29
50
|
requirements:
|
30
51
|
- - ! '>='
|
@@ -32,7 +53,28 @@ dependencies:
|
|
32
53
|
version: '0'
|
33
54
|
type: :runtime
|
34
55
|
prerelease: false
|
35
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: github-linguist
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
36
78
|
description: git_statistics is a gem that provides detailed git statistics
|
37
79
|
email:
|
38
80
|
- kevin.j.jalbert@gmail.com
|
@@ -51,15 +93,11 @@ files:
|
|
51
93
|
- bin/git_statistics
|
52
94
|
- git_statistics.gemspec
|
53
95
|
- lib/git_statistics.rb
|
96
|
+
- lib/git_statistics/blob.rb
|
54
97
|
- lib/git_statistics/collector.rb
|
55
98
|
- lib/git_statistics/commits.rb
|
56
99
|
- lib/git_statistics/initialize.rb
|
57
100
|
- lib/git_statistics/version.rb
|
58
|
-
- spec/collector_spec.rb
|
59
|
-
- spec/commits_spec.rb
|
60
|
-
- spec/fixtures/many_authors.json
|
61
|
-
- spec/fixtures/single_author.json
|
62
|
-
- spec/fixtures/single_author_unpretty.json
|
63
101
|
- spec/spec_helper.rb
|
64
102
|
homepage: https://github.com/kevinjalbert/git_statistics
|
65
103
|
licenses: []
|
@@ -79,19 +117,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
117
|
- - ! '>='
|
80
118
|
- !ruby/object:Gem::Version
|
81
119
|
version: '0'
|
82
|
-
segments:
|
83
|
-
- 0
|
84
|
-
hash: -1773514383536300330
|
85
120
|
requirements: []
|
86
121
|
rubyforge_project:
|
87
|
-
rubygems_version: 1.8.
|
122
|
+
rubygems_version: 1.8.24
|
88
123
|
signing_key:
|
89
124
|
specification_version: 3
|
90
125
|
summary: Gem that provides the ability to gather detailed git statistics
|
91
126
|
test_files:
|
92
|
-
- spec/collector_spec.rb
|
93
|
-
- spec/commits_spec.rb
|
94
|
-
- spec/fixtures/many_authors.json
|
95
|
-
- spec/fixtures/single_author.json
|
96
|
-
- spec/fixtures/single_author_unpretty.json
|
97
127
|
- spec/spec_helper.rb
|