hans-gitchart 1.0 → 1.1
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/Rakefile +5 -0
- data/bin/git-chart +18 -2
- data/gitchart.gemspec +2 -2
- data/lib/gitchart.rb +102 -8
- data/lib/platform.rb +101 -0
- metadata +2 -2
data/Rakefile
CHANGED
@@ -16,3 +16,8 @@ end
|
|
16
16
|
task :default => "pkg/#{spec.name}-#{spec.version}.gem" do
|
17
17
|
puts 'generated latest version'
|
18
18
|
end
|
19
|
+
|
20
|
+
desc "build 'n' install"
|
21
|
+
task :bni => "pkg/#{spec.name}-#{spec.version}.gem" do
|
22
|
+
puts `sudo gem install pkg/#{spec.name}-#{spec.version}.gem`
|
23
|
+
end
|
data/bin/git-chart
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
1
|
+
#!/usr/bin/env ruby -s
|
2
2
|
|
3
3
|
=begin
|
4
4
|
Copyright (c) 2008 Hans Engel
|
@@ -8,5 +8,21 @@ See the file LICENSE for licensing details.
|
|
8
8
|
begin; require 'rubygems'; rescue LoadError; end
|
9
9
|
require 'gitchart'
|
10
10
|
|
11
|
-
|
11
|
+
repo = '.'
|
12
|
+
branch = 'master'
|
13
|
+
size = '1000x300'
|
14
|
+
threed = true
|
15
|
+
|
16
|
+
repo = ARGV[0] if ARGV[0]
|
17
|
+
branch = ARGV[1] if ARGV[1]
|
18
|
+
size = ARGV[2] if ARGV[2]
|
19
|
+
|
20
|
+
if ARGV[3]
|
21
|
+
threed = case ARGV[3]
|
22
|
+
when 'true': true
|
23
|
+
when 'false': false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
gc = GitChart.new size, threed, repo, branch
|
12
28
|
gc.run
|
data/gitchart.gemspec
CHANGED
@@ -6,9 +6,9 @@ See the file LICENSE for licensing details.
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.name = 'gitchart'
|
9
|
-
s.version = '1.
|
9
|
+
s.version = '1.1'
|
10
10
|
s.date = '2008-08-23'
|
11
|
-
s.homepage = 'http://
|
11
|
+
s.homepage = 'http://gitchart.rubyforge.org'
|
12
12
|
s.author = 'Hans Engel'
|
13
13
|
s.email = 'spam.me@engel.uk.to'
|
14
14
|
s.summary = 'Generate cool stats about Git repositories'
|
data/lib/gitchart.rb
CHANGED
@@ -6,7 +6,6 @@ See the file LICENSE for licensing details.
|
|
6
6
|
require 'ftools'
|
7
7
|
require 'tempfile'
|
8
8
|
|
9
|
-
require 'gitchart'
|
10
9
|
require 'platform'
|
11
10
|
require 'google_chart'
|
12
11
|
include GoogleChart
|
@@ -64,21 +63,36 @@ EOF
|
|
64
63
|
end
|
65
64
|
|
66
65
|
def run
|
67
|
-
|
66
|
+
puts "Generating chart data . . ."
|
67
|
+
puts "This may take a while, depending on the size of your repository."
|
68
|
+
begin
|
69
|
+
@commits = @repo.commits_since @branch
|
70
|
+
rescue SystemStackError
|
71
|
+
puts "Uh oh, your repository is humongous. We're going to have to only grab stats for the last several hundred."
|
72
|
+
puts "How many commits should be graphed? (750 is probably as far as you can get). "
|
73
|
+
amt = gets
|
74
|
+
@commits = @repo.commits @branch, amt.strip.to_i
|
75
|
+
end
|
68
76
|
chart_authors
|
69
|
-
chart_commits
|
77
|
+
chart_commits :bar
|
78
|
+
chart_commits :line
|
79
|
+
chart_hours
|
70
80
|
chart_extensions
|
81
|
+
chart_bytes
|
71
82
|
chart_awesomeness
|
72
83
|
output
|
73
84
|
end
|
74
85
|
|
75
86
|
def chart_authors
|
87
|
+
generating_chart 'Repository Authors'
|
76
88
|
authors = {}
|
77
89
|
@commits.each do |c|
|
90
|
+
puts "\treading commit #{c.id[0, 7]}" if $vv
|
78
91
|
if authors[c.author.to_s]
|
79
92
|
authors[c.author.to_s] += 1
|
80
93
|
else
|
81
94
|
authors[c.author.to_s] = 1
|
95
|
+
puts "\t\tauthor: #{c.author.to_s}" if $v or $vv
|
82
96
|
end
|
83
97
|
end
|
84
98
|
PieChart.new(@size, 'Repository Authors', @threed) do |pc|
|
@@ -89,25 +103,60 @@ EOF
|
|
89
103
|
end
|
90
104
|
end
|
91
105
|
|
92
|
-
def chart_commits
|
106
|
+
def chart_commits(type)
|
107
|
+
generating_chart 'Commit Frequency'
|
93
108
|
weeks = Array.new 53, 0
|
94
109
|
@commits.each do |c|
|
110
|
+
puts "\treading commit #{c.id[0, 7]}" if $vv
|
95
111
|
time = Time.parse c.committed_date.to_s
|
96
112
|
week = time.strftime '%U'
|
97
113
|
weeks[week.to_i] ||= 0
|
98
114
|
weeks[week.to_i] += 1
|
99
115
|
end
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
116
|
+
case type
|
117
|
+
when :bar:
|
118
|
+
BarChart.new(@size, 'Commit Frequency', :vertical, @threed) do |bc|
|
119
|
+
bc.data 'Commits', weeks
|
120
|
+
bc.axis :y, { :range => [0, weeks.max] }
|
121
|
+
@html += "<img src='#{bc.to_url}' alt='Commit Frequency' /><br/>"
|
122
|
+
end
|
123
|
+
when :line:
|
124
|
+
weeks.pop while weeks.last.zero?
|
125
|
+
LineChart.new @size, 'Commit Frequency' do |lc|
|
126
|
+
lc.data 'Commits', weeks
|
127
|
+
lc.axis :y, { :range => [0, weeks.max] }
|
128
|
+
@html += "<img src='#{lc.to_url}' alt='Commit Frequency' /><br/>"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def chart_hours
|
134
|
+
generating_chart 'Commit Hours'
|
135
|
+
hours = Hash.new
|
136
|
+
@commits.each do |c|
|
137
|
+
puts "\treading commit #{c.id[0, 7]}" if $vv
|
138
|
+
date = Time.parse c.committed_date.to_s
|
139
|
+
hour = date.strftime '%H'
|
140
|
+
hours[hour.to_i] ||= 0
|
141
|
+
hours[hour.to_i] += 1
|
142
|
+
end
|
143
|
+
PieChart.new(@size, 'Commit Hours', @threed) do |pc|
|
144
|
+
hours.each do |hr, num|
|
145
|
+
pc.data hr.to_s + ':00 - ' + hr.to_s + ':59', num
|
146
|
+
end
|
147
|
+
@html += "<img src='#{pc.to_url}' alt='Commit Hours' /><br/>"
|
104
148
|
end
|
105
149
|
end
|
106
150
|
|
107
151
|
def chart_extensions
|
152
|
+
generating_chart 'Popular Extensions'
|
108
153
|
@extensions = {}
|
109
154
|
@tree = @commits.first.tree
|
110
155
|
extensions_add_tree @tree
|
156
|
+
if $v or $vv
|
157
|
+
print "\textensions: "
|
158
|
+
p @extensions
|
159
|
+
end
|
111
160
|
PieChart.new(@size, 'Popular Extensions', @threed) do |pc|
|
112
161
|
@extensions.each do |ext, num|
|
113
162
|
pc.data ext, num
|
@@ -134,15 +183,51 @@ EOF
|
|
134
183
|
@files += 1
|
135
184
|
end
|
136
185
|
|
186
|
+
def chart_bytes
|
187
|
+
generating_chart 'Total Filesize'
|
188
|
+
@bytes = Array.new
|
189
|
+
@commits.each do |c|
|
190
|
+
print "\treading commit #{c.id[0, 7]}" if $vv
|
191
|
+
@bytes.push 0
|
192
|
+
bytes_add_tree c.tree
|
193
|
+
puts " (#{@bytes.last} bytes)" if $vv
|
194
|
+
end
|
195
|
+
@bytes = @bytes.reverse
|
196
|
+
LineChart.new(@size, 'Total Filesize') do |lc|
|
197
|
+
lc.data 'Bytes', @bytes
|
198
|
+
lc.axis :y, { :range => [0, @bytes.max] }
|
199
|
+
@html += "<img src='#{lc.to_url}' alt='Total Filesize' /><br/>"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
def bytes_add_tree(tree)
|
203
|
+
tree.contents.each do |el|
|
204
|
+
if Blob === el
|
205
|
+
bytes_add_blob el
|
206
|
+
elsif Tree === el
|
207
|
+
bytes_add_tree el
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
def bytes_add_blob(blob)
|
212
|
+
bytes = blob.size
|
213
|
+
@bytes[-1] += bytes
|
214
|
+
end
|
215
|
+
|
137
216
|
def chart_awesomeness
|
217
|
+
generating_chart 'Repository Awesomeness'
|
138
218
|
@extensions['.rb'] ||= 0.1
|
139
219
|
awesomeness = @files / @extensions['.rb']
|
140
220
|
awesomeness = ( awesomeness * 100 ).round / 100.0
|
141
221
|
awesomeness = 0.1 if @extensions['.rb'] == 0.1
|
222
|
+
puts "\tawesomeness: #{awesomeness}%" if $v or $vv
|
142
223
|
url = "http://chart.apis.google.com/chart?cht=gom&chtt=Repository+Awesomeness&chs=#{@size}&chl=#{awesomeness}%25&chd=t:#{awesomeness}"
|
143
224
|
@html += "<img src='#{url}' alt='Repository Awesomeness' /><br/><br/>"
|
144
225
|
end
|
145
226
|
|
227
|
+
def generating_chart(chart)
|
228
|
+
puts "Generating chart '#{chart}' . . ."
|
229
|
+
end
|
230
|
+
|
146
231
|
def output
|
147
232
|
@html += <<EOF
|
148
233
|
</body>
|
@@ -153,15 +238,24 @@ EOF
|
|
153
238
|
t.flush
|
154
239
|
f = t.path + '.html'
|
155
240
|
File.move t.path, f
|
241
|
+
program = ''
|
156
242
|
case Platform::OS
|
157
243
|
when :unix:
|
158
244
|
if Platform::IMPL == :macosx
|
245
|
+
print "determined that platform = osx" if $v or $vv
|
246
|
+
program = 'open'
|
159
247
|
`open #{f}`
|
160
248
|
else
|
249
|
+
print "determined that platform = unix" if $v or $vv
|
250
|
+
program = 'xdg-open'
|
161
251
|
`xdg-open #{f}`
|
162
252
|
end
|
163
253
|
when :win32:
|
254
|
+
print "determined that platform = win32" if $v or $vv
|
255
|
+
program = 'start'
|
164
256
|
`start #{f}`
|
165
257
|
end
|
258
|
+
puts ". . . using `#{program}` to open the HTML page" if $v or $vv
|
259
|
+
puts "final file path: " + f if $v or $vv
|
166
260
|
end
|
167
261
|
end
|
data/lib/platform.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
#
|
2
|
+
# platform.rb: naive platform detection for Ruby
|
3
|
+
# author: Matt Mower <self@mattmower.com>
|
4
|
+
#
|
5
|
+
|
6
|
+
# == Platform
|
7
|
+
#
|
8
|
+
# Platform is a simple module which parses the Ruby constant
|
9
|
+
# RUBY_PLATFORM and works out the OS, it's implementation,
|
10
|
+
# and the architecture it's running on.
|
11
|
+
#
|
12
|
+
# The motivation for writing this was coming across a case where
|
13
|
+
#
|
14
|
+
# +if RUBY_PLATFORM =~ /win/+
|
15
|
+
#
|
16
|
+
# didn't behave as expected (i.e. on powerpc-darwin-8.1.0)
|
17
|
+
#
|
18
|
+
# It is hoped that providing a library for parsing the platform
|
19
|
+
# means that we can cover all the cases and have something which
|
20
|
+
# works reliably 99% of the time.
|
21
|
+
#
|
22
|
+
# Please report any anomalies or new combinations to the author(s).
|
23
|
+
#
|
24
|
+
# == Use
|
25
|
+
#
|
26
|
+
# require "platform"
|
27
|
+
#
|
28
|
+
# defines
|
29
|
+
#
|
30
|
+
# Platform::OS (:unix,:win32,:vms,:os2)
|
31
|
+
# Platform::IMPL (:macosx,:linux,:mswin)
|
32
|
+
# Platform::ARCH (:powerpc,:x86,:alpha)
|
33
|
+
#
|
34
|
+
# if an unknown configuration is encountered any (or all) of
|
35
|
+
# these constant may have the value :unknown.
|
36
|
+
#
|
37
|
+
# To display the combination for your setup run
|
38
|
+
#
|
39
|
+
# ruby platform.rb
|
40
|
+
#
|
41
|
+
module Platform
|
42
|
+
|
43
|
+
if RUBY_PLATFORM =~ /darwin/i
|
44
|
+
OS = :unix
|
45
|
+
IMPL = :macosx
|
46
|
+
elsif RUBY_PLATFORM =~ /linux/i
|
47
|
+
OS = :unix
|
48
|
+
IMPL = :linux
|
49
|
+
elsif RUBY_PLATFORM =~ /freebsd/i
|
50
|
+
OS = :unix
|
51
|
+
IMPL = :freebsd
|
52
|
+
elsif RUBY_PLATFORM =~ /netbsd/i
|
53
|
+
OS = :unix
|
54
|
+
IMPL = :netbsd
|
55
|
+
elsif RUBY_PLATFORM =~ /mswin/i
|
56
|
+
OS = :win32
|
57
|
+
IMPL = :mswin
|
58
|
+
elsif RUBY_PLATFORM =~ /cygwin/i
|
59
|
+
OS = :unix
|
60
|
+
IMPL = :cygwin
|
61
|
+
elsif RUBY_PLATFORM =~ /mingw/i
|
62
|
+
OS = :win32
|
63
|
+
IMPL = :mingw
|
64
|
+
elsif RUBY_PLATFORM =~ /bccwin/i
|
65
|
+
OS = :win32
|
66
|
+
IMPL = :bccwin
|
67
|
+
elsif RUBY_PLATFORM =~ /wince/i
|
68
|
+
OS = :win32
|
69
|
+
IMPL = :wince
|
70
|
+
elsif RUBY_PLATFORM =~ /vms/i
|
71
|
+
OS = :vms
|
72
|
+
IMPL = :vms
|
73
|
+
elsif RUBY_PLATFORM =~ /os2/i
|
74
|
+
OS = :os2
|
75
|
+
IMPL = :os2 # maybe there is some better choice here?
|
76
|
+
else
|
77
|
+
OS = :unknown
|
78
|
+
IMPL = :unknown
|
79
|
+
end
|
80
|
+
|
81
|
+
# whither AIX, SOLARIS, and the other unixen?
|
82
|
+
|
83
|
+
if RUBY_PLATFORM =~ /(i\d86)/i
|
84
|
+
ARCH = :x86
|
85
|
+
elsif RUBY_PLATFORM =~ /ia64/i
|
86
|
+
ARCH = :ia64
|
87
|
+
elsif RUBY_PLATFORM =~ /powerpc/i
|
88
|
+
ARCH = :powerpc
|
89
|
+
elsif RUBY_PLATFORM =~ /alpha/i
|
90
|
+
ARCH = :alpha
|
91
|
+
else
|
92
|
+
ARCH = :unknown
|
93
|
+
end
|
94
|
+
|
95
|
+
# What about AMD, Turion, Motorola, etc..?
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
if __FILE__ == $0
|
100
|
+
puts "Platform OS=#{Platform::OS}, IMPL=#{Platform::IMPL}, ARCH=#{Platform::ARCH}"
|
101
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hans-gitchart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "1.
|
4
|
+
version: "1.1"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hans Engel
|
@@ -46,7 +46,7 @@ files:
|
|
46
46
|
- lib/platform.rb
|
47
47
|
- bin/git-chart
|
48
48
|
has_rdoc: false
|
49
|
-
homepage: http://
|
49
|
+
homepage: http://gitchart.rubyforge.org
|
50
50
|
post_install_message:
|
51
51
|
rdoc_options: []
|
52
52
|
|