pair_see 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,24 @@
1
+ module PairSee
2
+ class LogLineParse
3
+ require_relative 'log_lines'
4
+ require 'git'
5
+
6
+ @@maximum_commits_to_parse = 9999
7
+ attr_reader :log_lines
8
+
9
+ def initialize(roots, date_string)
10
+ @log_lines = _parse(date_string, roots)
11
+ end
12
+
13
+ def _parse(date_string, roots)
14
+ lines = []
15
+ roots.each do |root|
16
+ g = Git.open(root)
17
+ lines << g.log(@@maximum_commits_to_parse).since(date_string).map do |l|
18
+ LogLine.new("#{l.date} #{l.message}")
19
+ end
20
+ end
21
+ LogLines.new(lines.flatten)
22
+ end
23
+ end
24
+ end
@@ -10,11 +10,11 @@ module PairSee
10
10
  end
11
11
 
12
12
  def each(&block)
13
- lines.each &block
13
+ @lines.each &block
14
14
  end
15
15
 
16
16
  def last
17
- lines.last
17
+ @lines.last
18
18
  end
19
19
 
20
20
  def active?(person)
@@ -24,21 +24,17 @@ module PairSee
24
24
  end
25
25
 
26
26
  def commits_for_pair(person1, person2)
27
- select {|log_line| log_line.authored_by?(person1, person2)}
27
+ select { |log_line| log_line.authored_by?(person1, person2) }
28
28
  end
29
29
 
30
- def commits_not_by_known_pair(devs)
31
- reject {|log_line| log_line.by_any? devs}
30
+ def commits_not_by_known_person(devs)
31
+ reject { |log_line| log_line.by_any? devs }
32
32
  end
33
33
 
34
34
  def solo_commits(people, person)
35
35
  select do |log_line|
36
- log_line.authored_by?(person) && (people - [person]).none? {|single_person| log_line.authored_by?(single_person)}
36
+ log_line.authored_by?(person) && (people - [person]).none? { |single_person| log_line.authored_by?(single_person) }
37
37
  end
38
38
  end
39
-
40
- private
41
-
42
- attr_reader :lines
43
39
  end
44
40
  end
@@ -1,9 +1,10 @@
1
1
  module PairSee
2
- class Combo
2
+ class PairCommitCount
3
3
  attr_reader :count, :devs
4
4
 
5
5
  def initialize(count, *devs)
6
- @count, @devs = count, devs
6
+ @count = count
7
+ @devs = devs
7
8
  end
8
9
 
9
10
  def to_s
@@ -0,0 +1,27 @@
1
+ module PairSee
2
+ class PairRecency
3
+ def initialize(log_lines, card_prefixes, people)
4
+ @log_lines = log_lines
5
+ @card_prefixes = card_prefixes
6
+ @people = people
7
+ end
8
+
9
+ def pair_recency
10
+ pairing_events = @people.map do |current_person|
11
+ my_commits = @log_lines.select { |ll| ll.authored_by?(current_person) }
12
+
13
+ most_recent_commits = {}
14
+ @people.map do |pair|
15
+ my_commits.each do |ll|
16
+ if pair.display_name != current_person.display_name && ll.authored_by?(pair)
17
+ most_recent_commits[pair] = [ll, pair] # TODO: make [ll, pair] and object? or make ll know devs in ll?
18
+ end
19
+ end
20
+ end
21
+ PairingEvent.new(current_person, most_recent_commits)
22
+ end
23
+
24
+ pairing_events.map(&:pretty) # TODO: make an object which extends Enum and holds pairing events
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ module PairSee
2
+ class PairingEvent
3
+ def initialize(current_person, most_recent_commits)
4
+ @current_person = current_person
5
+ @most_recent_commits = most_recent_commits
6
+ end
7
+
8
+ def pretty
9
+ @most_recent_commits.sort_by { |_pair, tuple| tuple.first.date }.map do |_pair, tuple|
10
+ "#{@current_person}, #{tuple.last}: #{tuple.first.date}"
11
+ end + _pretty_spacing
12
+ end
13
+
14
+ def person
15
+ @current_person
16
+ end
17
+
18
+ private
19
+
20
+ def _pretty_spacing
21
+ ['']
22
+ end
23
+ end
24
+ end
@@ -1,6 +1,5 @@
1
1
  module PairSee
