codespicuous 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +7 -0
  3. data/LICENSE +29 -0
  4. data/README.md +2 -0
  5. data/Rakefile +6 -0
  6. data/bin/codespicuous +4 -0
  7. data/bin/filezilla/codespicuous.yaml +23 -0
  8. data/bin/filezilla/committers.csv +4 -0
  9. data/bin/filezilla/svnlog/filezilla.log +3939 -0
  10. data/bin/filezilla/svnlog/python.log +3 -0
  11. data/bin/filezilla/svnlog/xiph.log +265 -0
  12. data/codespicuous.gemspec +22 -0
  13. data/lib/codespicuous.rb +38 -0
  14. data/lib/codespicuous/codespicuous.rb +55 -0
  15. data/lib/codespicuous/codespicuous_config.rb +35 -0
  16. data/lib/codespicuous/codespicuousconfigurator.rb +136 -0
  17. data/lib/codespicuous/commandrunner.rb +13 -0
  18. data/lib/codespicuous/commithistory.rb +71 -0
  19. data/lib/codespicuous/commithistory_builder.rb +49 -0
  20. data/lib/codespicuous/commits.rb +147 -0
  21. data/lib/codespicuous/commitstatistics.rb +245 -0
  22. data/lib/codespicuous/committer.rb +105 -0
  23. data/lib/codespicuous/danielparser.rb +31 -0
  24. data/lib/codespicuous/dateutil.rb +18 -0
  25. data/lib/codespicuous/metrics_generator.rb +22 -0
  26. data/lib/codespicuous/metrics_generator_csv.rb +67 -0
  27. data/lib/codespicuous/metrics_generator_daniel.rb +13 -0
  28. data/lib/codespicuous/participantsparser_from_csv.rb +37 -0
  29. data/lib/codespicuous/repositories.rb +80 -0
  30. data/lib/codespicuous/repository_lister.rb +8 -0
  31. data/lib/codespicuous/svn_client.rb +14 -0
  32. data/lib/codespicuous/svn_data_collector.rb +50 -0
  33. data/lib/codespicuous/svn_log_parser.rb +100 -0
  34. data/lib/codespicuous/teams.rb +99 -0
  35. data/lib/codespicuous/version.rb +4 -0
  36. data/spec/codespicuous_spec.rb +81 -0
  37. data/spec/codespicuousconfigurator_spec.rb +202 -0
  38. data/spec/commithistories_data.rb +46 -0
  39. data/spec/commithistory_spec.rb +57 -0
  40. data/spec/commits_spec.rb +93 -0
  41. data/spec/committers_spec.rb +66 -0
  42. data/spec/danielparser_spec.rb +12 -0
  43. data/spec/integration_filezilla_spec.rb +41 -0
  44. data/spec/metrics_generator_csv_spec.rb +91 -0
  45. data/spec/metrics_generator_daniel_spec.rb +10 -0
  46. data/spec/metrics_generator_spec.rb +35 -0
  47. data/spec/repositories_spec.rb +29 -0
  48. data/spec/svn_client_spec.rb +16 -0
  49. data/spec/svn_data_collector_spec.rb +93 -0
  50. data/spec/svn_log_parser_spec.rb +141 -0
  51. data/spec/teams_spec.rb +16 -0
  52. metadata +142 -0
