codespicuous 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.
- checksums.yaml +7 -0
- data/Gemfile +7 -0
- data/LICENSE +29 -0
- data/README.md +2 -0
- data/Rakefile +6 -0
- data/bin/codespicuous +4 -0
- data/bin/filezilla/codespicuous.yaml +23 -0
- data/bin/filezilla/committers.csv +4 -0
- data/bin/filezilla/svnlog/filezilla.log +3939 -0
- data/bin/filezilla/svnlog/python.log +3 -0
- data/bin/filezilla/svnlog/xiph.log +265 -0
- data/codespicuous.gemspec +22 -0
- data/lib/codespicuous.rb +38 -0
- data/lib/codespicuous/codespicuous.rb +55 -0
- data/lib/codespicuous/codespicuous_config.rb +35 -0
- data/lib/codespicuous/codespicuousconfigurator.rb +136 -0
- data/lib/codespicuous/commandrunner.rb +13 -0
- data/lib/codespicuous/commithistory.rb +71 -0
- data/lib/codespicuous/commithistory_builder.rb +49 -0
- data/lib/codespicuous/commits.rb +147 -0
- data/lib/codespicuous/commitstatistics.rb +245 -0
- data/lib/codespicuous/committer.rb +105 -0
- data/lib/codespicuous/danielparser.rb +31 -0
- data/lib/codespicuous/dateutil.rb +18 -0
- data/lib/codespicuous/metrics_generator.rb +22 -0
- data/lib/codespicuous/metrics_generator_csv.rb +67 -0
- data/lib/codespicuous/metrics_generator_daniel.rb +13 -0
- data/lib/codespicuous/participantsparser_from_csv.rb +37 -0
- data/lib/codespicuous/repositories.rb +80 -0
- data/lib/codespicuous/repository_lister.rb +8 -0
- data/lib/codespicuous/svn_client.rb +14 -0
- data/lib/codespicuous/svn_data_collector.rb +50 -0
- data/lib/codespicuous/svn_log_parser.rb +100 -0
- data/lib/codespicuous/teams.rb +99 -0
- data/lib/codespicuous/version.rb +4 -0
- data/spec/codespicuous_spec.rb +81 -0
- data/spec/codespicuousconfigurator_spec.rb +202 -0
- data/spec/commithistories_data.rb +46 -0
- data/spec/commithistory_spec.rb +57 -0
- data/spec/commits_spec.rb +93 -0
- data/spec/committers_spec.rb +66 -0
- data/spec/danielparser_spec.rb +12 -0
- data/spec/integration_filezilla_spec.rb +41 -0
- data/spec/metrics_generator_csv_spec.rb +91 -0
- data/spec/metrics_generator_daniel_spec.rb +10 -0
- data/spec/metrics_generator_spec.rb +35 -0
- data/spec/repositories_spec.rb +29 -0
- data/spec/svn_client_spec.rb +16 -0
- data/spec/svn_data_collector_spec.rb +93 -0
- data/spec/svn_log_parser_spec.rb +141 -0
- data/spec/teams_spec.rb +16 -0
- metadata +142 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class CommitHistory
|
4
|
+
|
5
|
+
attr_reader :commits, :teams, :repositories, :committers
|
6
|
+
|
7
|
+
def initialize(commits = Commits.new)
|
8
|
+
@commits = Commits.new
|
9
|
+
@committers = Committers.new
|
10
|
+
@teams = Teams.new
|
11
|
+
@repositories = Repositories.new
|
12
|
+
add_commits(commits)
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_commit(commit)
|
16
|
+
@commits.add(commit)
|
17
|
+
committer(commit.author).add_commit(commit)
|
18
|
+
@repositories.add(commit.repository)
|
19
|
+
commit.repository.add_commit(commit)
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_commits(commits)
|
23
|
+
commits.each { |commit|
|
24
|
+
add_commit(commit)
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_team_member(team, member)
|
29
|
+
team = @teams.team(team)
|
30
|
+
team.add_member(committer(member))
|
31
|
+
end
|
32
|
+
|
33
|
+
def committer(name)
|
34
|
+
@committers.committer(name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def repository(name)
|
38
|
+
@repositories.repository(name)
|
39
|
+
end
|
40
|
+
|
41
|
+
def team(name)
|
42
|
+
@teams.team(name)
|
43
|
+
end
|
44
|
+
|
45
|
+
def repository_names
|
46
|
+
@repositories.repository_names
|
47
|
+
end
|
48
|
+
|
49
|
+
def amount_of_comitters
|
50
|
+
@committers.amount
|
51
|
+
end
|
52
|
+
|
53
|
+
def amount_of_commits_for_team_in_week(team_name, week)
|
54
|
+
@commits.inject(0) { |amount_of_commits, commit|
|
55
|
+
amount_of_commits + ((commit.by_team_with_name?(team_name) && commit.in_week?(week)) ? 1 : 0)
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def earliest_commit_date
|
60
|
+
@commits.earliest_commit_date
|
61
|
+
end
|
62
|
+
|
63
|
+
def latest_commit_date
|
64
|
+
@commits.latest_commit_date
|
65
|
+
end
|
66
|
+
|
67
|
+
def == commit_history
|
68
|
+
@commits == commit_history.commits
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
class CommitHistoryBuilder
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@commit_history = CommitHistory.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def build
|
9
|
+
@commit_history
|
10
|
+
end
|
11
|
+
|
12
|
+
def in_repository(name)
|
13
|
+
@current_repository = Repository.new(name, "")
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def commits_of(name)
|
18
|
+
@author = name
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def of_team(name)
|
23
|
+
@team = name
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def at(date)
|
28
|
+
@commit_date = date
|
29
|
+
add_commit_to_history
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def times(number)
|
34
|
+
(number-1).times {
|
35
|
+
add_commit_to_history
|
36
|
+
}
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_commit_to_history
|
41
|
+
commit = Commit.new
|
42
|
+
commit.author = @author
|
43
|
+
commit.date = DateTime.parse(@commit_date)
|
44
|
+
commit.repository = @current_repository
|
45
|
+
@commit_history.add_commit(commit)
|
46
|
+
@commit_history.add_team_member(@team, @author)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,147 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class Change
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@changed_property = false
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :type, :file, :copyfrom, :copyrev, :kind
|
10
|
+
|
11
|
+
def changed_property?
|
12
|
+
@changed_property
|
13
|
+
end
|
14
|
+
|
15
|
+
def property_changed
|
16
|
+
@changed_property = true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class CommitSameButDifferentError < Exception
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
class Commit
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@changes = []
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_accessor :author, :revision, :message, :date, :changes, :repository, :committer
|
31
|
+
|
32
|
+
def by_team_with_name?(team_name)
|
33
|
+
committer.in_team_with_name?(team_name)
|
34
|
+
end
|
35
|
+
|
36
|
+
def in_week?(date)
|
37
|
+
@date.cwyear == date.cwyear && @date.cweek == date.cweek
|
38
|
+
end
|
39
|
+
|
40
|
+
def my_object_id
|
41
|
+
object_id
|
42
|
+
end
|
43
|
+
|
44
|
+
def inspect
|
45
|
+
"Commit(o:#{my_object_id}) #{repository.name}:#{revision}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def ==(commit)
|
49
|
+
is_equal = @repository == commit.repository && @revision == commit.revision
|
50
|
+
|
51
|
+
raise CommitSameButDifferentError.new if is_equal && @author != commit.author
|
52
|
+
is_equal
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
class Commits
|
58
|
+
|
59
|
+
attr_reader :commits
|
60
|
+
|
61
|
+
def initialize(commits = [])
|
62
|
+
@commits = commits
|
63
|
+
end
|
64
|
+
|
65
|
+
def [] index
|
66
|
+
@commits[index]
|
67
|
+
end
|
68
|
+
|
69
|
+
def each
|
70
|
+
@commits.each { |commit|
|
71
|
+
yield commit
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def inject(value, &block)
|
76
|
+
@commits.inject(value, &block)
|
77
|
+
end
|
78
|
+
|
79
|
+
def commits_in_repository(name)
|
80
|
+
@commits.select { |commit| commit.repository.name == name }
|
81
|
+
end
|
82
|
+
|
83
|
+
def add commit
|
84
|
+
@commits << commit
|
85
|
+
end
|
86
|
+
|
87
|
+
def add_commits commits
|
88
|
+
commits.each { |commit|
|
89
|
+
add commit
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
def set_repository(repository)
|
94
|
+
each { |commit|
|
95
|
+
commit.repository = repository
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
def find_commit(repository, revision)
|
100
|
+
@commits.find { |commit| commit.repository == repository && commit.revision == revision}
|
101
|
+
end
|
102
|
+
|
103
|
+
def find_by_committer name
|
104
|
+
Commits.new (@commits.select { |commit| commit.author == name })
|
105
|
+
end
|
106
|
+
|
107
|
+
def earliest_commit_date
|
108
|
+
@commits.inject(DateTime.now) { |date, commit| date < commit.date ? date : commit.date }
|
109
|
+
end
|
110
|
+
|
111
|
+
def latest_commit_date
|
112
|
+
@commits.inject(DateTime.new(1977)) { |date, commit| date > commit.date ? date : commit.date }
|
113
|
+
end
|
114
|
+
|
115
|
+
def amount
|
116
|
+
@commits.size
|
117
|
+
end
|
118
|
+
|
119
|
+
def amount_of_commits_to_repository(name)
|
120
|
+
commits_in_repository(name).size
|
121
|
+
end
|
122
|
+
|
123
|
+
def amount_of_weeks_committed_in_repository(name)
|
124
|
+
commits_in_repository(name).collect { |commit| [commit.date.cwyear, commit.date.cweek]}.uniq.size
|
125
|
+
end
|
126
|
+
|
127
|
+
def amount_of_commits_in_week(week_start)
|
128
|
+
@commits.select { |commit| commit.in_week?(week_start)}.size
|
129
|
+
end
|
130
|
+
|
131
|
+
def amount_of_commits_to_repository_in_week(name, week_start)
|
132
|
+
commits_in_repository(name).select { |commit|
|
133
|
+
commit.in_week?(week_start)
|
134
|
+
}.size
|
135
|
+
end
|
136
|
+
|
137
|
+
def == commits
|
138
|
+
@commits == commits.commits
|
139
|
+
end
|
140
|
+
|
141
|
+
def +(commits)
|
142
|
+
result = Commits.new
|
143
|
+
result.add_commits(self)
|
144
|
+
result.add_commits(commits)
|
145
|
+
result
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'csv'
|
3
|
+
|
4
|
+
class CommitStatisticsForCommitterInRepository
|
5
|
+
attr_writer :commits
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
self.commits = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def commit(date, amount)
|
12
|
+
@commits[DateTime.parse(date.to_s)] ||= 0
|
13
|
+
@commits[DateTime.parse(date.to_s)] += amount.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
def amount_of_commits
|
17
|
+
@commits.values.inject(0) { |sum, commits_of_week| sum += commits_of_week }
|
18
|
+
end
|
19
|
+
|
20
|
+
def amount_of_weeks_committed
|
21
|
+
@commits.size
|
22
|
+
end
|
23
|
+
|
24
|
+
def amount_of_commits_in_week week_start
|
25
|
+
@commits[week_start] ? @commits[week_start] : 0
|
26
|
+
end
|
27
|
+
|
28
|
+
def first_week_committed
|
29
|
+
commit_week = DateTime.now
|
30
|
+
@commits.each_key { |date|
|
31
|
+
commit_week = date if date < commit_week
|
32
|
+
}
|
33
|
+
commit_week
|
34
|
+
end
|
35
|
+
|
36
|
+
def last_week_committed
|
37
|
+
commit_week = DateTime.new(1977)
|
38
|
+
@commits.each_key { |date|
|
39
|
+
commit_week = date if date > commit_week
|
40
|
+
}
|
41
|
+
commit_week
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class CommitStatisticsForCommitter
|
46
|
+
|
47
|
+
attr_accessor :username, :team, :commits_in_repositories
|
48
|
+
|
49
|
+
def initialize(username)
|
50
|
+
self.username = username
|
51
|
+
self.commits_in_repositories = {}
|
52
|
+
end
|
53
|
+
|
54
|
+
def commit(repository, date, amount)
|
55
|
+
repository(repository.name).commit(date, amount)
|
56
|
+
end
|
57
|
+
|
58
|
+
def repository name
|
59
|
+
@commits_in_repositories[name] ||= CommitStatisticsForCommitterInRepository.new
|
60
|
+
end
|
61
|
+
|
62
|
+
def repositories_committed_to
|
63
|
+
@commits_in_repositories.keys
|
64
|
+
end
|
65
|
+
|
66
|
+
def amount_of_commits
|
67
|
+
@commits_in_repositories.values.inject(0) { |sum, repository|
|
68
|
+
sum + repository.amount_of_commits
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def amount_of_weeks_committed_to_repository name
|
73
|
+
repository(name).amount_of_weeks_committed
|
74
|
+
end
|
75
|
+
|
76
|
+
def amount_of_comnmits_to_repository name
|
77
|
+
repository(name).amount_of_commits
|
78
|
+
end
|
79
|
+
|
80
|
+
def amount_of_commits_in_week week_start
|
81
|
+
@commits_in_repositories.each_value.inject(0) { |sum, commits|
|
82
|
+
sum + commits.amount_of_commits_in_week(week_start)
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def amount_of_commits_to_repository_in_week(name, week_start)
|
87
|
+
repository(name).amount_of_commits_in_week(week_start)
|
88
|
+
end
|
89
|
+
|
90
|
+
def first_week_committed
|
91
|
+
commit_week = DateTime.now
|
92
|
+
@commits_in_repositories.each_value { |commits|
|
93
|
+
commit_week = commits.first_week_committed if commits.first_week_committed < commit_week
|
94
|
+
}
|
95
|
+
commit_week
|
96
|
+
end
|
97
|
+
|
98
|
+
def last_week_committed
|
99
|
+
commit_week = DateTime.new(1977)
|
100
|
+
@commits_in_repositories.each_value { |commits|
|
101
|
+
commit_week = commits.last_week_committed if commits.last_week_committed > commit_week
|
102
|
+
}
|
103
|
+
commit_week
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class CommitStatistics
|
108
|
+
|
109
|
+
attr_accessor :committer_statistics
|
110
|
+
|
111
|
+
def initialize
|
112
|
+
self.committer_statistics = {}
|
113
|
+
end
|
114
|
+
|
115
|
+
def commits= commits
|
116
|
+
commits.each { |commit|
|
117
|
+
commit(commit.author, commit.repository, commit.date)
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
def teams= teams
|
122
|
+
teams.each_member { |team, member|
|
123
|
+
committer(member.username).team = team.name
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
def commit(username, repository, date)
|
128
|
+
committer(username).commit(repository, date, 1)
|
129
|
+
end
|
130
|
+
|
131
|
+
def committer username
|
132
|
+
@committer_statistics[username] ||= CommitStatisticsForCommitter.new(username)
|
133
|
+
end
|
134
|
+
|
135
|
+
def committer_in_team(team)
|
136
|
+
team_members = []
|
137
|
+
@committer_statistics.each_value { |committer|
|
138
|
+
team_members << committer.username if committer.team == team || team == nil
|
139
|
+
}
|
140
|
+
team_members
|
141
|
+
end
|
142
|
+
|
143
|
+
def repositories_committed_to
|
144
|
+
names = []
|
145
|
+
@committer_statistics.each_value { |stats_for_committer|
|
146
|
+
names << stats_for_committer.repositories_committed_to
|
147
|
+
}
|
148
|
+
names.flatten.uniq
|
149
|
+
end
|
150
|
+
|
151
|
+
def teams
|
152
|
+
teams = []
|
153
|
+
@committer_statistics.each_value { |stats_for_committer|
|
154
|
+
teams << stats_for_committer.team
|
155
|
+
}
|
156
|
+
teams.flatten.uniq.sort
|
157
|
+
end
|
158
|
+
|
159
|
+
def first_week_committed
|
160
|
+
commit_week = DateTime.now
|
161
|
+
@committer_statistics.each_value { |committer|
|
162
|
+
commit_week = committer.first_week_committed if committer.first_week_committed < commit_week
|
163
|
+
}
|
164
|
+
commit_week
|
165
|
+
end
|
166
|
+
|
167
|
+
def last_week_committed
|
168
|
+
commit_week = DateTime.new(1977)
|
169
|
+
@committer_statistics.each_value { |committer|
|
170
|
+
commit_week = committer.last_week_committed if committer.last_week_committed > commit_week
|
171
|
+
}
|
172
|
+
commit_week
|
173
|
+
end
|
174
|
+
|
175
|
+
def amount_of_comitters
|
176
|
+
self.committer_statistics.size
|
177
|
+
end
|
178
|
+
|
179
|
+
def amount_of_commits_for_team_in_week(team, week)
|
180
|
+
@committer_statistics.each_value.inject(0) { |amount_of_commits, committer|
|
181
|
+
amount_of_commits + ((committer.team == team) ? committer.amount_of_commits_in_week(week) : 0)
|
182
|
+
}
|
183
|
+
end
|
184
|
+
|
185
|
+
def amount_of_commits_to_repository_in_week(repository, week)
|
186
|
+
@committer_statistics.each_value.inject(0) { |amount_of_commits, committer|
|
187
|
+
amount_of_commits + committer.amount_of_commits_to_repository_in_week(repository, week)
|
188
|
+
}
|
189
|
+
end
|
190
|
+
|
191
|
+
def for_each_week
|
192
|
+
(first_week_committed..last_week_committed).step(7) { |week|
|
193
|
+
yield week
|
194
|
+
}
|
195
|
+
end
|
196
|
+
|
197
|
+
def string_date(date)
|
198
|
+
date.strftime("%Y-%m-%d")
|
199
|
+
end
|
200
|
+
|
201
|
+
def create_commit_table_row_for_committer_with_repository_info committer
|
202
|
+
[committer.username, committer.team, repositories_committed_to.map { |repository| committer.amount_of_comnmits_to_repository(repository)}, committer.amount_of_commits].flatten
|
203
|
+
end
|
204
|
+
|
205
|
+
def create_commit_table_rows_with_committers_and_repository_info(team_to_select)
|
206
|
+
@committer_statistics.values.select { |committer| committer.team == team_to_select }.map { |committer| create_commit_table_row_for_committer_with_repository_info(committer) }
|
207
|
+
end
|
208
|
+
|
209
|
+
def create_commit_table_with_committers_and_repository_info
|
210
|
+
CSV.generate do |csv|
|
211
|
+
csv << ["Committer", "Team", repositories_committed_to, "Total"].flatten
|
212
|
+
teams.each { |team|
|
213
|
+
create_commit_table_rows_with_committers_and_repository_info(team).each { |row| csv << row }
|
214
|
+
}
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def create_commit_table_with_weeks_and_team_commits
|
219
|
+
CSV.generate do |csv|
|
220
|
+
csv << ["Week", teams].flatten
|
221
|
+
for_each_week { |week|
|
222
|
+
csv << [string_date(week), teams.map { |team| amount_of_commits_for_team_in_week(team, week) } ].flatten
|
223
|
+
}
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def create_commit_table_with_week_and_repository_info
|
228
|
+
CSV.generate do |csv|
|
229
|
+
csv << ["Week", repositories_committed_to].flatten
|
230
|
+
for_each_week { |week|
|
231
|
+
csv << [string_date(week), repositories_committed_to.map { |repository| amount_of_commits_to_repository_in_week(repository, week) } ].flatten
|
232
|
+
}
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def create_commit_table_with_weeks_and_committers(team=nil)
|
237
|
+
CSV.generate do |csv|
|
238
|
+
csv << ["Week", committer_in_team(team) ].flatten
|
239
|
+
for_each_week { |week|
|
240
|
+
csv << [string_date(week), @committer_statistics.values.select { |committer| committer.team == team || team == nil }.map { |committer| committer.amount_of_commits_in_week(week)} ].flatten
|
241
|
+
}
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|