gitstats-ruby 1.0.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/.gitignore +3 -0
- data/LICENSE +674 -0
- data/README.markdown +53 -0
- data/bin/gitstats +176 -0
- data/gitstats-ruby.gemspec +22 -0
- data/lib/gitstats.rb +18 -0
- data/lib/gitstats/author.rb +41 -0
- data/lib/gitstats/git.rb +158 -0
- data/lib/gitstats/renderer.rb +30 -0
- data/lib/gitstats/renderer/gnuplot.rb +150 -0
- data/lib/gitstats/renderer/haml.rb +70 -0
- data/lib/gitstats/renderer/sass.rb +33 -0
- data/lib/gitstats/statgen.rb +116 -0
- data/lib/gitstats/stats.rb +12 -0
- data/lib/gitstats/stats/commit.rb +48 -0
- data/lib/gitstats/stats/commit/author.rb +17 -0
- data/lib/gitstats/stats/commit/time.rb +92 -0
- data/lib/gitstats/stats/file.rb +15 -0
- data/lib/gitstats/stats/file/filetype.rb +14 -0
- data/lib/gitstats/yearmonth.rb +39 -0
- data/template/activity.haml +3 -0
- data/template/asc.gif +0 -0
- data/template/authors.haml +2 -0
- data/template/bg.gif +0 -0
- data/template/commits_per_hour.plot +14 -0
- data/template/commits_per_month.plot +15 -0
- data/template/commits_per_wday.plot +15 -0
- data/template/commits_per_year.plot +11 -0
- data/template/commits_per_yearmonth.plot +11 -0
- data/template/desc.gif +0 -0
- data/template/filechanges_by_yearmonth.plot +17 -0
- data/template/files.haml +2 -0
- data/template/files_by_yearmonth.plot +11 -0
- data/template/helpers/block.rb +26 -0
- data/template/helpers/config.rb +12 -0
- data/template/helpers/names.rb +76 -0
- data/template/helpers/utils.rb +16 -0
- data/template/index.haml +2 -0
- data/template/jquery.js +4 -0
- data/template/jquery.tablesorter.js +4 -0
- data/template/lastweeks.plot +14 -0
- data/template/layouts/default.haml +43 -0
- data/template/linechanges_by_yearmonth.plot +17 -0
- data/template/lines.haml +2 -0
- data/template/lines_by_yearmonth.plot +11 -0
- data/template/partials/authors.haml +30 -0
- data/template/partials/blockheader.haml +2 -0
- data/template/partials/blocktoc.haml +7 -0
- data/template/partials/commits_per_month.haml +27 -0
- data/template/partials/commits_per_year.haml +27 -0
- data/template/partials/commits_per_yearmonth.haml +27 -0
- data/template/partials/day_of_week.haml +28 -0
- data/template/partials/filechanges_by_yearmonth.haml +3 -0
- data/template/partials/files_by_yearmonth.haml +3 -0
- data/template/partials/filetypes.haml +23 -0
- data/template/partials/general.haml +34 -0
- data/template/partials/hour_of_day.haml +28 -0
- data/template/partials/hour_of_week.haml +24 -0
- data/template/partials/lastweeks.haml +24 -0
- data/template/partials/linechanges_by_yearmonth.haml +3 -0
- data/template/partials/lines_by_yearmonth.haml +3 -0
- data/template/partials/repos.haml +13 -0
- data/template/partials/top_authors_of_year.haml +30 -0
- data/template/partials/top_authors_of_yearmonth.haml +30 -0
- data/template/style.scss +132 -0
- metadata +187 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
class AuthorsCommitStats < CommitStats
|
2
|
+
include StatsHash
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
@hash = Hash.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def update(commit)
|
10
|
+
super(commit)
|
11
|
+
|
12
|
+
author = commit[:author]
|
13
|
+
@hash[author] ||= CommitStats.new
|
14
|
+
@hash[author].update(commit)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
class YearCommitStats
|
2
|
+
include StatsHash
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@hash = Hash.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def update(commit)
|
9
|
+
year = commit[:time].year
|
10
|
+
@hash[year] ||= AuthorsCommitStats.new
|
11
|
+
@hash[year].update(commit)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class MonthCommitStats
|
16
|
+
include StatsHash
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@hash = Hash.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def update(commit)
|
23
|
+
month = commit[:time].month
|
24
|
+
@hash[month] ||= AuthorsCommitStats.new
|
25
|
+
@hash[month].update(commit)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class YearMonthCommitStats
|
30
|
+
include StatsHash
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
@hash = Hash.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def update(commit)
|
37
|
+
yearmonth = YearMonth.new(commit[:time])
|
38
|
+
@hash[yearmonth] ||= AuthorsCommitStats.new
|
39
|
+
@hash[yearmonth].update(commit)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class HourCommitStats < CommitStats
|
44
|
+
include StatsHash
|
45
|
+
|
46
|
+
def initialize
|
47
|
+
super
|
48
|
+
@hash = Hash.new
|
49
|
+
end
|
50
|
+
|
51
|
+
def update(commit)
|
52
|
+
super(commit)
|
53
|
+
|
54
|
+
hour = commit[:time].hour
|
55
|
+
@hash[hour] ||= CommitStats.new
|
56
|
+
@hash[hour].update(commit)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class DayOfWeekCommitStats
|
61
|
+
include StatsHash
|
62
|
+
|
63
|
+
def initialize
|
64
|
+
@hash = Hash.new
|
65
|
+
end
|
66
|
+
|
67
|
+
def update(commit)
|
68
|
+
day = commit[:time].wday
|
69
|
+
@hash[day] ||= HourCommitStats.new
|
70
|
+
@hash[day].update(commit)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class LastWeeksCommitStats
|
75
|
+
include StatsHash
|
76
|
+
|
77
|
+
def initialize
|
78
|
+
@hash = Hash.new
|
79
|
+
@base = Time.now
|
80
|
+
end
|
81
|
+
|
82
|
+
def update(commit)
|
83
|
+
return if commit[:time] > @base
|
84
|
+
|
85
|
+
diff = ((@base - commit[:time]) / 604800).to_i
|
86
|
+
return if diff >= 52
|
87
|
+
|
88
|
+
@hash[diff] ||= CommitStats.new
|
89
|
+
@hash[diff].update(commit)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class YearMonth
|
2
|
+
include Comparable
|
3
|
+
|
4
|
+
attr_reader :year
|
5
|
+
attr_reader :month
|
6
|
+
|
7
|
+
def initialize(a, b = nil)
|
8
|
+
if a.is_a? Time
|
9
|
+
@year = a.year
|
10
|
+
@month = a.month
|
11
|
+
elsif b.nil?
|
12
|
+
@year = (a / 100).to_i
|
13
|
+
@month = a % 100
|
14
|
+
else
|
15
|
+
@year = a.to_i
|
16
|
+
@month = b.to_i
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def <=>(b)
|
21
|
+
to_i <=> b.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_i
|
25
|
+
@year * 12 + @month - 1
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
'%04d-%02d' % [@year, @month]
|
30
|
+
end
|
31
|
+
|
32
|
+
def eql?(b)
|
33
|
+
to_i == b.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
def hash
|
37
|
+
to_i
|
38
|
+
end
|
39
|
+
end
|
data/template/asc.gif
ADDED
Binary file
|
data/template/bg.gif
ADDED
Binary file
|
@@ -0,0 +1,14 @@
|
|
1
|
+
defplot do |plotter|
|
2
|
+
plotter.plot.xrange '[-0.5:23.5]'
|
3
|
+
plotter.plot.xtics '1'
|
4
|
+
plotter.plot.ylabel 'Commits'
|
5
|
+
|
6
|
+
plotter.add_boxes(:setrange => false, :limitlabels => false) do |x, l, y|
|
7
|
+
for hour in 0..23
|
8
|
+
s = stats.hour_stats[hour]
|
9
|
+
x << hour
|
10
|
+
l << hour
|
11
|
+
y << (s.nil? ? 0 : s.commits)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
defplot do |plotter|
|
2
|
+
plotter.plot.xrange '[0.5:12.5]'
|
3
|
+
plotter.plot.xtics '1'
|
4
|
+
plotter.plot.ylabel 'Commits'
|
5
|
+
plotter.plot.yrange '[0:]'
|
6
|
+
|
7
|
+
plotter.add_boxes(:setrange => false, :limitlabels => false) do |x, l, y|
|
8
|
+
for month in 1..12
|
9
|
+
s = stats.month_stats[month]
|
10
|
+
x << month
|
11
|
+
l << monthname(month)
|
12
|
+
y << (s.nil? ? 0 : s.commits)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
defplot do |plotter|
|
2
|
+
plotter.plot.xrange '[0.5:7.5]'
|
3
|
+
plotter.plot.xtics '1'
|
4
|
+
plotter.plot.ylabel 'Commits'
|
5
|
+
|
6
|
+
plotter.add_boxes(:setrange => false, :limitlabels => false) do |x, l, y|
|
7
|
+
for i in 0..6
|
8
|
+
s = stats.wday_stats[i]
|
9
|
+
day = (i + 6) % 7
|
10
|
+
x << day + 1
|
11
|
+
l << weekday(day)
|
12
|
+
y << (s.nil? ? 0 : s.commits)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/template/desc.gif
ADDED
Binary file
|
@@ -0,0 +1,17 @@
|
|
1
|
+
defplot do |plotter|
|
2
|
+
plotter.add_steps do |x, l, y|
|
3
|
+
stats.yearmonth_stats.each_sorted do |yearmonth, stats|
|
4
|
+
x << yearmonth.to_i
|
5
|
+
l << yearmonth.to_s
|
6
|
+
y << stats.files_added
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
plotter.add_steps do |x, l, y|
|
11
|
+
stats.yearmonth_stats.each_sorted do |yearmonth, stats|
|
12
|
+
x << yearmonth.to_i
|
13
|
+
l << yearmonth.to_s
|
14
|
+
y << stats.files_deleted
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/template/files.haml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module BlockHelper
|
2
|
+
def blocktoc(*args)
|
3
|
+
partial :blocktoc, { :blocks => args }
|
4
|
+
end
|
5
|
+
|
6
|
+
def block(name)
|
7
|
+
haml_concat(partial(:blockheader, { :name => name }))
|
8
|
+
haml_concat("<div id=\"block-#{name.to_s}\" class=\"blockcontainer\">")
|
9
|
+
yield
|
10
|
+
haml_concat('</div>')
|
11
|
+
end
|
12
|
+
|
13
|
+
def blocks(*args)
|
14
|
+
ret = blocktoc(*args)
|
15
|
+
args.each do |block|
|
16
|
+
if block_given?
|
17
|
+
ret += yield(partial(block))
|
18
|
+
else
|
19
|
+
ret += partial(block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
ret
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
self.extend BlockHelper
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module NamesHelper
|
2
|
+
def label(name)
|
3
|
+
@names ||= {
|
4
|
+
:repos => 'Repositories',
|
5
|
+
:general => 'Stats',
|
6
|
+
:hour_of_day => 'Hour of day',
|
7
|
+
:day_of_week => 'Day of week',
|
8
|
+
:hour_of_week => 'Hour of week',
|
9
|
+
:commits_per_month => 'Commits per month',
|
10
|
+
:commits_per_year => 'Commits per year',
|
11
|
+
:commits_per_yearmonth => 'Commits per year and month',
|
12
|
+
:authors => "Top #{author_count} authors",
|
13
|
+
:top_authors_of_year => "Top #{top_author_count} authors of year",
|
14
|
+
:top_authors_of_yearmonth => "Top #{top_author_count} authors of year and month",
|
15
|
+
:files_by_yearmonth => 'Files by year and month',
|
16
|
+
:filechanges_by_yearmonth => 'Filechanges by year and month',
|
17
|
+
:lines_by_yearmonth => 'Lines by year and month',
|
18
|
+
:linechanges_by_yearmonth => 'Linechanges by year and month',
|
19
|
+
:filetypes => 'Filetypes',
|
20
|
+
:lastweeks => 'Last years weeks',
|
21
|
+
}
|
22
|
+
|
23
|
+
@names[name].nil? ? name.to_s : @names[name]
|
24
|
+
end
|
25
|
+
|
26
|
+
def weekday(wday)
|
27
|
+
case wday
|
28
|
+
when 0
|
29
|
+
'Mon'
|
30
|
+
when 1
|
31
|
+
'Tue'
|
32
|
+
when 2
|
33
|
+
'Wed'
|
34
|
+
when 3
|
35
|
+
'Thu'
|
36
|
+
when 4
|
37
|
+
'Fri'
|
38
|
+
when 5
|
39
|
+
'Sat'
|
40
|
+
when 6
|
41
|
+
'Sun'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def monthname(month)
|
46
|
+
case month
|
47
|
+
when 1
|
48
|
+
'Jan'
|
49
|
+
when 2
|
50
|
+
'Feb'
|
51
|
+
when 3
|
52
|
+
'Mar'
|
53
|
+
when 4
|
54
|
+
'Apr'
|
55
|
+
when 5
|
56
|
+
'May'
|
57
|
+
when 6
|
58
|
+
'Jun'
|
59
|
+
when 7
|
60
|
+
'Jul'
|
61
|
+
when 8
|
62
|
+
'Aug'
|
63
|
+
when 9
|
64
|
+
'Sep'
|
65
|
+
when 10
|
66
|
+
'Oct'
|
67
|
+
when 11
|
68
|
+
'Nov'
|
69
|
+
when 12
|
70
|
+
'Dec'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
self.extend NamesHelper
|
76
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module UtilsHelper
|
2
|
+
def filesize(i)
|
3
|
+
case
|
4
|
+
when i > 1000000000
|
5
|
+
'%dG' % (i / 1000000000).to_i
|
6
|
+
when i > 1000000
|
7
|
+
'%dM' % (i / 1000000).to_i
|
8
|
+
when i > 1000
|
9
|
+
'%dk' % (i / 1000).to_i
|
10
|
+
else
|
11
|
+
i.to_s
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
self.extend UtilsHelper
|