lib/fugit/cron.rb in fugit-1.1.9 vs lib/fugit/cron.rb in fugit-1.1.10
- old
+ new
@@ -9,12 +9,11 @@
'@annually' => '0 0 1 1 *',
'@monthly' => '0 0 1 * *',
'@weekly' => '0 0 * * 0',
'@daily' => '0 0 * * *',
'@midnight' => '0 0 * * *',
- '@hourly' => '0 * * * *',
- }
+ '@hourly' => '0 * * * *' }
attr_reader :original, :zone
attr_reader :seconds, :minutes, :hours, :monthdays, :months, :weekdays, :timezone
class << self
@@ -47,21 +46,19 @@
end
end
def to_cron_s
- @cron_s ||= begin
- [
- @seconds == [ 0 ] ? nil : (@seconds || [ '*' ]).join(','),
- (@minutes || [ '*' ]).join(','),
- (@hours || [ '*' ]).join(','),
- (@monthdays || [ '*' ]).join(','),
- (@months || [ '*' ]).join(','),
- (@weekdays || [ [ '*' ] ]).map { |d| d.compact.join('#') }.join(','),
- @timezone ? @timezone.name : nil
- ].compact.join(' ')
- end
+ @cron_s ||= [
+ @seconds == [ 0 ] ? nil : (@seconds || [ '*' ]).join(','),
+ (@minutes || [ '*' ]).join(','),
+ (@hours || [ '*' ]).join(','),
+ (@monthdays || [ '*' ]).join(','),
+ (@months || [ '*' ]).join(','),
+ (@weekdays || [ [ '*' ] ]).map { |d| d.compact.join('#') }.join(','),
+ @timezone ? @timezone.name : nil
+ ].compact.join(' ')
end
class TimeCursor
def initialize(cron, t)
@@ -71,11 +68,11 @@
end
def time; @t; end
def to_i; @t.to_i; end
- %w[ year month day wday hour min sec wday_in_month ]
+ %w[ year month day wday hour min sec wday_in_month rweek rday ]
.collect(&:to_sym).each { |k| define_method(k) { @t.send(k) } }
def inc(i)
@t = @t + i
self
@@ -138,25 +135,39 @@
def month_match?(nt); ( ! @months) || @months.include?(nt.month); end
def hour_match?(nt); ( ! @hours) || @hours.include?(nt.hour); end
def min_match?(nt); ( ! @minutes) || @minutes.include?(nt.min); end
def sec_match?(nt); ( ! @seconds) || @seconds.include?(nt.sec); end
+ def weekday_hash_match?(nt, hsh)
+
+ phsh, nhsh = nt.wday_in_month
+
+ if hsh > 0
+ hsh == phsh # positive wday, from the beginning of the month
+ else
+ hsh == nhsh # negative wday, from the end of the month, -1 == last
+ end
+ end
+
+ def weekday_modulo_match?(nt, mod)
+
+ nt.rweek % mod[0] == mod[1]
+ end
+
def weekday_match?(nt)
return true if @weekdays.nil?
- wd, hsh = @weekdays.find { |d, _| d == nt.wday }
+ wd, hom = @weekdays.find { |d, _| d == nt.wday }
return false unless wd
- return true if hsh.nil?
+ return true if hom.nil?
- phsh, nhsh = nt.wday_in_month
-
- if hsh > 0
- hsh == phsh # positive wday, from the beginning of the month
+ if hom.is_a?(Array)
+ weekday_modulo_match?(nt, hom)
else
- hsh == nhsh # negative wday, from the end of the month, -1 == last
+ weekday_hash_match?(nt, hom)
end
end
def monthday_match?(nt)
@@ -485,15 +496,15 @@
def determine_weekdays(arr)
@weekdays = []
- arr.each do |a, z, s, h| # a to z, slash and hash
- if h
- @weekdays << [ a, h ]
- elsif s
- ((a || 0)..(z || (a ? a : 6))).step(s < 1 ? 1 : s)
+ arr.each do |a, z, sl, ha, mo| # a to z, slash, hash, and mod
+ if ha || mo
+ @weekdays << [ a, ha || mo ]
+ elsif sl
+ ((a || 0)..(z || (a ? a : 6))).step(sl < 1 ? 1 : sl)
.each { |i| @weekdays << [ i ] }
elsif z
(a..z).each { |i| @weekdays << [ i ] }
elsif a
@weekdays << [ a ]
@@ -525,24 +536,18 @@
def hyphen(i); str(nil, i, '-'); end
def comma(i); str(nil, i, ','); end
def slash(i); rex(:slash, i, /\/\d\d?/); end
- def core_mos(i); rex(:mos, i, /[0-5]?\d/); end # min or sec
- def core_hou(i); rex(:hou, i, /(2[0-4]|[01]?[0-9])/); end
- def core_dom(i); rex(:dom, i, /(-?(3[01]|[12][0-9]|0?[1-9])|last|l)/i); end
- def core_mon(i); rex(:mon, i, /(1[0-2]|0?[1-9]|#{MONTHS[1..-1].join('|')})/i); end
- def core_dow(i); rex(:dow, i, /([0-7]|#{WEEKDS.join('|')})/i); end
+ def mos(i); rex(:mos, i, /[0-5]?\d/); end # min or sec
+ def hou(i); rex(:hou, i, /(2[0-4]|[01]?[0-9])/); end
+ def dom(i); rex(:dom, i, /(-?(3[01]|[12][0-9]|0?[1-9])|last|l)/i); end
+ def mon(i); rex(:mon, i, /(1[0-2]|0?[1-9]|#{MONTHS[1..-1].join('|')})/i); end
+ def dow(i); rex(:dow, i, /([0-7]|#{WEEKDS.join('|')})/i); end
def dow_hash(i); rex(:hash, i, /#(-?[1-5]|last|l)/i); end
- def mos(i); core_mos(i); end
- def hou(i); core_hou(i); end
- def dom(i); core_dom(i); end
- def mon(i); core_mon(i); end
- def dow(i); core_dow(i); end
-
def _mos(i); seq(nil, i, :hyphen, :mos); end
def _hou(i); seq(nil, i, :hyphen, :hou); end
def _dom(i); seq(nil, i, :hyphen, :dom); end
def _mon(i); seq(nil, i, :hyphen, :mon); end
def _dow(i); seq(nil, i, :hyphen, :dow); end
@@ -566,14 +571,17 @@
def sorws_hou(i); seq(:elt, i, :sor_hou, :slash, '?'); end
def sorws_dom(i); seq(:elt, i, :sor_dom, :slash, '?'); end
def sorws_mon(i); seq(:elt, i, :sor_mon, :slash, '?'); end
def sorws_dow(i); seq(:elt, i, :sor_dow, :slash, '?'); end
- def h_dow(i); seq(:elt, i, :core_dow, :dow_hash); end
+ def mod(i); rex(:mod, i, /%\d+(\+\d+)?/); end
- def _sorws_dow(i); alt(nil, i, :h_dow, :sorws_dow); end
+ def mod_dow(i); seq(:elt, i, :dow, :mod); end
+ def h_dow(i); seq(:elt, i, :dow, :dow_hash); end
+ def _sorws_dow(i); alt(nil, i, :h_dow, :mod_dow, :sorws_dow); end
+
def list_sec(i); jseq(:sec, i, :sorws_mos, :comma); end
def list_min(i); jseq(:min, i, :sorws_mos, :comma); end
def list_hou(i); jseq(:hou, i, :sorws_hou, :comma); end
def list_dom(i); jseq(:dom, i, :sorws_dom, :comma); end
def list_mon(i); jseq(:mon, i, :sorws_mon, :comma); end
@@ -605,36 +613,51 @@
alt(:cron, i, :second_cron, :classic_cron)
end
# rewriting the parsed tree
- def to_i(k, t)
+ def rewrite_bound(k, t)
s = t.string.downcase
(k == :mon && MONTHS.index(s)) ||
(k == :dow && WEEKDS.index(s)) ||
((k == :dom) && s[0, 1] == 'l' && -1) || # L, l, last
s.to_i
end
+ def rewrite_mod(k, t)
+
+ mod, plus = t.string
+ .split(/[%+]/).reject(&:empty?).collect(&:to_i)
+
+ [ mod, plus || 0 ]
+ end
+
def rewrite_elt(k, t)
- (a, z), others = t
- .subgather(nil)
- .partition { |tt| ![ :hash, :slash ].include?(tt.name) }
- s = others.find { |tt| tt.name == :slash }
- h = others.find { |tt| tt.name == :hash }
+ at, zt, slt, hat, mot = nil; t.subgather(nil).each do |tt|
+ case tt.name
+ when :slash then slt = tt
+ when :hash then hat = tt
+ when :mod then mot = tt
+ else if at; zt ||= tt; else; at = tt; end
+ end
+ end
- h = h ? h.string[1..-1] : nil
- h = -1 if h && h.upcase[0, 1] == 'L'
- h = h.to_i if h
+ sl = slt ? slt.string[1..-1].to_i : nil
- a = a ? to_i(k, a) : nil
- z = z ? to_i(k, z) : nil
+ ha = hat ? hat.string[1..-1] : nil
+ ha = -1 if ha && ha.upcase[0, 1] == 'L'
+ ha = ha.to_i if ha
+
+ mo = mot ? rewrite_mod(k, mot) : nil
+
+ a = at ? rewrite_bound(k, at) : nil
+ z = zt ? rewrite_bound(k, zt) : nil
a, z = z, a if a && z && a > z
- [ a, z, s ? s.string[1..-1].to_i : nil, h ]
+ [ a, z, sl, ha, mo ]
end
def rewrite_entry(t)
t