@@ -0,0 +1,105 @@
1
+
2
+ class Committer
3
+
4
+ attr_reader :commits
5
+ attr_accessor :username, :first_name, :last_name, :email, :team
6
+
7
+ def initialize(username)
8
+ @username = username
9
+ @commits = Commits.new
10
+ end
11
+
12
+ def self.create_committer(login, firstname, lastname, email, team)
13
+ committer = Committer.new(login)
14
+ committer.first_name = firstname
15
+ committer.last_name = lastname
16
+ committer.email = email
17
+ committer.team = team
18
+ committer
19
+ end
20
+
21
+ def in_team_with_name?(team_name)
22
+ @team.name == team_name
23
+ end
24
+
25
+ def add_commit commit
26
+ @commits.add(commit)
27
+ commit.committer = self
28
+ end
29
+
30
+ def amount_of_commits
31
+ @commits.amount
32
+ end
33
+
34
+ def amount_of_commits_to_repository name
35
+ @commits.amount_of_commits_to_repository name
36
+ end
37
+
38
+ def amount_of_weeks_committed_to_repository name
39
+ @commits.amount_of_weeks_committed_in_repository(name)
40
+ end
41
+
42
+ def amount_of_commits_in_week(week_start)
43
+ @commits.amount_of_commits_in_week(week_start)
44
+ end
45
+
46
+ def amount_of_commits_to_repository_in_week(name, week_start)
47
+ @commits.amount_of_commits_to_repository_in_week(name, week_start)
48
+ end
49
+
50
+ def ==(committer)
51
+ username == committer.username &&
52
+ first_name == committer.first_name &&
53
+ last_name == committer.last_name &&
54
+ email == committer.email &&
55
+ team.name == committer.team.name
56
+ end
57
+
58
+ end
59
+
60
+ class Committers
61
+
62
+ attr_reader :committers
63
+
64
+ def initialize(initial_committers_usernames = [])
65
+ @committers = {}
66
+
67
+ [initial_committers_usernames].flatten.each { |username|
68
+ @committers[username] = Committer.new(username)
69
+ }
70
+ end
71
+
72
+ def add(committer)
73
+ @committers[committer.username] = committer
74
+ end
75
+
76
+ def committer(name)
77
+ @committers[name] ||= Committer.new(name)
78
+ end
79
+
80
+ def amount
81
+ @committers.size
82
+ end
83
+
84
+ def find_by_username username
85
+ @committers[username]
86
+ end
87
+
88
+ def include? username
89
+ @committers.keys.include?(username)
90
+ end
91
+
92
+ def select(&block)
93
+ @committers.values.select(&block)
94
+ end
95
+
96
+ def empty?
97
+ @committers.empty?
98
+ end
99
+
100
+ def ==(committers)
101
+ @committers == committers.committers
102
+ end
103
+
104
+ end
105
+
@@ -0,0 +1,31 @@
1
+
2
+ class DanielFormatParser
3
+
4
+ def parse committers_daniel_format
5
+
6
+ commit_history = CommitHistory.new
7
+
8
+ current_repository = current_author = ""
9
+
10
+ committers_daniel_format.each_line { |line|
11
+
12
+ if /repository: (.*)/.match(line)
13
+ current_repository = Repository.new($~[1], "")
14
+ elsif /\*\*\* (.*)/.match(line)
15
+ current_author = $~[1]
16
+ elsif /team:(.*)/.match(line)
17
+ commit_history.add_team_member($~[1].strip, current_author)
18
+ elsif / (.*): (.*) commits/.match(line)
19
+ amount_of_commits = $~[2]
20
+ amount_of_commits.to_i.times {
21
+ commit = Commit.new
22
+ commit.author = current_author
23
+ commit.repository = current_repository
24
+ commit.date = DateTime.parse($~[1])
25
+ commit_history.add_commit(commit)
26
+ }
27
+ end
28
+ }
29
+ commit_history
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+
2
+ module DateUtil
3
+
4
+ def begin_of_week(date)
5
+ date - (date.cwday-1)
6
+ end
7
+
8
+ def string_date(date)
9
+ date.strftime("%Y-%m-%d")
10
+ end
11
+
12
+ def for_each_week(start_date, end_date)
13
+ (begin_of_week(start_date)..begin_of_week(end_date)).step(7) { |week|
14
+ yield week
15
+ }
16
+ end
17
+
18
+ end
@@ -0,0 +1,22 @@
1
+
2
+
3
+ class MetricsGenerator
4
+
5
+ attr_accessor :commit_history
6
+
7
+ def generate(commit_history)
8
+ @commit_history = commit_history
9
+ generate_daniel
10
+ generate_csv
11
+ end
12
+
13
+ def generate_daniel
14
+ daniel = MetricsGeneratorDaniel.new(@commit_history)
15
+ daniel.generate
16
+ end
17
+
18
+ def generate_csv
19
+ csv = MetricsGeneratorCsv.new(@commit_history)
20
+ csv.generate
21
+ end
22
+ end
@@ -0,0 +1,67 @@
1
+
2
+
3
+ class MetricsGeneratorCsv
4
+
5
+ include DateUtil
6
+
7
+ def initialize(commit_history)
8
+ @commit_history = commit_history
9
+ end
10
+
11
+ def generate
12
+
13
+ end
14
+
15
+ def create_commit_table_row_for_committer_with_repository_info committer
16
+ [committer.username, committer.team.name, @commit_history.repository_names.map { |repository|
17
+ committer.amount_of_commits_to_repository(repository)}, committer.amount_of_commits].flatten
18
+ end
19
+
20
+ def create_commit_table_rows_with_committers_and_repository_info(team_to_select)
21
+ @commit_history.team(team_to_select.name).members.map { |committer|
22
+ create_commit_table_row_for_committer_with_repository_info(committer) }
23
+ end
24
+
25
+ def create_commit_table_with_committers_and_repository_info
26
+ CSV.generate do |csv|
27
+ csv << ["Committer", "Team", @commit_history.repository_names, "Total"].flatten
28
+ @commit_history.teams.each { |team|
29
+ create_commit_table_rows_with_committers_and_repository_info(team).each { |row| csv << row }
30
+ }
31
+ end
32
+ end
33
+
34
+ def create_commit_table_with_weeks_and_team_commits
35
+ CSV.generate do |csv|
36
+ csv << ["Week", @commit_history.teams.team_names].flatten
37
+ for_each_week(@commit_history.earliest_commit_date, @commit_history.latest_commit_date) { |week|
38
+ csv << [string_date(week), @commit_history.teams.map { |team|
39
+ @commit_history.amount_of_commits_for_team_in_week(team.name, week)
40
+ } ].flatten
41
+ }
42
+ end
43
+ end
44
+
45
+ def create_commit_table_with_week_and_repository_info
46
+ CSV.generate do |csv|
47
+ csv << ["Week", @commit_history.repository_names].flatten
48
+ for_each_week(@commit_history.earliest_commit_date, @commit_history.latest_commit_date) { |week|
49
+ csv << [string_date(week), @commit_history.repositories.map { |repository|
50
+ repository.amount_of_commits_in_week(week)
51
+ } ].flatten
52
+ }
53
+ end
54
+ end
55
+
56
+ def create_commit_table_with_weeks_and_committers(team=nil)
57
+ CSV.generate do |csv|
58
+ csv << ["Week", @commit_history.teams.member_usernames(team) ].flatten
59
+ for_each_week(@commit_history.earliest_commit_date, @commit_history.latest_commit_date) { |week|
60
+ csv << [string_date(week), @commit_history.teams.member_usernames(team).map { |name|
61
+ @commit_history.committers.find_by_username(name).amount_of_commits_in_week(week)
62
+ }].flatten
63
+ }
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,13 @@
1
+
2
+
3
+ class MetricsGeneratorDaniel
4
+
5
+ def initialize(commit_history)
6
+ end
7
+
8
+ def generate
9
+
10
+ end
11
+
12
+
13
+ end
@@ -0,0 +1,37 @@
1
+
2
+
3
+ class CommittersParserFromCsv
4
+
5
+ def initialize
6
+ @committers = Committers.new
7
+ @teams = Teams.new
8
+ end
9
+
10
+ def parse csv_string
11
+ CSV.parse(csv_string, headers: true) { |row|
12
+ parse_row row
13
+ }
14
+ self
15
+ end
16
+
17
+ def parse_row row
18
+ committer = Committer.new(row["Login"])
19
+ committer.first_name = row["First Name"]
20
+ committer.last_name = row["Last Name"]
21
+ committer.email = row["Email"]
22
+ team = @teams.team(row["Team"])
23
+ committer.team = team
24
+ team.add_member(committer)
25
+ @committers.add(committer)
26
+ end
27
+
28
+ def committers
29
+ @committers
30
+ end
31
+
32
+ def teams
33
+ @teams
34
+ end
35
+ end
36
+
37
+
@@ -0,0 +1,80 @@
1
+
2
+
3
+ class SameRepositoriesWithDifferentCommitsError < Exception
4
+
5
+ end
6
+
7
+ class Repository
8
+
9
+ attr_reader :commits
10
+ attr_accessor :url, :name
11
+
12
+ def initialize(name, url)
13
+ @name = name
14
+ @url = url
15
+ @commits = Commits.new
16
+ end
17
+
18
+ def add_commit commit
19
+ @commits.add(commit)
20
+ end
21
+
22
+ def amount_of_commits_in_week(week_start)
23
+ @commits.amount_of_commits_to_repository_in_week(name, week_start)
24
+ end
25
+
26
+ def ==(repository)
27
+ is_equal = @name == repository.name && @url == repository.url
28
+
29
+ raise SameRepositoriesWithDifferentCommitsError.new if is_equal && @commits != repository.commits
30
+ is_equal
31
+ end
32
+ end
33
+
34
+ class Repositories
35
+
36
+ attr_reader :repositories
37
+
38
+ def initialize
39
+ @repositories = {}
40
+ end
41
+
42
+ def add repository
43
+ @repositories[repository.name] = repository
44
+ end
45
+
46
+ def repository name
47
+ @repositories[name]
48
+ end
49
+
50
+ def repository_names
51
+ @repositories.keys
52
+ end
53
+
54
+ def amount
55
+ @repositories.size
56
+ end
57
+
58
+ def each
59
+ @repositories.values.each { |repository|
60
+ yield repository
61
+ }
62
+ end
63
+
64
+ def empty?
65
+ @repositories.empty?
66
+ end
67
+
68
+ def map(&block)
69
+ @repositories.values.map(&block)
70
+ end
71
+
72
+ def [](index)
73
+ @repositories.values[index]
74
+ end
75
+
76
+ def ==(repositories)
77
+ @repositories == repositories.repositories
78
+ end
79
+ end
80
+
@@ -0,0 +1,8 @@
1
+
2
+
3
+ class RepositoryLister
4
+
5
+ def list(commit_history)
6
+
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+
2
+ require 'attempt_to'
3
+ class SVNClient
4
+
5
+ def repository(repository)
6
+ @repository = repository
7
+ end
8
+
9
+ def log_xml(from, to)
10
+ AttemptTo.attempt_to('svn log: "' + @repository + '"', 5) {
11
+ CommandRunner.run("svn log #{@repository} -r{#{from.strftime("%Y-%m-%d")}}:{#{to.strftime("%Y-%m-%d")}} --xml")
12
+ }
13
+ end
14
+ end
@@ -0,0 +1,50 @@
1
+ require 'date'
2
+
3
+ class SVNDataCollector
4
+
5
+ attr_reader :config
6
+
7
+ def initialize(config)
8
+ @config = config
9
+ end
10
+
11
+ def retrieve_svn_log_from(repository)
12
+ if config.offline
13
+ File.read(config.path_to_cached_svn_log(repository.name))
14
+ else
15
+ svn = SVNClient.new
16
+ svn.repository(repository.url)
17
+ now = DateTime.now
18
+ svn.log_xml(now.prev_year, now)
19
+ end
20
+ end
21
+
22
+ def retrieve_commits_from_log(xmllog)
23
+ parser = SVNLogParser.new
24
+ parser.parse(xmllog)
25
+ parser.commits
26
+ end
27
+
28
+ def save_svn_log(repository, xmllog)
29
+ Dir.mkdir(config.path_to_cached_svn_log_dir) unless Dir.exists?(config.path_to_cached_svn_log_dir)
30
+ File.write(config.path_to_cached_svn_log(repository.name), xmllog)
31
+ end
32
+
33
+ def collect_commits_for_repository(repository)
34
+ puts "Getting svn log from repository: " + repository.name
35
+ xmllog = retrieve_svn_log_from(repository)
36
+ save_svn_log(repository, xmllog)
37
+ commits_in_repository = retrieve_commits_from_log(xmllog)
38
+ commits_in_repository.set_repository(repository)
39
+ commits_in_repository
40
+ end
41
+
42
+ def collect_commit_history(repositories)
43
+ commit_history = CommitHistory.new
44
+ repositories.each { | repository|
45
+ commit_history.add_commits(collect_commits_for_repository(repository))
46
+ }
47
+ commit_history
48
+ end
49
+
50
+ end