2
2
  class Person
3
-
4
3
  attr_reader :display_name
5
4
  attr_reader :names
6
5
 
@@ -1,128 +1,52 @@
1
1
  module PairSee
2
2
  class Seer
3
- require 'yamler'
4
- require_relative 'combo'
5
- require_relative 'date_combo'
6
- require_relative 'log_lines'
7
- require_relative 'card'
8
- require_relative 'cards_per_person'
9
- require_relative 'active_devs'
3
+ require_relative 'too_much_stuff'
10
4
 
11
- attr_reader :log_lines, :devs, :dev_pairs, :card_prefixes
12
- @@maximum_commits_to_parse = 9999
5
+ attr_reader :seer
13
6
 
14
7
  def initialize(options)
15
- @log_lines = _lines_from(options[:repo_locations], options[:after_date])
16
- @sub_seer = CardsPerPerson.new(@log_lines, options[:card_prefix], options[:names])
17
- @active_devs = ActiveDevs.new(@log_lines, options).devs
18
- @devs = @sub_seer.devs
19
- @card_prefixes = options[:card_prefix]
20
- @dev_pairs = devs.combination(2)
8
+ @repo_locations = options[:repo_locations]
9
+ @after_date = options[:after_date]
10
+ @card_prefix = options[:card_prefix]
11
+ @names = options[:names]
12
+ @seer = PairSee::TooMuchStuff.new(options)
13
+ @log_lines = LogLineParse.new(@repo_locations, @after_date).log_lines
21
14
  end
22
15
 
23
- def cards_per_person
24
- @sub_seer.cards_per_person
25
- end
26
-
27
- def _lines_from(roots, date_string)
28
- lines = []
29
- roots.each {|root|
30
- g = Git.open(root)
31
- lines << g.log(@@maximum_commits_to_parse).since(date_string).map do |l|
32
- LogLine.new("#{l.date} #{l.message}")
33
- end
34
- }
35
- LogLines.new(lines.flatten)
36
- end
37
-
38
- def pretty_card_data
39
- card_data(card_prefixes).map do |card|
40
- card.pretty unless card.nil?
41
- end
42
- end
43
-
44
- def card_data(card_prefixes)
45
- card_prefixes.map do |card_prefix|
46
- card_numbers(card_prefix).map do |card_name|
47
- commits = commits_on_card(card_name)
48
- Card.new(card_name, commits.count, commits.first.date, commits.last.date)
49
- end
50
- end.flatten.sort_by(&:duration).reverse
51
- end
52
-
53
- def commits_on_card(card_name)
54
- log_lines.select {|line| line.contains_card_name?(card_name)}
55
- end
56
-
57
- def card_numbers(card_prefix)
58
- log_lines.select do |line|
59
- line.contains_card?(card_prefix)
60
- end.map do |line|
61
- line.card_name([card_prefix])
62
- end.uniq.compact
16
+ def commits_not_by_known_pair
17
+ seer.commits_not_by_known_person
63
18
  end
64
19
 
65
- def get_card_prefix(config_file)
66
- config = YAML.load_file(config_file)
67
- config['card_prefix']
20
+ def all_most_recent_commits
21
+ seer.all_most_recent_commits
68
22
  end
69
23
 
70
- def active_devs(config_file)
71
- @active_devs
24
+ def recommended_pairings
25
+ seer.recommended_pairings
72
26
  end
73
27
 
74
- def pair_commits
75
- dev_pairs.map do |person1, person2|
76
- Combo.new(commits_for_pair(person1, person2).count, person1, person2)
77
- end
28
+ def pretty_card_data
29
+ seer.pretty_card_data
78
30
  end
79
31
 
80
- def solo_commits
81
- devs.map do |dev|
82
- Combo.new(log_lines.solo_commits(devs, dev).count, dev)
83
- end
32
+ def pretty_card_data_by_commits
33
+ seer.pretty_card_data_by_commits
84
34
  end
