pair_see 0.1.5 → 0.1.6
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 +4 -4
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +98 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +8 -0
- data/README.md +35 -43
- data/Rakefile +1 -1
- data/TODO.md +3 -20
- data/bin/bundler +7 -6
- data/bin/cc-tddium-post-worker +7 -6
- data/bin/coderay +7 -6
- data/bin/console +0 -0
- data/bin/htmldiff +7 -6
- data/bin/ldiff +7 -6
- data/bin/pairsee +22 -8
- data/bin/pry +7 -6
- data/bin/rake +7 -6
- data/bin/rake_commit +7 -6
- data/bin/rspec +7 -6
- data/bin/rubocop +7 -6
- data/bin/ruby-parse +7 -6
- data/bin/ruby-rewrite +7 -6
- data/config/config.yml.example +11 -0
- data/lib/pair_see.rb +1 -1
- data/lib/pair_see/active_devs.rb +3 -12
- data/lib/pair_see/card.rb +5 -4
- data/lib/pair_see/card_knowledge_summary.rb +25 -0
- data/lib/pair_see/cards_per_person.rb +35 -25
- data/lib/pair_see/date_combo.rb +2 -1
- data/lib/pair_see/knowledge_debt.rb +31 -0
- data/lib/pair_see/log_line.rb +38 -40
- data/lib/pair_see/log_line_parse.rb +24 -0
- data/lib/pair_see/log_lines.rb +6 -10
- data/lib/pair_see/{combo.rb → pair_commit_count.rb} +3 -2
- data/lib/pair_see/pair_recency.rb +27 -0
- data/lib/pair_see/pairing_event.rb +24 -0
- data/lib/pair_see/person.rb +0 -1
- data/lib/pair_see/seer.rb +25 -101
- data/lib/pair_see/too_much_stuff.rb +157 -0
- data/lib/pair_see/version.rb +1 -1
- data/pair_see.gemspec +1 -0
- metadata +13 -5
- data/config/config.yml.sample +0 -8
@@ -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
|
data/lib/pair_see/log_lines.rb
CHANGED
@@ -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
|
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
|
@@ -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
|
data/lib/pair_see/person.rb
CHANGED
data/lib/pair_see/seer.rb
CHANGED
@@ -1,128 +1,52 @@
|
|
1
1
|
module PairSee
|
2
2
|
class Seer
|
3
|
-
|
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 :
|
12
|
-
@@maximum_commits_to_parse = 9999
|
5
|
+
attr_reader :seer
|
13
6
|
|
14
7
|
def initialize(options)
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@
|
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
|
24
|
-
|
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
|
66
|
-
|
67
|
-
config['card_prefix']
|
20
|
+
def all_most_recent_commits
|
21
|
+
seer.all_most_recent_commits
|
68
22
|
end
|
69
23
|
|
70
|
-
def
|
71
|
-
|
24
|
+
def recommended_pairings
|
25
|
+
seer.recommended_pairings
|
72
26
|
end
|
73
27
|
|
74
|
-
def
|
75
|
-
|
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
|
81
|
-
|
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
|
-
|
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
|
99
|
-
|
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
|
115
|
-
|
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
|
121
|
-
|
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
|