Module: Railbow::Calendar

Defined in:
lib/railbow/calendar.rb

Overview

Turns an ordered list of migration versions into the calendar furniture that gives the status table its shape: a separator row when the month changes, optionally one when the ISO week changes, and optionally a tick mark on the date column at each week boundary.

A separator introduces the rows beneath it and runs until the next separator, so the optional count always answers "how many migrations in this section".

Defined Under Namespace

Classes: Furniture

Constant Summary collapse

DEFAULT_MONTH_LABEL =
"%b %Y   W%V"
DEFAULT_WEEK_LABEL =

Week rows carry the month too, so the week number sits at the same offset on every separator row rather than jumping left when the month is absent.

DEFAULT_MONTH_LABEL

Class Method Summary collapse

Class Method Details

.append_counts(separators, total) ⇒ Object



76
77
78
79
80
81
82
# File 'lib/railbow/calendar.rb', line 76

def append_counts(separators, total)
  indices = separators.keys.sort
  indices.each_with_index do |index, nth|
    section_end = indices[nth + 1] || total
    separators[index] = "#{separators[index]} ยท #{migration_count(section_end - index)}"
  end
end

.build(versions, weeks: false, ticks: false, counts: false, month_label: DEFAULT_MONTH_LABEL, week_label: DEFAULT_WEEK_LABEL) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/railbow/calendar.rb', line 36

def build(versions, weeks: false, ticks: false, counts: false,
  month_label: DEFAULT_MONTH_LABEL, week_label: DEFAULT_WEEK_LABEL)
  dates = versions.map { |v| parse_date(v) }
  furniture = none

  dates.each_with_index do |date, i|
    prev = (i > 0) ? dates[i - 1] : nil
    next unless date && prev

    opens_week = week_key(prev) != week_key(date)

    if month_key(prev) != month_key(date)
      furniture.separators[i] = date.strftime(month_label)
    elsif weeks && opens_week
      furniture.separators[i] = date.strftime(week_label)
    end

    furniture.tick_rows << i if ticks && opens_week
  end

  append_counts(furniture.separators, dates.size) if counts
  furniture
end

.migration_count(count) ⇒ Object

Spelled out: a bare number next to a week label reads as part of the date.



85
86
87
# File 'lib/railbow/calendar.rb', line 85

def migration_count(count)
  "#{count} #{(count == 1) ? "migration" : "migrations"}"
end

.month_key(date) ⇒ Object



67
68
69
# File 'lib/railbow/calendar.rb', line 67

def month_key(date)
  [date.year, date.month]
end

.noneObject



32
33
34
# File 'lib/railbow/calendar.rb', line 32

def none
  Furniture.new
end

.parse_date(version) ⇒ Object



60
61
62
63
64
65
# File 'lib/railbow/calendar.rb', line 60

def parse_date(version)
  v = version.to_s
  Date.new(v[0..3].to_i, v[4..5].to_i, v[6..7].to_i)
rescue Date::Error
  nil
end

.week_key(date) ⇒ Object

cwyear, not year: the ISO week of Jan 1 can belong to the year before.



72
73
74
# File 'lib/railbow/calendar.rb', line 72

def week_key(date)
  [date.cwyear, date.cweek]
end