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.
data/bin/pry CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -7,11 +8,11 @@
7
8
  # this file is here to facilitate running it.
8
9
  #
9
10
 
10
- require "pathname"
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
- Pathname.new(__FILE__).realpath)
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
13
14
 
14
- require "rubygems"
15
- require "bundler/setup"
15
+ require 'rubygems'
16
+ require 'bundler/setup'
16
17
 
17
- load Gem.bin_path("pry", "pry")
18
+ load Gem.bin_path('pry', 'pry')
data/bin/rake CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -7,11 +8,11 @@
7
8
  # this file is here to facilitate running it.
8
9
  #
9
10
 
10
- require "pathname"
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
- Pathname.new(__FILE__).realpath)
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
13
14
 
14
- require "rubygems"
15
- require "bundler/setup"
15
+ require 'rubygems'
16
+ require 'bundler/setup'
16
17
 
17
- load Gem.bin_path("rake", "rake")
18
+ load Gem.bin_path('rake', 'rake')
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -7,11 +8,11 @@
7
8
  # this file is here to facilitate running it.
8
9
  #
9
10
 
10
- require "pathname"
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
- Pathname.new(__FILE__).realpath)
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
13
14
 
14
- require "rubygems"
15
- require "bundler/setup"
15
+ require 'rubygems'
16
+ require 'bundler/setup'
16
17
 
17
- load Gem.bin_path("rake_commit", "rake_commit")
18
+ load Gem.bin_path('rake_commit', 'rake_commit')
data/bin/rspec CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -7,11 +8,11 @@
7
8
  # this file is here to facilitate running it.
8
9
  #
9
10
 
10
- require "pathname"
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
- Pathname.new(__FILE__).realpath)
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
13
14
 
14
- require "rubygems"
15
- require "bundler/setup"
15
+ require 'rubygems'
16
+ require 'bundler/setup'
16
17
 
17
- load Gem.bin_path("rspec-core", "rspec")
18
+ load Gem.bin_path('rspec-core', 'rspec')
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -7,11 +8,11 @@
7
8
  # this file is here to facilitate running it.
8
9
  #
9
10
 
10
- require "pathname"
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
- Pathname.new(__FILE__).realpath)
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
13
14
 
14
- require "rubygems"
15
- require "bundler/setup"
15
+ require 'rubygems'
16
+ require 'bundler/setup'
16
17
 
17
- load Gem.bin_path("rubocop", "rubocop")
18
+ load Gem.bin_path('rubocop', 'rubocop')
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -7,11 +8,11 @@
7
8
  # this file is here to facilitate running it.
8
9
  #
9
10
 
10
- require "pathname"
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
- Pathname.new(__FILE__).realpath)
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
13
14
 
14
- require "rubygems"
15
- require "bundler/setup"
15
+ require 'rubygems'
16
+ require 'bundler/setup'
16
17
 
17
- load Gem.bin_path("parser", "ruby-parse")
18
+ load Gem.bin_path('parser', 'ruby-parse')
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -7,11 +8,11 @@
7
8
  # this file is here to facilitate running it.
8
9
  #
9
10
 
10
- require "pathname"
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
- Pathname.new(__FILE__).realpath)
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
13
14
 
14
- require "rubygems"
15
- require "bundler/setup"
15
+ require 'rubygems'
16
+ require 'bundler/setup'
16
17
 
17
- load Gem.bin_path("parser", "ruby-rewrite")
18
+ load Gem.bin_path('parser', 'ruby-rewrite')
@@ -0,0 +1,11 @@
1
+ names:
2
+ - Person1
3
+ - Person2
4
+ - ManyNamesPerson mnperson mprss
5
+ card_prefix:
6
+ - FOO-
7
+ - BAR-
8
+ roots:
9
+ - /Users/foo/repo1
10
+ - /Users/foo/repositories/repo2
11
+ - /Users/foo/repositories/baz/repo3
@@ -1,5 +1,5 @@
1
1
  require_relative 'pair_see/version.rb'
2
- require_relative 'pair_see/seer.rb'
2
+ require_relative 'pair_see/too_much_stuff.rb'
3
3
 
4
4
  module PairSee
5
5
  end
@@ -2,18 +2,9 @@ module PairSee
2
2
  class ActiveDevs
3
3
  attr_reader :devs
4
4
 
5
- def initialize(log_lines, options)
5
+ def initialize(log_lines, people)
6
6
  @log_lines = log_lines
7
- @options = options
8
- @devs = _active(options[:names])
9
- end
10
-
11
- def active_devs(config_file)
12
- config = YAML.load_file(config_file)
13
- devs_in_config = config['names'].split(' ')
14
- devs_in_config.select do |dev|
15
- _is_active?(dev)
16
- end
7
+ @devs = _active(people)
17
8
  end
18
9
 
