commit-comment-tools 0.0.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/.yardopts +8 -0
- data/Gemfile +20 -0
- data/README.md +26 -0
- data/Rakefile +46 -0
- data/bin/git-stats +71 -0
- data/bin/report-analyzer +73 -0
- data/commit-comment-tools.gemspec +67 -0
- data/doc/text/gpl-3.0.txt +674 -0
- data/doc/text/news.md +5 -0
- data/doc/text/scenario.txt +168 -0
- data/lib/commit-comment-tools/entry.rb +45 -0
- data/lib/commit-comment-tools/generator.rb +4 -0
- data/lib/commit-comment-tools/generator/csv.rb +63 -0
- data/lib/commit-comment-tools/generator/graph.rb +25 -0
- data/lib/commit-comment-tools/report-normalizer.rb +58 -0
- data/lib/commit-comment-tools/report-parser.rb +98 -0
- data/lib/commit-comment-tools/repository-loader.rb +131 -0
- data/lib/commit-comment-tools/repository-stats.rb +113 -0
- data/lib/commit-comment-tools/version.rb +20 -0
- data/test/run-test.rb +32 -0
- data/test/test-entry.rb +78 -0
- data/test/test-report-normalizer.rb +87 -0
- data/test/test-report-parser.rb +111 -0
- metadata +230 -0
data/doc/text/news.md
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
# -*- org -*-
|
2
|
+
#+STARTUP: overview
|
3
|
+
#+STARTUP: hidestars
|
4
|
+
|
5
|
+
* 導入研修
|
6
|
+
|
7
|
+
研修でやることの説明をする。↓のリストを読んでやることの説明をする。全
|
8
|
+
体の流れを説明する。
|
9
|
+
|
10
|
+
- 「リーダブルコードの解説」を読む (10分)
|
11
|
+
http://www.clear-code.com/blog/2012/6/11.html
|
12
|
+
|
13
|
+
「リーダブルコードの解説」を読むことで須藤が考える「リーダブルコードを
|
14
|
+
書くために必要なこと」を知ってもらいます。
|
15
|
+
|
16
|
+
- 「リーダブルコードの解説」の解説 (5分)
|
17
|
+
|
18
|
+
「リーダブルコードの解説」を書いた時点と現在では、須藤の考え方も変わっ
|
19
|
+
ているため、考え方の変わった部分について説明します。
|
20
|
+
|
21
|
+
- 「Ruby コードの感想戦 【第 1 回】 WikiR」を読む (20分)
|
22
|
+
http://jp.rubyist.net/magazine/?0040-CodePostMortem
|
23
|
+
|
24
|
+
他の人がどんな読み方をするのか知っておくと、コードを読むときの視点が増
|
25
|
+
えるので、その一例として須藤の読み方を知ってもらいます。
|
26
|
+
|
27
|
+
- 「Ruby コードの感想戦 【第 1 回】 WikiR」の解説 (5分)
|
28
|
+
|
29
|
+
須藤がどういう読み方をしていたのか簡単に解説したあと、参加者のみなさん
|
30
|
+
に普段どのようにしてコードを読んでいるのか聞きます。
|
31
|
+
|
32
|
+
そのあと、講師の読み方を説明します。
|
33
|
+
|
34
|
+
- 実際にやってもらう (10分)
|
35
|
+
|
36
|
+
1人ずつ2,3分くらいで実際にコミットメールを読んでもらいます。
|
37
|
+
1人がやっている間、他の人はその人の周りに集ります。
|
38
|
+
|
39
|
+
- 感想を聞く (10分)
|
40
|
+
|
41
|
+
やってもらった感想を聞く。
|
42
|
+
|
43
|
+
- コメントの仕方 (5分)
|
44
|
+
|
45
|
+
どういう点に注意してコメントをするのか説明します。
|
46
|
+
|
47
|
+
- まとめ (5分)
|
48
|
+
|
49
|
+
** 「リーダブルコードの解説」を読む (10分)
|
50
|
+
|
51
|
+
「リーダブルコードの解説」を10分くらいで読んでください。
|
52
|
+
http://www.clear-code.com/blog/2012/6/11.html
|
53
|
+
|
54
|
+
「リーダブルコードの解説 ククログ」でぐぐると一番上に表示されます。
|
55
|
+
|
56
|
+
リーダブルコードの解説にはリーダブルなコードを継続的に書くために必要な
|
57
|
+
ことが書いてあります。また、リーダブルなコードを書くことを始めたばかり
|
58
|
+
の頃に困りそうなことも書いてあります。
|
59
|
+
|
60
|
+
|
61
|
+
(大きめの字で印刷して配ってもいいかも)
|
62
|
+
|
63
|
+
** 「リーダブルコードの解説」の解説 (5分)
|
64
|
+
|
65
|
+
「リーダブルコードの解説」には、まず自分がリーダブルなコードを書くんだ
|
66
|
+
というようなことが書かれていますが、普通の人はいきなりリーダブルないい
|
67
|
+
コードを書くことはできません。なぜなら、いいコードを読んだ経験がないか
|
68
|
+
らです。いいコードを読んだ経験がないと、いいコードを書くことは難しいの
|
69
|
+
で、まずはコードを読む習慣をつける必要があります。
|
70
|
+
|
71
|
+
いいコードは読みやすく、コミットメールに載っている差分だけ読んでも書い
|
72
|
+
た人の意図が理解できるものです。一方、よくないコードは、コミットメール
|
73
|
+
に載っている差分だけ読んでも、よくないコードであることがわかることが多
|
74
|
+
いです。なぜなら、よくないコードは何かしら「歪み」や「臭い」を持ってい
|
75
|
+
るからです。
|
76
|
+
|
77
|
+
コミットメールを読んで、読みやすいと思ったコミットやいい書き方をしてい
|
78
|
+
るなと思ったコミットは書き方を真似て、自分のコミットに取り入れてくださ
|
79
|
+
い。そのコミットに使われていた書き方を使うと、真似された方は真似されて
|
80
|
+
いることに気付きます。同じ書き方を使ったコミットが増えるとまわりの人も
|
81
|
+
気付いて真似するので、いいコードが広まるという流れになればいいと思って
|
82
|
+
います。
|
83
|
+
|
84
|
+
そして、コミットへのコメントサービスでは、コミットメールを読む習慣作り
|
85
|
+
の最初の一歩目をお手伝いします。
|
86
|
+
|
87
|
+
|
88
|
+
** 「Ruby コードの感想戦 【第 1 回】 WikiR」を読む (20分)
|
89
|
+
|
90
|
+
「Ruby コードの感想戦 【第 1 回】 WikiR」を10分くらいで読んでください。
|
91
|
+
http://jp.rubyist.net/magazine/?0040-CodePostMortem
|
92
|
+
|
93
|
+
他の人がどんな読み方をするのか知っておくことは重要です。なぜなら、コー
|
94
|
+
ドを読むときの視点が増えるからです。コードを読むときの視点が増えると、
|
95
|
+
視野が広くなり、自分がコードを書くときの引き出しが増えます。他の人のコー
|
96
|
+
ドの読み方の一例として須藤がコードを読むときにどんなことを考えながら読
|
97
|
+
んでいるかを知ってもらいます。
|
98
|
+
|
99
|
+
Rubyの機能やライブラリの説明が何ヶ所かありますが、その部分は「ふーん、
|
100
|
+
そうなのか」程度で流し読みしてもらって大丈夫です。
|
101
|
+
|
102
|
+
(大きめの字で印刷して配ってもいいかも)
|
103
|
+
|
104
|
+
** 「Ruby コードの感想戦 【第 1 回】 WikiR」の解説 (5分)
|
105
|
+
|
106
|
+
須藤の読み方は、書いた人の意図を想像しながら読むというものでした。しか
|
107
|
+
し、中にはあまり意図などなく書いている人もいます。
|
108
|
+
|
109
|
+
普段、どのようにしてコードやコミットメールを読んでいますか?
|
110
|
+
(順番に聞いていく)
|
111
|
+
(今後に活かすため、記録する)
|
112
|
+
|
113
|
+
講師のコミットメールの読み方を説明します。
|
114
|
+
|
115
|
+
- コミットログを読む
|
116
|
+
- コミットの内容とコミットログの内容が一致しているか確認する
|
117
|
+
- 一致していないときは注意して読む
|
118
|
+
- 一致しているときは、流し読みする
|
119
|
+
- あんまり難しいことは考えない
|
120
|
+
- 間違いを見つける意識では読まない
|
121
|
+
|
122
|
+
あと、自分にとって重要なプロジェクトかどうかで変わります。
|
123
|
+
|
124
|
+
** 実際にやってもらう (15分)
|
125
|
+
|
126
|
+
# 具体的な案はないが、毎回初見のコミットメールを用意するのは大変かも。
|
127
|
+
# 他の導入先のコードは初見のはずなので特に問題ないか
|
128
|
+
|
129
|
+
対象プロジェクトのコミットのうちそのときの最新10から20コミットくらいでやる。
|
130
|
+
|
131
|
+
- 自分がやる(3分)
|
132
|
+
- 1人3分でやってもらう(10分)
|
133
|
+
|
134
|
+
もっと長い時間やったときは記録も付けてもらう
|
135
|
+
|
136
|
+
- 記録を付けてもらう(2分)
|
137
|
+
- 読んだ割合(ざっくり)、印象に残ったコミット
|
138
|
+
|
139
|
+
** 感想を聞く (10分)
|
140
|
+
|
141
|
+
それぞれの人に感想を聞く。
|
142
|
+
|
143
|
+
- 読んでみてどうだった?
|
144
|
+
- 気になったことは?
|
145
|
+
|
146
|
+
(感想など聞いた話は次に活かすために記録する)
|
147
|
+
|
148
|
+
** コメントする方法を説明する (5分)
|
149
|
+
|
150
|
+
- 場所。気になったのはどこかを書く。
|
151
|
+
- 理由。なぜ気になったのか。○○だから読みにくい。理由がなければ無いこ
|
152
|
+
とを書く。
|
153
|
+
- 改善案。改善案があるかないか。改善案があればそれを書く、改善案がなけ
|
154
|
+
れば無いことを書く。
|
155
|
+
|
156
|
+
** まとめ (5分)
|
157
|
+
|
158
|
+
例えば、コミットメールを読むのに使う時間は一日30分までと決めると、時間
|
159
|
+
を使い過ぎることはなくなるので、試してほしいです。徐々にコミットされる
|
160
|
+
コードが読みやすくなってくれば、読めるコミットメールの数や割合が増えて
|
161
|
+
くると思います。
|
162
|
+
|
163
|
+
質問はありますか?
|
164
|
+
|
165
|
+
他に気になることはないですか?
|
166
|
+
|
167
|
+
(何度か質問を繰り返して、疑問点を出してもらってできるかぎり解消しておく。)
|
168
|
+
(また、出てきた質問と回答はメモを取っておいて、次回以降に活かす。)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Haruka Yoshihara <yoshihara@clear-code.com>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require "date"
|
19
|
+
|
20
|
+
module CommitCommentTools
|
21
|
+
class Entry
|
22
|
+
class InvalidEntryError < StandardError
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :name, :date, :read_ratio, :comment
|
26
|
+
|
27
|
+
def initialize(name, entry_chunk)
|
28
|
+
@name = name
|
29
|
+
@date = nil
|
30
|
+
@read_ratio = nil
|
31
|
+
@comment = nil
|
32
|
+
|
33
|
+
if /\A(\d\d\d\d-\d+-\d+):(\d+)%:(.*)\z/m =~ entry_chunk
|
34
|
+
@date = Date.parse($1).strftime("%Y-%m-%d")
|
35
|
+
@read_ratio = $2.to_i
|
36
|
+
@comment = $3
|
37
|
+
else
|
38
|
+
valid_format = "DATE:READ_RATIO%:COMMENT"
|
39
|
+
error_message = "The expected format of entry like below:\n" +
|
40
|
+
"\"#{valid_format}\", but was \"#{entry_chunk}\"."
|
41
|
+
raise(InvalidEntryError, error_message)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Kenji Okimoto <okimoto@clear-code.com>
|
4
|
+
# Copyright (C) 2013 Kouhei Sutou <kou@clear-code.com>
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
require "csv"
|
20
|
+
|
21
|
+
module CommitCommentTools
|
22
|
+
module Generator
|
23
|
+
class CSV
|
24
|
+
def initialize(reports, options={})
|
25
|
+
@reports = reports
|
26
|
+
@options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
def generate
|
30
|
+
members = []
|
31
|
+
daily_read_ratios = {}
|
32
|
+
@reports.each do |name, diaries|
|
33
|
+
members << name
|
34
|
+
diaries.each do |date, report|
|
35
|
+
daily_read_ratios[date] ||= {}
|
36
|
+
daily_read_ratios[date][name] = report[:read_ratio]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
sorted_members = members.sort
|
40
|
+
csv_string = generate_csv(sorted_members, daily_read_ratios)
|
41
|
+
# TODO write to file
|
42
|
+
puts csv_string
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def generate_csv(members, daily_read_ratios)
|
47
|
+
::CSV.generate do |csv|
|
48
|
+
csv << ["DATE", *members]
|
49
|
+
daily_read_ratios.sort_by {|date, _| date}.each do |date, read_ratios|
|
50
|
+
row_values = daily_record2row(read_ratios, members)
|
51
|
+
csv << [date, *row_values]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def daily_record2row(read_ratios, members)
|
57
|
+
members.collect do |name|
|
58
|
+
read_ratios[name] || 0
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Haruka Yoshihara <yoshihara@clear-code.com>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require "gruff"
|
19
|
+
|
20
|
+
module CommitCommentTools
|
21
|
+
module Generator
|
22
|
+
class Graph
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Haruka Yoshihara <yoshihara@clear-code.com>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require "date"
|
19
|
+
|
20
|
+
module CommitCommentTools
|
21
|
+
class ReportNormlizer
|
22
|
+
class << self
|
23
|
+
def normalize(parsed_reports)
|
24
|
+
new.normalize(parsed_reports)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@person_reports = {}
|
30
|
+
end
|
31
|
+
|
32
|
+
def normalize(parsed_reports)
|
33
|
+
parsed_reports.each do |person, daily_report|
|
34
|
+
normalize_daily_report(person, daily_report)
|
35
|
+
end
|
36
|
+
@person_reports
|
37
|
+
end
|
38
|
+
|
39
|
+
def normalize_daily_report(person, daily_report)
|
40
|
+
@person_reports[person] = {}
|
41
|
+
|
42
|
+
daily_report.each do |date, report|
|
43
|
+
normalized_date = normalize_date(date)
|
44
|
+
@person_reports[person][normalized_date] = normalize_report(report)
|
45
|
+
end
|
46
|
+
@person_reports
|
47
|
+
end
|
48
|
+
|
49
|
+
def normalize_date(date)
|
50
|
+
Date.parse(date).strftime("%Y-%m-%d")
|
51
|
+
end
|
52
|
+
|
53
|
+
def normalize_report(report)
|
54
|
+
report[:read_ratio] = report[:read_ratio].to_i
|
55
|
+
report
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Haruka Yoshihara <yoshihara@clear-code.com>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require "English"
|
19
|
+
|
20
|
+
module CommitCommentTools
|
21
|
+
class ReportParser
|
22
|
+
class << self
|
23
|
+
def parse(report_directory=nil)
|
24
|
+
report_directory ||= "."
|
25
|
+
report_unexpanded_path = File.join(report_directory, "**", "*.txt")
|
26
|
+
report_file_paths = Dir.glob(report_unexpanded_path)
|
27
|
+
|
28
|
+
new.parse(report_file_paths)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
@person_reports = {}
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse(report_files)
|
37
|
+
report_files.each do |report_file|
|
38
|
+
person_name = File.basename(report_file, ".txt")
|
39
|
+
next unless person_name == person_name.downcase
|
40
|
+
daily_entries = parse_file(report_file)
|
41
|
+
@person_reports[person_name] = generate_daily_report(daily_entries)
|
42
|
+
end
|
43
|
+
|
44
|
+
@person_reports
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_file(report_file)
|
48
|
+
File.open(report_file, "r") do |report_io|
|
49
|
+
parse_stream(report_io)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_stream(report_io)
|
54
|
+
entries = []
|
55
|
+
date = ""
|
56
|
+
read_ratio = ""
|
57
|
+
comment = ""
|
58
|
+
|
59
|
+
report_io.each_line.with_index do |line, line_number|
|
60
|
+
case line.chomp
|
61
|
+
when /\A(\d\d\d\d-\d+-\d+):(\d+)%:?(.*)\z/
|
62
|
+
unless line_number.zero?
|
63
|
+
entries << entry(date, read_ratio, comment)
|
64
|
+
end
|
65
|
+
|
66
|
+
date = $1
|
67
|
+
read_ratio = $2
|
68
|
+
comment = $3
|
69
|
+
when /\A\s+/
|
70
|
+
comment << $POSTMATCH << "\n"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
unless comment.empty?
|
75
|
+
entries << entry(date, read_ratio, comment)
|
76
|
+
end
|
77
|
+
entries
|
78
|
+
end
|
79
|
+
|
80
|
+
def entry(date, read_ratio, comment)
|
81
|
+
{
|
82
|
+
:date => date,
|
83
|
+
:read_ratio => read_ratio,
|
84
|
+
:comment => comment.chomp
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def generate_daily_report(entries)
|
89
|
+
daily_report = {}
|
90
|
+
|
91
|
+
entries.each do |entry|
|
92
|
+
date = entry.delete(:date)
|
93
|
+
daily_report[date] = entry
|
94
|
+
end
|
95
|
+
daily_report
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|