85
35
 
86
36
  def all_commits
87
- (pair_commits + solo_commits).sort_by(&:count).reject(&:empty?).map(&:to_s)
88
- end
89
-
90
- def commits_for_pair(person1, person2)
91
- log_lines.commits_for_pair person1, person2
92
- end
93
-
94
- def commits_not_by_known_pair
95
- log_lines.commits_not_by_known_pair devs
37
+ seer.all_commits
96
38
  end
97
39
 
98
- def most_recent_commit_date(person1, person2)
99
- recent_commit = commits_for_pair(person1, person2).sort_by(&:date).first
100
- recent_commit ? recent_commit.date : nil
101
- end
102
-
103
- def all_most_recent_commits
104
- dev_pairs.map do |person1, person2|
105
- DateCombo.new(most_recent_commit_date(person1, person2), person1, person2)
106
- end.sort.reverse.map &:to_s
107
- end
108
-
109
- def recommended_pairings
110
- should_pair = unpaired_in_range
111
- should_pair.empty? ? [least_recent_pair] : should_pair
40
+ def cards_per_person
41
+ CardsPerPerson.new(@log_lines, @card_prefix, @names).cards_per_person
112
42
  end
113
43
 
114
- def least_recent_pair
115
- devs.select do |person|
116
- person.names.any? {|name| log_lines.last.line.match(name)}
117
- end.map(&:display_name).join(', ')
44
+ def knowledge_debt
45
+ KnowledgeDebt.new(@log_lines, @card_prefix, @names).knowledge_debt
118
46
  end
119
47
 
120
- def unpaired_in_range
121
- dev_pairs.select do |person1, person2|
122
- most_recent_commit_date(person1, person2).nil?
123
- end.map do |person1, person2|
124
- "#{person1}, #{person2}"
125
- end
48
+ def pair_recency
49
+ PairRecency.new(@log_lines, @card_prefix, @names).pair_recency
126
50
  end
127
51
  end
128
52
  end
