nova_git_stats 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/git_stats +6 -0
- data/config/locales/bg.yml +63 -0
- data/config/locales/bg_default.yml +70 -0
- data/config/locales/de.yml +63 -0
- data/config/locales/de_default.yml +224 -0
- data/config/locales/en.yml +63 -0
- data/config/locales/es.yml +63 -0
- data/config/locales/es_deafult.yml +70 -0
- data/config/locales/pl.yml +63 -0
- data/config/locales/pl_default.yml +224 -0
- data/config/locales/tr.yml +63 -0
- data/config/locales/tr_default.yml +70 -0
- data/config/locales/zh_cn.yml +65 -0
- data/config/locales/zh_cn_default.yml +70 -0
- data/config/locales/zh_tw.yml +63 -0
- data/config/locales/zh_tw_default.yml +76 -0
- data/lib/git_stats/base.rb +28 -0
- data/lib/git_stats/cli.rb +35 -0
- data/lib/git_stats/command_parser.rb +30 -0
- data/lib/git_stats/command_runner.rb +13 -0
- data/lib/git_stats/core_extensions/enumerable.rb +8 -0
- data/lib/git_stats/core_extensions/hash.rb +24 -0
- data/lib/git_stats/core_extensions/symbol.rb +5 -0
- data/lib/git_stats/generator.rb +38 -0
- data/lib/git_stats/git_data/activity.rb +76 -0
- data/lib/git_stats/git_data/author.rb +77 -0
- data/lib/git_stats/git_data/blob.rb +41 -0
- data/lib/git_stats/git_data/comment_stat.rb +38 -0
- data/lib/git_stats/git_data/commit.rb +76 -0
- data/lib/git_stats/git_data/repo.rb +172 -0
- data/lib/git_stats/git_data/short_stat.rb +29 -0
- data/lib/git_stats/git_data/tree.rb +21 -0
- data/lib/git_stats/hash_initializable.rb +9 -0
- data/lib/git_stats/i18n.rb +2 -0
- data/lib/git_stats/inspector.rb +52 -0
- data/lib/git_stats/stats_view/charts/activity_charts.rb +69 -0
- data/lib/git_stats/stats_view/charts/authors_charts.rb +49 -0
- data/lib/git_stats/stats_view/charts/chart.rb +126 -0
- data/lib/git_stats/stats_view/charts/charts.rb +36 -0
- data/lib/git_stats/stats_view/charts/repo_charts.rb +61 -0
- data/lib/git_stats/stats_view/template.rb +21 -0
- data/lib/git_stats/stats_view/view.rb +89 -0
- data/lib/git_stats/stats_view/view_data.rb +28 -0
- data/lib/git_stats/version.rb +7 -0
- data/lib/git_stats.rb +14 -0
- data/templates/activity/_activity.haml +102 -0
- data/templates/activity/by_date.haml +1 -0
- data/templates/activity/day_of_week.haml +1 -0
- data/templates/activity/hour_of_day.haml +1 -0
- data/templates/activity/hour_of_week.haml +1 -0
- data/templates/activity/month_of_year.haml +1 -0
- data/templates/activity/year.haml +1 -0
- data/templates/activity/year_month.haml +1 -0
- data/templates/assets/bootstrap/css/bootstrap-3.3.7.min.css +6 -0
- data/templates/assets/bootstrap/css/bootstrap-theme-3.3.7.min.css +6 -0
- data/templates/assets/bootstrap/css/bootstrap-theme.min.css.map +1 -0
- data/templates/assets/bootstrap/css/bootstrap.min.css.map +1 -0
- data/templates/assets/bootstrap/js/bootstrap-3.3.7.min.js +7 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap-grid.css +3872 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap-grid.css.map +1 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap-grid.min.css +7 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap-grid.min.css.map +1 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap-reboot.css +325 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap-reboot.css.map +1 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap-reboot.min.css +8 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap-reboot.min.css.map +1 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap.css +10298 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap.css.map +1 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap.min.css +7 -0
- data/templates/assets/bootstrap-4.6.0-dist/css/bootstrap.min.css.map +1 -0
- data/templates/assets/bootstrap-4.6.0-dist/js/bootstrap.bundle.js +7045 -0
- data/templates/assets/bootstrap-4.6.0-dist/js/bootstrap.bundle.js.map +1 -0
- data/templates/assets/bootstrap-4.6.0-dist/js/bootstrap.bundle.min.js +7 -0
- data/templates/assets/bootstrap-4.6.0-dist/js/bootstrap.bundle.min.js.map +1 -0
- data/templates/assets/bootstrap-4.6.0-dist/js/bootstrap.js +4432 -0
- data/templates/assets/bootstrap-4.6.0-dist/js/bootstrap.js.map +1 -0
- data/templates/assets/bootstrap-4.6.0-dist/js/bootstrap.min.js +7 -0
- data/templates/assets/bootstrap-4.6.0-dist/js/bootstrap.min.js.map +1 -0
- data/templates/assets/export-data.js +17 -0
- data/templates/assets/exporting.js +27 -0
- data/templates/assets/highstock.js +525 -0
- data/templates/assets/jquery-3.6.0.min.js +2 -0
- data/templates/assets/menu.css +28 -0
- data/templates/author_details/_author_details.haml +31 -0
- data/templates/author_details/changed_lines_by_date.haml +1 -0
- data/templates/author_details/commits_by_date.haml +1 -0
- data/templates/author_details/deletions_by_date.haml +1 -0
- data/templates/author_details/insertions_by_date.haml +1 -0
- data/templates/authors/_authors.haml +72 -0
- data/templates/authors/best_authors.haml +1 -0
- data/templates/authors/changed_lines_by_author_by_date.haml +1 -0
- data/templates/authors/commits_sum_by_author_by_date.haml +1 -0
- data/templates/authors/deletions_by_author_by_date.haml +1 -0
- data/templates/authors/insertions_by_author_by_date.haml +1 -0
- data/templates/comments/_comments.haml +11 -0
- data/templates/comments/by_date.haml +1 -0
- data/templates/files/_files.haml +16 -0
- data/templates/files/by_date.haml +1 -0
- data/templates/files/by_extension.haml +1 -0
- data/templates/general.haml +31 -0
- data/templates/layout.haml +32 -0
- data/templates/lines/_lines.haml +16 -0
- data/templates/lines/by_date.haml +1 -0
- data/templates/lines/by_extension.haml +1 -0
- data/templates/static/index.html +5 -0
- metadata +262 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
module GitStats
|
2
|
+
module Inspector
|
3
|
+
def to_s
|
4
|
+
vars = defined_ivars.map do |sym|
|
5
|
+
value = if ivars_to_be_filtered.include?(sym)
|
6
|
+
'...'
|
7
|
+
else
|
8
|
+
var = instance_variable_get(sym)
|
9
|
+
var.is_a?(String) ? %("#{var}") : var.inspect
|
10
|
+
end
|
11
|
+
[sym, value].join('=')
|
12
|
+
end
|
13
|
+
vars = vars.join(', ').presence
|
14
|
+
"#<#{[self.class, vars].compact.join(' ')}>"
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def pretty_print(pp)
|
22
|
+
pp.object_address_group(self) do
|
23
|
+
pp.seplist(defined_ivars, proc { pp.text(',') }) do |attr_name|
|
24
|
+
pp.breakable(' ')
|
25
|
+
pp.group(1) do
|
26
|
+
pp.text(attr_name.to_s)
|
27
|
+
pp.text('=')
|
28
|
+
if ivars_to_be_filtered.include?(attr_name)
|
29
|
+
pp.text('...')
|
30
|
+
else
|
31
|
+
pp.pp(instance_variable_get(attr_name))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def ivars_to_be_displayed
|
41
|
+
instance_variables
|
42
|
+
end
|
43
|
+
|
44
|
+
def ivars_to_be_filtered
|
45
|
+
[]
|
46
|
+
end
|
47
|
+
|
48
|
+
def defined_ivars
|
49
|
+
(ivars_to_be_displayed | ivars_to_be_filtered).select { |sym| instance_variable_defined?(sym) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module GitStats
|
2
|
+
module StatsView
|
3
|
+
module Charts
|
4
|
+
class ActivityCharts
|
5
|
+
def initialize(repo)
|
6
|
+
@repo = repo
|
7
|
+
@activity = repo.activity
|
8
|
+
end
|
9
|
+
|
10
|
+
def activity_by_date(author)
|
11
|
+
Chart.new do |f|
|
12
|
+
f.date_column_chart(
|
13
|
+
data: author.activity.by_date,
|
14
|
+
title: :commits_by_date.t,
|
15
|
+
y_text: :commits.t
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def activity_by_hour(author)
|
21
|
+
Chart.new do |f|
|
22
|
+
f.simple_column_chart(
|
23
|
+
title: :commits_by_hour.t,
|
24
|
+
y_text: :commits.t,
|
25
|
+
x_text: :hour.t,
|
26
|
+
data_x: (0..23),
|
27
|
+
data_y: author.activity.by_hour_array
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def activity_by_wday(author)
|
33
|
+
Chart.new do |f|
|
34
|
+
f.simple_column_chart(
|
35
|
+
title: :commits_by_wday.t,
|
36
|
+
y_text: :commits.t,
|
37
|
+
x_text: :day.t,
|
38
|
+
data_x: I18n.t('date.abbr_day_names'),
|
39
|
+
data_y: author.activity.by_wday_array
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def activity_by_month(author)
|
45
|
+
Chart.new do |f|
|
46
|
+
f.simple_column_chart(
|
47
|
+
title: :commits_by_month.t,
|
48
|
+
y_text: :commits.t,
|
49
|
+
x_text: :month.t,
|
50
|
+
data_x: I18n.t('date.abbr_month_names')[1..-1],
|
51
|
+
data_y: author.activity.by_month_array
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def activity_by_year(author)
|
57
|
+
Chart.new do |f|
|
58
|
+
f.column_hash_chart(
|
59
|
+
title: :commits_by_year.t,
|
60
|
+
y_text: :commits.t,
|
61
|
+
x_text: :year.t,
|
62
|
+
data: author.activity.by_year
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module GitStats
|
2
|
+
module StatsView
|
3
|
+
module Charts
|
4
|
+
class AuthorsCharts
|
5
|
+
AUTHORS_ON_CHART_LIMIT = 5
|
6
|
+
|
7
|
+
def initialize(authors)
|
8
|
+
@authors = authors
|
9
|
+
end
|
10
|
+
|
11
|
+
[:commits_sum].each do |method|
|
12
|
+
define_method "#{method}_by_author_by_date" do |authors = nil|
|
13
|
+
Chart.new do |f|
|
14
|
+
authors ||= @authors.sort_by { |a| -a.send(method) }[0...AUTHORS_ON_CHART_LIMIT]
|
15
|
+
f.multi_date_chart(
|
16
|
+
data: authors.map { |a| {name: a.name, data: a.send("#{method}_by_date")} },
|
17
|
+
title: :lines_by_date.t,
|
18
|
+
y_text: :lines.t
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
[:insertions, :deletions, :changed_lines].each do |method|
|
25
|
+
define_method "total_#{method}_by_author_by_date" do |authors = nil|
|
26
|
+
Chart.new do |f|
|
27
|
+
authors ||= @authors.sort_by { |a| -a.send(method) }[0...AUTHORS_ON_CHART_LIMIT]
|
28
|
+
f.multi_date_chart(
|
29
|
+
data: authors.map { |a| {name: a.name, data: a.send("total_#{method}_by_date")} },
|
30
|
+
title: :lines_by_date.t,
|
31
|
+
y_text: :lines.t
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
define_method "#{method}_by_author_by_date" do |author|
|
37
|
+
Chart.new do |f|
|
38
|
+
f.date_column_chart(
|
39
|
+
data: author.send("#{method}_by_date"),
|
40
|
+
title: :lines_by_date.t,
|
41
|
+
y_text: :lines.t
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module GitStats
|
2
|
+
module StatsView
|
3
|
+
module Charts
|
4
|
+
class Chart
|
5
|
+
def method_missing(name, *args, &block)
|
6
|
+
@chart.send(name, *args, &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def respond_to_missing?(name, include_private = false)
|
10
|
+
@chart.respond_to?(name, include_private)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@chart = LazyHighCharts::HighChart.new('graph')
|
15
|
+
yield self if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
def simple_column_chart(params)
|
19
|
+
column_chart(params)
|
20
|
+
series(name: params[:title], data: params[:data_y])
|
21
|
+
end
|
22
|
+
|
23
|
+
def multiple_column_chart(params)
|
24
|
+
column_chart(params)
|
25
|
+
params[:data_y].each do |s|
|
26
|
+
series(name: s[:name], data: s[:data])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def column_hash_chart(params)
|
31
|
+
simple_column_chart(params.merge(
|
32
|
+
data_x: params[:data].keys,
|
33
|
+
data_y: params[:data].values
|
34
|
+
))
|
35
|
+
end
|
36
|
+
|
37
|
+
def date_chart(params)
|
38
|
+
common_options(params)
|
39
|
+
series(date_series({name: params[:title], data: params[:data]}))
|
40
|
+
end
|
41
|
+
|
42
|
+
def multi_date_chart(params)
|
43
|
+
common_options(params)
|
44
|
+
default_legend
|
45
|
+
params[:data].each do |s|
|
46
|
+
series(date_series(s))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def date_column_chart(params)
|
51
|
+
common_options(params)
|
52
|
+
series(date_series({name: params[:title], data: params[:data]}, aggregated: false).merge(
|
53
|
+
{
|
54
|
+
type: 'column',
|
55
|
+
dataGrouping: {units: [['day', [1]], ['week', [1]]], forced: true}
|
56
|
+
}
|
57
|
+
))
|
58
|
+
end
|
59
|
+
|
60
|
+
def default_legend
|
61
|
+
legend(
|
62
|
+
enabled: true,
|
63
|
+
layout: 'vertical',
|
64
|
+
backgroundColor: '#FFFFFF',
|
65
|
+
align: 'left',
|
66
|
+
verticalAlign: 'top',
|
67
|
+
x: 100,
|
68
|
+
y: 70,
|
69
|
+
floating: true,
|
70
|
+
shadow: true
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
def no_legend
|
75
|
+
legend(
|
76
|
+
enabled: false
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
def type(type)
|
81
|
+
@chart.chart!(type: type)
|
82
|
+
end
|
83
|
+
|
84
|
+
def x_categories(categories)
|
85
|
+
@chart.xAxis!(categories: categories)
|
86
|
+
end
|
87
|
+
|
88
|
+
def x_text(text)
|
89
|
+
@chart.xAxis!(title: {text: text})
|
90
|
+
end
|
91
|
+
|
92
|
+
def y_text(text)
|
93
|
+
@chart.yAxis!(title: {text: text})
|
94
|
+
end
|
95
|
+
|
96
|
+
def title(title)
|
97
|
+
@chart.title!(text: title)
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def common_options(params)
|
103
|
+
no_legend
|
104
|
+
title ''
|
105
|
+
y_text params[:y_text]
|
106
|
+
x_text params[:x_text]
|
107
|
+
end
|
108
|
+
|
109
|
+
def date_series(params, aggregated: true)
|
110
|
+
{
|
111
|
+
name: params[:name],
|
112
|
+
type: 'spline',
|
113
|
+
data: (params[:data]).to_h.fill_empty_days!(aggregated: aggregated)
|
114
|
+
.map { |date, value| [date.to_datetime.to_i * 1000, value] }.sort_by { |d| d[0] }
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
def column_chart(params)
|
119
|
+
common_options(params)
|
120
|
+
type 'column'
|
121
|
+
x_categories params[:data_x]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module GitStats
|
2
|
+
module StatsView
|
3
|
+
module Charts
|
4
|
+
class All
|
5
|
+
delegate :files_by_extension, :lines_by_extension, :files_by_date, :lines_by_date, :comments_by_date,
|
6
|
+
to: :repo_charts
|
7
|
+
|
8
|
+
delegate :commits_sum_by_author_by_date, :changed_lines_by_author_by_date,
|
9
|
+
:insertions_by_author_by_date, :deletions_by_author_by_date,
|
10
|
+
:total_changed_lines_by_author_by_date, :total_insertions_by_author_by_date, :total_deletions_by_author_by_date,
|
11
|
+
to: :authors_charts
|
12
|
+
|
13
|
+
delegate :activity_by_date, :activity_by_hour, :activity_by_wday, :activity_by_month,
|
14
|
+
:activity_by_year, to: :activity_charts
|
15
|
+
|
16
|
+
attr_reader :repo
|
17
|
+
|
18
|
+
def initialize(repo)
|
19
|
+
@repo = repo
|
20
|
+
end
|
21
|
+
|
22
|
+
def repo_charts
|
23
|
+
@repo_charts ||= Charts::RepoCharts.new(repo)
|
24
|
+
end
|
25
|
+
|
26
|
+
def authors_charts
|
27
|
+
@authors_charts ||= Charts::AuthorsCharts.new(repo.authors)
|
28
|
+
end
|
29
|
+
|
30
|
+
def activity_charts
|
31
|
+
@activity_charts ||= Charts::ActivityCharts.new(repo)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module GitStats
|
2
|
+
module StatsView
|
3
|
+
module Charts
|
4
|
+
class RepoCharts
|
5
|
+
def initialize(repo)
|
6
|
+
@repo = repo
|
7
|
+
end
|
8
|
+
|
9
|
+
def files_by_extension
|
10
|
+
Chart.new do |f|
|
11
|
+
f.column_hash_chart(
|
12
|
+
data: @repo.files_by_extension_count,
|
13
|
+
title: :files_by_extension.t,
|
14
|
+
y_text: :files.t
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def lines_by_extension
|
20
|
+
Chart.new do |f|
|
21
|
+
f.column_hash_chart(
|
22
|
+
data: @repo.lines_by_extension,
|
23
|
+
title: :lines_by_extension.t,
|
24
|
+
y_text: :lines.t
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def files_by_date
|
30
|
+
Chart.new do |f|
|
31
|
+
f.date_chart(
|
32
|
+
data: @repo.files_count_by_date,
|
33
|
+
title: :files_by_date.t,
|
34
|
+
y_text: :files.t
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def lines_by_date
|
40
|
+
Chart.new do |f|
|
41
|
+
f.date_chart(
|
42
|
+
data: @repo.lines_count_by_date,
|
43
|
+
title: :lines_by_date.t,
|
44
|
+
y_text: :lines.t
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def comments_by_date
|
50
|
+
Chart.new do |f|
|
51
|
+
f.date_chart(
|
52
|
+
data: @repo.comments_count_by_date,
|
53
|
+
title: :comments_by_date.t,
|
54
|
+
y_text: :comments.t
|
55
|
+
)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GitStats
|
2
|
+
module StatsView
|
3
|
+
class Template
|
4
|
+
def initialize(name, layout = nil)
|
5
|
+
@name = name
|
6
|
+
@layout = layout
|
7
|
+
@template = Tilt.new(GitStats.root.join("templates/#{@name}.haml"))
|
8
|
+
end
|
9
|
+
|
10
|
+
def render(data, params = {})
|
11
|
+
if @layout
|
12
|
+
@layout.render(data, active_page: params[:active_page] || @name, links: params[:links]) do
|
13
|
+
@template.render(data, params)
|
14
|
+
end
|
15
|
+
else
|
16
|
+
@template.render(data, params)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require_relative '../inspector'
|
2
|
+
|
3
|
+
module GitStats
|
4
|
+
module StatsView
|
5
|
+
class View
|
6
|
+
include GitStats::Inspector
|
7
|
+
|
8
|
+
def initialize(view_data, out_path)
|
9
|
+
@view_data = view_data
|
10
|
+
@out_path = File.expand_path(out_path)
|
11
|
+
@layout = Tilt.new(GitStats.root.join('templates/layout.haml'))
|
12
|
+
end
|
13
|
+
|
14
|
+
def render_all
|
15
|
+
prepare_static_content
|
16
|
+
prepare_assets
|
17
|
+
|
18
|
+
all_templates.reject { |t| t.include?('author_details') }.each do |template|
|
19
|
+
output = Template.new(template, @layout).render(@view_data, author: @view_data.repo, links: links)
|
20
|
+
write(output, "#{@out_path}/#{template}.html")
|
21
|
+
end
|
22
|
+
|
23
|
+
render_authors
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_authors
|
27
|
+
done = []
|
28
|
+
@view_data.repo.authors.sort_by { |a| -a.commits.size }.each do |author|
|
29
|
+
next if done.include? author.dirname
|
30
|
+
|
31
|
+
done << author.dirname
|
32
|
+
(all_templates('activity/') + all_templates('author_details')).each do |template|
|
33
|
+
output = Template.new(template, @layout).render(@view_data,
|
34
|
+
author: author,
|
35
|
+
links: links,
|
36
|
+
active_page: "/authors/#{author.dirname}/#{template}")
|
37
|
+
write(output, "#{@out_path}/authors/#{author.dirname}/#{template}.html")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def all_templates(root = '')
|
43
|
+
(Dir[GitStats.root.join("templates/#{root}**/[^_]*.haml")].map do |f|
|
44
|
+
path = Pathname.new(f)
|
45
|
+
path.relative_path_from(GitStats.root.join('templates')).sub_ext('').to_s
|
46
|
+
end - %w(layout))
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def write(output, write_file)
|
52
|
+
FileUtils.mkdir_p(File.dirname(write_file))
|
53
|
+
File.write(write_file, output)
|
54
|
+
end
|
55
|
+
|
56
|
+
def links
|
57
|
+
{
|
58
|
+
general: 'general.html',
|
59
|
+
activity: 'activity/by_date.html',
|
60
|
+
authors: 'authors/best_authors.html',
|
61
|
+
files: 'files/by_date.html',
|
62
|
+
lines: 'lines/by_date.html',
|
63
|
+
comments: 'comments/by_date.html'
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def prepare_static_content
|
68
|
+
create_out_dir
|
69
|
+
FileUtils.cp_r(Dir[GitStats.root.join('templates/static/*')], @out_path)
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_out_dir
|
73
|
+
FileUtils.mkdir_p(@out_path) unless Dir.exist?(@out_path)
|
74
|
+
end
|
75
|
+
|
76
|
+
def prepare_assets
|
77
|
+
FileUtils.cp_r(GitStats.root.join('templates/assets'), @out_path)
|
78
|
+
end
|
79
|
+
|
80
|
+
def ivars_to_be_displayed
|
81
|
+
[:@view_data, :@out_path]
|
82
|
+
end
|
83
|
+
|
84
|
+
def ivars_to_be_filtered
|
85
|
+
[:@layout]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module GitStats
|
2
|
+
module StatsView
|
3
|
+
class ViewData
|
4
|
+
include LazyHighCharts::LayoutHelper
|
5
|
+
attr_reader :repo
|
6
|
+
|
7
|
+
def initialize(repo)
|
8
|
+
@repo = repo
|
9
|
+
end
|
10
|
+
|
11
|
+
def charts
|
12
|
+
@charts ||= Charts::All.new(repo)
|
13
|
+
end
|
14
|
+
|
15
|
+
def render_partial(template_name, params = {})
|
16
|
+
Template.new(template_name).render(self, params)
|
17
|
+
end
|
18
|
+
|
19
|
+
def asset_path(asset, active_page)
|
20
|
+
Pathname.new("/assets/#{asset}").relative_path_from(Pathname.new("/#{active_page}").dirname)
|
21
|
+
end
|
22
|
+
|
23
|
+
def link_to(href, active_page)
|
24
|
+
Pathname.new("/#{href}").relative_path_from(Pathname.new("/#{active_page}").dirname)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/git_stats.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module GitStats
|
2
|
+
def self.root
|
3
|
+
Pathname.new(File.dirname(File.dirname(__FILE__)))
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'active_support/all'
|
8
|
+
require 'fileutils'
|
9
|
+
require 'tilt'
|
10
|
+
require 'pathname'
|
11
|
+
require 'lazy_high_charts'
|
12
|
+
require 'i18n'
|
13
|
+
|
14
|
+
require 'git_stats/base'
|
@@ -0,0 +1,102 @@
|
|
1
|
+
.tabbable.tabs-left
|
2
|
+
%ul.nav.nav-tabs
|
3
|
+
%li{class: page == :activity_by_date ? 'active' : '', role: 'presentation'}
|
4
|
+
%a{href: 'by_date.html'}= :activity_by_date.t
|
5
|
+
%li{class: page == :hour_of_day ? 'active' : '', role: 'presentation'}
|
6
|
+
%a{href: 'hour_of_day.html'}= :hour_of_day.t
|
7
|
+
%li{class: page == :day_of_week ? 'active' : '', role: 'presentation'}
|
8
|
+
%a{href: 'day_of_week.html'}= :day_of_week.t
|
9
|
+
%li{class: page == :hour_of_week ? 'active' : '', role: 'presentation'}
|
10
|
+
%a{href: 'hour_of_week.html'}= :hour_of_week.t
|
11
|
+
%li{class: page == :month_of_year ? 'active' : '', role: 'presentation'}
|
12
|
+
%a{href: 'month_of_year.html'}= :month_of_year.t
|
13
|
+
%li{class: page == :year ? 'active' : '', role: 'presentation'}
|
14
|
+
%a{href: 'year.html'}= :year.t
|
15
|
+
%li{class: page == :year_month ? 'active' : '', role: 'presentation'}
|
16
|
+
%a{href: 'year_month.html'}= :year_month.t
|
17
|
+
|
18
|
+
.tab-content
|
19
|
+
.tab-pane.active
|
20
|
+
.page-header.text-center
|
21
|
+
%h1= page.t
|
22
|
+
%h3 #{author.respond_to?(:name) ? author.name : ''} #{author.respond_to?(:email) ? "<#{author.email}>" : ''}
|
23
|
+
- case page
|
24
|
+
- when :activity_by_date
|
25
|
+
= high_stock('charts.activity_by_date', charts.activity_by_date(author))
|
26
|
+
|
27
|
+
- when :hour_of_day
|
28
|
+
%table{class: 'table table-bordered table-condensed'}
|
29
|
+
%tr
|
30
|
+
%th= :hour.t
|
31
|
+
- (0..23).each do |h|
|
32
|
+
%th= h
|
33
|
+
%tr
|
34
|
+
%th= :commits.t
|
35
|
+
- author.activity.by_hour_array.each do |commits|
|
36
|
+
%td= commits
|
37
|
+
%tr
|
38
|
+
%th= :percentage.t
|
39
|
+
- author.activity.by_hour_array.each do |commits|
|
40
|
+
%td= (commits * 100.0 / author.activity.by_hour_array.sum).round(1)
|
41
|
+
= high_chart('charts.activity_by_hour', charts.activity_by_hour(author))
|
42
|
+
|
43
|
+
- when :day_of_week
|
44
|
+
%table{class: 'table table-bordered table-condensed'}
|
45
|
+
%tr
|
46
|
+
%th= :day.t
|
47
|
+
- I18n.t('date.abbr_day_names').each do |d|
|
48
|
+
%th= d
|
49
|
+
%tr
|
50
|
+
%th= :commits.t
|
51
|
+
- author.activity.by_wday_array.each do |commits|
|
52
|
+
%td= commits
|
53
|
+
%tr
|
54
|
+
%th= :percentage.t
|
55
|
+
- author.activity.by_wday_array.each do |commits|
|
56
|
+
%td= (commits * 100.0 / author.activity.by_wday_array.sum).round(1)
|
57
|
+
= high_chart('charts.activity_by_wday', charts.activity_by_wday(author))
|
58
|
+
|
59
|
+
- when :hour_of_week
|
60
|
+
%table{class: 'table table-bordered table-condensed'}
|
61
|
+
%tr
|
62
|
+
%th
|
63
|
+
- (0..23).each do |h|
|
64
|
+
%th= h
|
65
|
+
- max = author.activity.by_wday_hour.values.map { |h| h.values.empty? ? 0 : h.values.max }.max
|
66
|
+
- (0..6).each do |day|
|
67
|
+
%tr
|
68
|
+
%th= I18n.t('date.abbr_day_names')[day]
|
69
|
+
- (0..23).each do |hour|
|
70
|
+
- color = max ? format('%02x', 255 - author.activity.by_wday_hour[day][hour] * 100 / max) : 'FF'
|
71
|
+
%td{style: "background-color: ##{color}#{color}#{color};"}= author.activity.by_wday_hour[day][hour]
|
72
|
+
|
73
|
+
- when :month_of_year
|
74
|
+
%table{class: 'table table-bordered table-condensed'}
|
75
|
+
%tr
|
76
|
+
%th= :month.t
|
77
|
+
- I18n.t('date.abbr_month_names')[1..-1].each do |m|
|
78
|
+
%th= m
|
79
|
+
%tr
|
80
|
+
%th= :commits.t
|
81
|
+
- author.activity.by_month_array.each do |commits|
|
82
|
+
%td= commits
|
83
|
+
%tr
|
84
|
+
%th= :percentage.t
|
85
|
+
- author.activity.by_month_array.each do |commits|
|
86
|
+
%td= (commits * 100.0 / author.activity.by_month_array.sum).round(1)
|
87
|
+
= high_chart('charts.activity_by_month', charts.activity_by_month(author))
|
88
|
+
|
89
|
+
- when :year
|
90
|
+
= high_chart('charts.activity_by_year', charts.activity_by_year(author))
|
91
|
+
|
92
|
+
- when :year_month
|
93
|
+
%table{class: 'table table-bordered table-condensed'}
|
94
|
+
%tr
|
95
|
+
%th
|
96
|
+
- I18n.t('date.abbr_month_names')[1..-1].each do |h|
|
97
|
+
%th= h
|
98
|
+
- author.activity.by_year_month.each do |year, months|
|
99
|
+
%tr
|
100
|
+
%th= year
|
101
|
+
- (1..12).each do |month|
|
102
|
+
%td= months[month]
|
@@ -0,0 +1 @@
|
|
1
|
+
= render_partial('activity/_activity', page: :activity_by_date, author: author)
|
@@ -0,0 +1 @@
|
|
1
|
+
= render_partial('activity/_activity', page: :day_of_week, author: author)
|
@@ -0,0 +1 @@
|
|
1
|
+
= render_partial('activity/_activity', page: :hour_of_day, author: author)
|
@@ -0,0 +1 @@
|
|
1
|
+
= render_partial('activity/_activity', page: :hour_of_week, author: author)
|
@@ -0,0 +1 @@
|
|
1
|
+
= render_partial('activity/_activity', page: :month_of_year, author: author)
|
@@ -0,0 +1 @@
|
|
1
|
+
= render_partial('activity/_activity', page: :year, author: author)
|
@@ -0,0 +1 @@
|
|
1
|
+
= render_partial('activity/_activity', page: :year_month, author: author)
|