19
10
  def _active(devs)
@@ -26,4 +17,4 @@ module PairSee
26
17
  @log_lines.active? dev
27
18
  end
28
19
  end
29
- end
20
+ end
@@ -2,14 +2,15 @@ module PairSee
2
2
  class Card
3
3
  attr_reader :card_name, :number_of_commits, :last_date
4
4
 
5
- def initialize(card_name, number_of_commits, first_date, last_date)
5
+ def initialize(card_name, commits)
6
6
  @card_name = card_name
7
- @number_of_commits = number_of_commits
8
- @first_date, @last_date = first_date, last_date
7
+ @number_of_commits = commits.count
8
+ @first_date = commits.first.date
9
+ @last_date = commits.last.date
9
10
  end
10
11
 
11
12
  def duration
12
- (@first_date - @last_date).to_i + 1
13
+ (@last_date - @first_date).to_i + 1
13
14
  end
14
15
 
15
16
  def ==(other)
@@ -0,0 +1,25 @@
1
+ module PairSee
2
+ class CardKnowledgeSummary
3
+ include Comparable
4
+ attr_reader :commits_on_card_count
5
+
6
+ def initialize(card_number, commits_on_card_count, authors)
7
+ @card_number = card_number
8
+ @commits_on_card_count = commits_on_card_count
9
+ @authors = authors
10
+ end
11
+
12
+ def has_debt
13
+ @authors.count < 2
14
+ end
15
+
16
+ def pretty
17
+ pretty_author_names = @authors.map(&:to_s).join
18
+ "#{@card_number} has #{@commits_on_card_count} commits with only #{@authors.count} committer(s) #{pretty_author_names} on the entire card"
19
+ end
20
+
21
+ def authors_list
22
+ @authors.sort.join(' ')
23
+ end
24
+ end
25
+ end
@@ -1,40 +1,50 @@
1
1
  module PairSee
2
2
  class CardsPerPerson
3
- attr_reader :devs
3
+ attr_reader :people, :cards_per_person, :dev_pairs
4
4
 
5
5
  def initialize(log_lines, card_prefix, people)
6
- @log_lines = log_lines
7
- @card_prefix = card_prefix
8
- @devs = _active(people)
6
+ @people = _active(people, log_lines)
7
+ @cards_per_person = _cards_per_person(log_lines, card_prefix)
8
+ @dev_pairs = @people.combination(2)
9
9
  end
10
10
 
11
- def cards_per_person
12
- @devs.map do |dev|
13
- {dev => _cards_dev_worked_on(@log_lines, dev)}
14
- end.inject({}) do |result, element|
15
- result.merge(element)
16
- end.map do |dev_name, cards_worked|
17
- {dev_name => cards_worked.uniq}
18
- end.inject({}) do |result, element|
19
- result.merge(element)
20
- end.sort do |a, b|
21
- a[1].size <=> b[1].size
22
- end.map do |dev, cards|
23
- "#{dev}: [#{cards.size} cards] #{cards.sort.join(', ')}"
11
+ private
12
+
13
+ def _cards_per_person(log_lines, card_prefix)
14
+ all = _people_hash
15
+ _populate_card_numbers(all, log_lines, card_prefix)
16
+ _unique_cards_per_person(all)
17
+ _sort_by_cards_count(all)
18
+ end
19
+
20
+ def _sort_by_cards_count(all)
21
+ all.sort_by { |_, card_names| card_names.count }.map do |person, card_names|
22
+ sorted = card_names.compact.sort_by(&:to_i)
23
+ "#{person}: [#{card_names.size} cards] #{sorted.join(', ')}"
24
+ end
25
+ end
26
+
27
+ def _unique_cards_per_person(all)
28
+ all.each { |_, card_names| card_names.uniq! }
29
+ end
30
+
31
+ def _populate_card_numbers(all, log_lines, card_prefix)
32
+ log_lines.each do |log_line| # loop through the biggest list only once
33
+ all.each do |person, _|
34
+ if log_line.authored_by? person
35
+ all[person] << log_line.card_number(card_prefix)
36
+ end
37
+ end
24
38
  end
25
39
  end
26
40
 
27
- def _cards_dev_worked_on(log_lines, person)
28
- log_lines.select do |log_line|
29
- log_line.authored_by?(person)
30
- end.map do |log_line|
31
- log_line.card_number(@card_prefix)
32
- end.compact
41
+ def _people_hash
42
+ Hash[people.map { |key, _| [key, []] }]
33
43
  end
34
44
 
35
- def _active(people)
45
+ def _active(people, log_lines)
36
46
  people.select do |person|
37
- @log_lines.active? person
47
+ log_lines.active? person
38
48
  end
39
49
  end
40
50
  end
@@ -3,7 +3,8 @@ module PairSee
3
3
  attr_reader :date, :devs
4
4
 
