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.
@@ -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