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