5
5
  def initialize(date, *devs)
6
- @date, @devs = date, devs
6
+ @date = date
7
+ @devs = devs
7
8
  end
8
9
 
9
10
  def to_s
@@ -0,0 +1,31 @@
1
+ module PairSee
2
+ class KnowledgeDebt
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 knowledge_debt
10
+ # TODO: do something here with percentage knowledge per card
11
+ commits_per_card.map do |card_name, commits|
12
+ authors_per_commit = commits.map do |log_line|
13
+ log_line.all_authors(@people)
14
+ end
15
+ authors = authors_per_commit.flatten.uniq
16
+ CardKnowledgeSummary.new(card_name, commits.count, authors)
17
+ end.select(&:has_debt).sort_by(&:authors_list).map(&:pretty)
18
+ end
19
+
20
+ def commits_per_card
21
+ card_to_commits = {}
22
+
23
+ @log_lines.each do |ll|
24
+ cn = ll.card_number(@card_prefixes)
25
+ card_to_commits[cn] = [] unless card_to_commits[cn]
26
+ card_to_commits[cn] << ll
27
+ end
28
+ card_to_commits
29
+ end
30
+ end
31
+ end
@@ -1,29 +1,32 @@
1
1
  module PairSee
2
2
  class LogLine
3
3
  require 'time'
4
- attr_reader :line
4
+ attr_reader :line, :date, :card_number
5
5
 
6
6
  def initialize(line)
7
7
  @line = line
8
+ @date = _get_date(line)
8
9
  end
9
10
 
10
- def authored_by?(*people)
11
- return false if people.empty?
12
- people.map {|person|
13
- contains_any_of?(person.names)
14
- }.all?
15
- end
16
-
17
- def contains_any_of?(names)
18
- names.any? {|name| line_contains_name(name)}
11
+ def all_authors(people)
12
+ people.select do |person|
13
+ _contains_any_of?(person.names)
14
+ end
19
15
  end
20
16
 
21
- def line_contains_name(name)
22
- /(^|\s+|\W)#{name}(\s+|$|\W)/i =~ line
17
+ def authored_by?(*people)
18
+ return false if people.empty?
19
+ people.map do |person|
20
+ _contains_any_of?(person.names)
21
+ end.all?
23
22
  end
24
23
 
25
- def contains_card?(card_prefix)
26
- line.match(card_prefix)
24
+ def card_number(card_prefixes)
25
+ card_prefixes.each do |cp|
26
+ card_num = card_name([cp])
27
+ return card_num.gsub(cp, '') if card_num
28
+ end
29
+ nil
27
30
  end
28
31
 
29
32
  def contains_card_name?(card_name)
@@ -33,46 +36,41 @@ module PairSee
33
36
  end
34
37
 
35
38
  def card_name(card_prefixes)
36
- card_prefixes.each {|cp|
39
+ card_prefixes.each do |cp|
37
40
  regex = /(#{cp}\d+)/
38
41
  matcher = line.match(regex)
39
- if (!matcher.nil?)
40
- return (line.match regex)[1]
41
- end
42
- }
43
- return nil
42
+ return (line.match regex)[1] unless matcher.nil?
43
+ end
44
+ nil
44
45
  end
45
46
 
46
- def card_number(card_prefixes)
47
- card_prefixes.each {|cp|
48
- card_num = card_name([cp])
49
- if (card_num)
50
- return card_num.gsub(cp, '')
51
- end
52
- }
53
- return nil
47
+ def by_any?(devs)
48
+ return false if devs.empty?
49
+ devs.any? { |dev| authored_by?(dev) }
54
50
  end
55
51
 
56
- def merge_commit?
57
- line.match('Merge remote-tracking branch') || line.match('Merge branch')
52
+ def contains_card?(card_prefix)
53
+ line.match(card_prefix)
54
+ end
55
+
56
+ def to_s
57
+ line
58
58
  end
59
59
 
60
- def date
60
+ private
61
+
62
+ def _get_date(line)
61
63
  regex = /(\d{4}-\d{2}-\d{2})/
62
64
  matcher = line.match(regex)
63
- part_to_parse = matcher.nil? ? '' : (line.match regex)[1]
64
- Date.parse(part_to_parse)
65
+ Date.parse((line.match regex)[1]) unless matcher.nil?
65
66
  end
66
67
 
67
- def by_any?(devs)
68
- if devs.size == 0
69
- return false
70
- end
71
- devs.any? {|dev| authored_by?(dev)}
68
+ def _contains_any_of?(names)
69
+ names.any? { |name| _line_contains_name(name) }
72
70
  end
73
71
 
74
- def to_s
75
- line
72
+ def _line_contains_name(name)
73
+ /(^|\s+|\W)#{name}(\s+|$|\W)/i =~ line
76
74
  end
77
75
  end
78
76
  end