@@ -0,0 +1,157 @@
1
+ require 'pry'
2
+ module PairSee
3
+ class TooMuchStuff
4
+ require 'yamler'
5
+ require_relative 'pair_commit_count'
6
+ require_relative 'date_combo'
7
+ require_relative 'log_lines'
8
+ require_relative 'log_line_parse'
9
+ require_relative 'card'
10
+ require_relative 'cards_per_person'
11
+ require_relative 'active_devs'
12
+
13
+ def initialize(options)
14
+ @log_lines = LogLineParse.new(options[:repo_locations], options[:after_date]).log_lines
15
+ @active_devs = ActiveDevs.new(@log_lines, options[:names]).devs
16
+
17
+ cards_per_person = CardsPerPerson.new(@log_lines, options[:card_prefix], options[:names])
18
+ @devs = cards_per_person.people
19
+ @dev_pairs = cards_per_person.dev_pairs
20
+
21
+ @card_prefixes = options[:card_prefix]
22
+ end
23
+
24
+ def pretty_card_data
25
+ card_data(@card_prefixes).map do |card|
26
+ card&.pretty
27
+ end
28
+ end
29
+
30
+ def pretty_card_data_by_commits
31
+ card_data(@card_prefixes).compact.sort_by.sort_by(&:number_of_commits).reverse.map(&:pretty)
32
+ end
33
+
34
+ def card_data(card_prefixes)
35
+ card_prefixes.map do |card_prefix|
36
+ card_numbers(card_prefix).map do |card_name|
37
+ Card.new(card_name, commits_on_card(card_name).sort_by(&:date))
38
+ end
39
+ end.flatten.sort_by(&:duration).reverse
40
+ end
41
+
42
+ def commits_on_card(card_name)
43
+ @log_lines.select { |line| line.contains_card_name?(card_name) }
44
+ end
45
+
46
+ def card_numbers(card_prefix)
47
+ @log_lines.select do |line|
48
+ line.contains_card?(card_prefix)
49
+ end.map do |line|
50
+ line.card_name([card_prefix])
51
+ end.uniq.compact
52
+ end
53
+
54
+ def get_card_prefix(config_file)
55
+ config = YAML.load_file(config_file)
56
+ config['card_prefix']
57
+ end
58
+
59
+ def pair_commits
60
+ @dev_pairs.map do |person1, person2|
61
+ log_lines_commits_for_pair = @log_lines.commits_for_pair person1, person2
62
+ PairCommitCount.new(log_lines_commits_for_pair.count, person1, person2)
63
+ end
64
+ end
65
+
66
+ def solo_commits
67
+ @devs.map do |dev|
68
+ PairCommitCount.new(@log_lines.solo_commits(@devs, dev).count, dev)
69
+ end
70
+ end
71
+
72
+ def all_commits
73
+ pairs_result = Hash[@dev_pairs.map { |k, v| [names_key(k, v), 0] }]
74
+ solos_result = Hash[@devs.map { |k| [k.display_name, 0] }]
75
+ result = pairs_result.merge solos_result
76
+
77
+ @log_lines.each do |ll|
78
+ result = method_name(ll, result)
79
+ end
80
+ result
81
+ .sort_by { |_, count| count }
82
+ .reject { |_, count| count == 0 }
83
+ .map { |names, count| "#{names}: #{count}" }
84
+ end
85
+
86
+ def method_name(ll, result)
87
+ @dev_pairs.each do |d1, d2|
88
+ if ll.authored_by?(d1, d2)
89
+ result[names_key(d1, d2)] += 1
90
+ return result
91
+ elsif is_solo_by?(@devs, d1, ll)
92
+ result[d1.display_name] += 1
93
+ return result
94
+ elsif is_solo_by?(@devs, d2, ll)
95
+ result[d2.display_name] += 1
96
+ return result
97
+ end
98
+ end
99
+ result
100
+ end
101
+
102
+ def is_solo_by?(devs, person, log_line)
103
+ no_other_devs_in_commit = (devs - [person]).none? { |dx| log_line.authored_by?(dx) }
104
+ log_line.authored_by?(person) && no_other_devs_in_commit
105
+ end
106
+
107
+ def names_key(k, v)
108
+ [k, v].sort_by(&:display_name).map(&:to_s).join(', ')
109
+ end
110
+
111
+ def b(log_line, person1)
112
+ log_line.authored_by?(person1) && (people - [person1]).none? { |single_person| log_line.authored_by?(single_person) }
113
+ end
114
+
115
+ def a(log_line, person1, person2)
116
+ log_line.authored_by?(person1, person2)
117
+ end
118
+
119
+ def commits_for_pair(person1, person2)
120
+ @log_lines.commits_for_pair person1, person2
121
+ end
122
+
123
+ def commits_not_by_known_person
124
+ @log_lines.commits_not_by_known_person @devs
125
+ end
126
+
127
+ def most_recent_commit_date(person1, person2)
128
+ recent_commit = commits_for_pair(person1, person2).sort_by(&:date).first
129
+ recent_commit ? recent_commit.date : nil
130
+ end
131
+
132
+ def all_most_recent_commits
133
+ @dev_pairs.map do |person1, person2|
134
+ DateCombo.new(most_recent_commit_date(person1, person2), person1, person2)
135
+ end.sort.reverse.map &:to_s
136
+ end
137
+
138
+ def recommended_pairings
139
+ should_pair = unpaired_in_range
140
+ should_pair.empty? ? [least_recent_pair] : should_pair
141
+ end
142
+
143
+ def least_recent_pair
144
+ devs.select do |person|
145
+ person.names.any? { |name| @log_lines.last.line.match(name) }
146
+ end.map(&:display_name).join(', ')
147
+ end
148
+
149
+ def unpaired_in_range
150
+ @dev_pairs.select do |person1, person2|
151
+ most_recent_commit_date(person1, person2).nil?
152
+ end.map do |person1, person2|
153
+ "#{person1}, #{person2}"
154
+ end
155
+ end
156
+ end
157
+ end