commit-comment-tools 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ # News
2
+
3
+ ## <a id="0-0-1">0.0.1</a>: 2013-04-11
4
+
5
+ The first release!
@@ -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,4 @@
1
+ module CommitCommentTools
2
+ module Generator
3
+ end
4
+ 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