Module: Wheneverd::Systemd::CronParser::DowParser

Defined in:
lib/wheneverd/systemd/cron_parser/dow_parser.rb

Overview

Parses and formats day-of-week cron field expressions.

Day-of-week has specialized handling:

  • Both 0 and 7 represent Sunday
  • Wrap-around ranges (e.g., Fri-Mon)
  • Formatting to systemd's Mon..Fri syntax

Constant Summary collapse

DOW_NAMES =
{
  "sun" => 0,
  "mon" => 1,
  "tue" => 2,
  "wed" => 3,
  "thu" => 4,
  "fri" => 5,
  "sat" => 6
}.freeze
DOW_SYSTEMD =
{
  0 => "Sun",
  1 => "Mon",
  2 => "Tue",
  3 => "Wed",
  4 => "Thu",
  5 => "Fri",
  6 => "Sat"
}.freeze
DOW_ORDER =

Day order for formatting (Mon-Sun instead of Sun-Sat)

[1, 2, 3, 4, 5, 6, 0].freeze

Class Method Summary collapse

Class Method Details

.format(days) ⇒ String

Formats a set of days into a systemd-compatible expression.

Parameters:

  • days (Array<Integer>)

    array of day numbers (0-6)

Returns:

  • (String)

    systemd expression (e.g., "Mon..Fri", "Mon,Wed,Fri")



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/wheneverd/systemd/cron_parser/dow_parser.rb', line 63

def self.format(days)
  present = Array.new(7, false)
  days.each { |day| present[day] = true }

  tokens = []
  i = 0
  while i < DOW_ORDER.length
    day = DOW_ORDER.fetch(i)
    unless present.fetch(day)
      i += 1
      next
    end

    start = day
    j = i
    j += 1 while (j + 1) < DOW_ORDER.length && present.fetch(DOW_ORDER.fetch(j + 1))
    finish = DOW_ORDER.fetch(j)

    token = format_range(start, finish)
    tokens << token
    i = j + 1
  end

  tokens.join(",")
end

.parse(dow_str, input:) ⇒ Array<Integer>?

Parses a day-of-week field into a set of days.

Parameters:

  • dow_str (String)

    the day-of-week field value

  • input (String)

    full cron expression for error messages

Returns:

  • (Array<Integer>, nil)

    array of day numbers (0-6), or nil if all days

Raises:



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/wheneverd/systemd/cron_parser/dow_parser.rb', line 42

def self.parse(dow_str, input:)
  raw = dow_str.to_s.strip
  raise_empty_error(input) if raw.empty?
  return nil if raw == "*"

  present = Array.new(7, false)

  raw.split(",").map(&:strip).each do |part|
    apply_part(present, part, input: input)
  end

  days = present.each_index.select { |idx| present[idx] }
  return nil if days.length == 7

  days
end