Class: BlockedStalledByDateBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/jirametrics/blocked_stalled_by_date_builder.rb

Overview

Rolls a stream of BlockedStalledChange entries up into a single winning entry per date across the requested date range. It's handed the already-computed stream so it never reaches back through the issue's collaborators.

Instance Method Summary collapse

Constructor Details

#initialize(blocked_stalled_changes:, date_range:) ⇒ BlockedStalledByDateBuilder

Returns a new instance of BlockedStalledByDateBuilder.



7
8
9
10
# File 'lib/jirametrics/blocked_stalled_by_date_builder.rb', line 7

def initialize blocked_stalled_changes:, date_range:
  @blocked_stalled_changes = blocked_stalled_changes
  @date_range = date_range
end

Instance Method Details

#buildObject



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/jirametrics/blocked_stalled_by_date_builder.rb', line 12

def build
  results = winners_and_last_by_date
  fill_gaps results
  results = results.transform_values(&:first)
  extrapolate_across_range results

  # We've been accumulating data for every date to keep the code simple. Now drop anything
  # that isn't in the requested date_range.
  results.select! { |date, _value| @date_range.include? date }
  results
end

#extrapolate_across_range(results) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'lib/jirametrics/blocked_stalled_by_date_builder.rb', line 55

def extrapolate_across_range results
  # The requested date range may span outside the actual changes we find in the changelog.
  date_of_first_change = @blocked_stalled_changes[0].time.to_date
  date_of_last_change = @blocked_stalled_changes[-1].time.to_date
  @date_range.each do |date|
    results[date] = @blocked_stalled_changes[0] if date < date_of_first_change
    results[date] = @blocked_stalled_changes[-1] if date > date_of_last_change
  end
end

#fill_gaps(results) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/jirametrics/blocked_stalled_by_date_builder.rb', line 43

def fill_gaps results
  last_populated_date = nil
  (results.keys.min..results.keys.max).each do |date|
    if results.key? date
      last_populated_date = date
    else
      _winner, last = results[last_populated_date]
      results[date] = [last, last]
    end
  end
end

#winners_and_last_by_dateObject

For each date we track both the winning change (the one that best represents the day) and the last change seen (used to carry state forward into days that had no changes of their own).



26
27
28
29
30
31
32
33
34
35
# File 'lib/jirametrics/blocked_stalled_by_date_builder.rb', line 26

def winners_and_last_by_date
  results = {}
  @blocked_stalled_changes.each do |change|
    date = change.time.to_date
    winning_change, = results[date]
    winning_change = change if winning_change.nil? || wins_the_day?(change, winning_change)
    results[date] = [winning_change, change]
  end
  results
end

#wins_the_day?(change, winning_change) ⇒ Boolean

Returns:

  • (Boolean)


37
38
39
40
41
# File 'lib/jirametrics/blocked_stalled_by_date_builder.rb', line 37

def wins_the_day? change, winning_change
  change.blocked? ||
    (change.active? && (winning_change.active? || winning_change.stalled?)) ||
    (change.stalled? && winning_change.stalled?)
end