rufus-scheduler 3.1.3 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.txt +5 -0
- data/CREDITS.txt +1 -0
- data/lib/rufus/scheduler.rb +1 -1
- data/lib/rufus/scheduler/cronline.rb +26 -26
- data/spec/cronline_spec.rb +193 -10
- metadata +2 -2
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
= rufus-scheduler CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-scheduler - 3.1.4 released 2015/08/29
|
6
|
+
|
7
|
+
- fix cron issue reported by Jesse https://github.com/jhw-at-prosperworks-com
|
8
|
+
|
9
|
+
|
5
10
|
== rufus-scheduler - 3.1.3 released 2015/06/20
|
6
11
|
|
7
12
|
- prevent Thread[:rufus_scheduler_time] -> nil, gh-156
|
data/CREDITS.txt
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
== Contributors
|
6
6
|
|
7
|
+
- Jesse Willet (https://github.com/jhw-at-prosperworks-com) cron vs "*/10"
|
7
8
|
- Pascal Ouellet (https://github.com/pouellet) Scheduler#timeline loop fix
|
8
9
|
- Ryan Biesemeyer (https://github.com/yaauie) ZoTime.is_timezone? on OSX
|
9
10
|
- Ketan Padegaonkar (https://github.com/ketan) .brute_frequency improvement
|
data/lib/rufus/scheduler.rb
CHANGED
@@ -186,19 +186,6 @@ class Rufus::Scheduler
|
|
186
186
|
time
|
187
187
|
end
|
188
188
|
|
189
|
-
if RUBY_VERSION >= '1.9'
|
190
|
-
def toa(item)
|
191
|
-
item == nil ? nil : item.to_a
|
192
|
-
end
|
193
|
-
else
|
194
|
-
def toi(item); item.is_a?(String) ? item.hash.abs : item.to_i; end
|
195
|
-
protected :toi
|
196
|
-
def toa(item)
|
197
|
-
item.is_a?(Set) ? item.to_a.sort_by { |e| toi(e) } : item
|
198
|
-
end
|
199
|
-
end
|
200
|
-
protected :toa
|
201
|
-
|
202
189
|
# Returns an array of 6 arrays (seconds, minutes, hours, days,
|
203
190
|
# months, weekdays).
|
204
191
|
# This method is used by the cronline unit tests.
|
@@ -228,16 +215,12 @@ class Rufus::Scheduler
|
|
228
215
|
|
229
216
|
return brute_frequency unless @seconds && @seconds.length > 1
|
230
217
|
|
231
|
-
delta = 60
|
232
218
|
secs = toa(@seconds)
|
233
|
-
prev = secs[0]
|
234
219
|
|
235
|
-
secs[1..-1].
|
220
|
+
secs[1..-1].inject([ secs[0], 60 ]) { |(prev, delta), sec|
|
236
221
|
d = sec - prev
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
delta
|
222
|
+
[ sec, d < delta ? d : delta ]
|
223
|
+
}[1]
|
241
224
|
end
|
242
225
|
|
243
226
|
# Returns the shortest delta between two potential occurences of the
|
@@ -288,13 +271,11 @@ class Rufus::Scheduler
|
|
288
271
|
delta
|
289
272
|
end
|
290
273
|
|
291
|
-
protected
|
292
|
-
|
293
274
|
def next_second(time)
|
294
275
|
|
295
|
-
secs = @seconds
|
276
|
+
secs = toa(@seconds)
|
296
277
|
|
297
|
-
return secs.
|
278
|
+
return secs.first + 60 - time.sec if time.sec > secs.last
|
298
279
|
|
299
280
|
secs.shift while secs.first < time.sec
|
300
281
|
|
@@ -303,13 +284,30 @@ class Rufus::Scheduler
|
|
303
284
|
|
304
285
|
def prev_second(time)
|
305
286
|
|
306
|
-
secs = @seconds
|
287
|
+
secs = toa(@seconds)
|
307
288
|
|
308
289
|
secs.pop while time.sec < secs.last
|
309
290
|
|
310
291
|
time.sec - secs.last
|
311
292
|
end
|
312
293
|
|
294
|
+
protected
|
295
|
+
|
296
|
+
def sc_sort(a)
|
297
|
+
|
298
|
+
a.sort_by { |e| e.is_a?(String) ? 61 : e.to_i }
|
299
|
+
end
|
300
|
+
|
301
|
+
if RUBY_VERSION >= '1.9'
|
302
|
+
def toa(item)
|
303
|
+
item == nil ? nil : item.to_a
|
304
|
+
end
|
305
|
+
else
|
306
|
+
def toa(item)
|
307
|
+
item.is_a?(Set) ? sc_sort(item.to_a) : item
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
313
311
|
WEEKDAYS = %w[ sun mon tue wed thu fri sat ]
|
314
312
|
DAY_S = 24 * 3600
|
315
313
|
WEEK_S = 7 * DAY_S
|
@@ -351,7 +349,7 @@ class Rufus::Scheduler
|
|
351
349
|
end
|
352
350
|
end
|
353
351
|
|
354
|
-
weekdays = weekdays.uniq if weekdays
|
352
|
+
weekdays = weekdays.uniq.sort if weekdays
|
355
353
|
|
356
354
|
[ weekdays, monthdays ]
|
357
355
|
end
|
@@ -366,6 +364,8 @@ class Rufus::Scheduler
|
|
366
364
|
"found duplicates in #{item.inspect}"
|
367
365
|
) if r.uniq.size < r.size
|
368
366
|
|
367
|
+
r = sc_sort(r)
|
368
|
+
|
369
369
|
Set.new(r)
|
370
370
|
end
|
371
371
|
|
data/spec/cronline_spec.rb
CHANGED
@@ -32,6 +32,10 @@ describe Rufus::Scheduler::CronLine do
|
|
32
32
|
in_zone(tz) { tu.getlocal }
|
33
33
|
end
|
34
34
|
|
35
|
+
def ns(cronline, now)
|
36
|
+
Rufus::Scheduler::CronLine.new(cronline).next_second(now)
|
37
|
+
end
|
38
|
+
|
35
39
|
def match(line, time)
|
36
40
|
expect(cl(line).matches?(time)).to eq(true)
|
37
41
|
end
|
@@ -68,20 +72,30 @@ describe Rufus::Scheduler::CronLine do
|
|
68
72
|
|
69
73
|
to_a '52 0 * * *', [ [0], [52], [0], nil, nil, nil, nil, nil ]
|
70
74
|
|
71
|
-
if ruby18?
|
72
|
-
|
73
|
-
else
|
74
|
-
|
75
|
-
end
|
75
|
+
#if ruby18?
|
76
|
+
# to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
|
77
|
+
#else
|
78
|
+
# to_a '0 23-24 * * *', [ [0], [0], [23, 0], nil, nil, nil, nil, nil ]
|
79
|
+
#end
|
76
80
|
#
|
77
81
|
# as reported by Aimee Rose in
|
78
82
|
# https://github.com/jmettraux/rufus-scheduler/issues/56
|
83
|
+
to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
|
79
84
|
|
80
|
-
if ruby18?
|
81
|
-
|
82
|
-
else
|
83
|
-
|
84
|
-
end
|
85
|
+
#if ruby18?
|
86
|
+
# to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
|
87
|
+
#else
|
88
|
+
# to_a '0 23-2 * * *', [ [0], [0], [23, 0, 1, 2], nil, nil, nil, nil, nil ]
|
89
|
+
#end
|
90
|
+
to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
|
91
|
+
|
92
|
+
# modulo forms work for five-field forms
|
93
|
+
to_a '*/17 * * * *', [[0], [0, 17, 34, 51], nil, nil, nil, nil, nil, nil]
|
94
|
+
to_a '13 */17 * * *', [[0], [13], [0, 17], nil, nil, nil, nil, nil]
|
95
|
+
|
96
|
+
# modulo forms work for six-field forms
|
97
|
+
to_a '*/17 * * * * *', [[0, 17, 34, 51], nil, nil, nil, nil, nil, nil, nil]
|
98
|
+
to_a '13 */17 * * * *', [[13], [0, 17, 34, 51], nil, nil, nil, nil, nil, nil]
|
85
99
|
end
|
86
100
|
|
87
101
|
it 'rejects invalid weekday expressions' do
|
@@ -215,6 +229,36 @@ describe Rufus::Scheduler::CronLine do
|
|
215
229
|
# as reported by Aimee Rose in
|
216
230
|
# https://github.com/jmettraux/rufus-scheduler/pull/58
|
217
231
|
end
|
232
|
+
|
233
|
+
it 'sorts seconds' do
|
234
|
+
|
235
|
+
to_a(
|
236
|
+
'23,30,10 * * * * *', [ [10,23,30], nil, nil, nil, nil, nil, nil, nil ])
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'sorts minutes' do
|
240
|
+
|
241
|
+
to_a(
|
242
|
+
'23,30,10 * * * * ', [ [0], [10,23,30], nil, nil, nil, nil, nil, nil ])
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'sorts days' do
|
246
|
+
|
247
|
+
to_a(
|
248
|
+
'* * 14,7 * * ', [ [0], nil, nil, [7, 14], nil, nil, nil, nil ])
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'sorts months' do
|
252
|
+
|
253
|
+
to_a(
|
254
|
+
'* * * 11,3,4 * ', [ [0], nil, nil, nil, [3,4,11], nil, nil, nil ])
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'sorts days of week' do
|
258
|
+
|
259
|
+
to_a(
|
260
|
+
'* * * * Sun,Fri,2 ', [ [0], nil, nil, nil, nil, [0, 2, 5], nil, nil ])
|
261
|
+
end
|
218
262
|
end
|
219
263
|
|
220
264
|
describe '#next_time' do
|
@@ -363,6 +407,55 @@ describe Rufus::Scheduler::CronLine do
|
|
363
407
|
)
|
364
408
|
).to eq(ltz('America/New_York', 2015, 3, 9, 2, 0, 0))
|
365
409
|
end
|
410
|
+
|
411
|
+
it 'understands six-field crontabs' do
|
412
|
+
|
413
|
+
expect(nt('* * * * * *',local(1970,1,1,1,1,1))).to(
|
414
|
+
eq(local(1970,1,1,1,1,2))
|
415
|
+
)
|
416
|
+
expect(nt('* * * * * *',local(1970,1,1,1,1,2))).to(
|
417
|
+
eq(local(1970,1,1,1,1,3))
|
418
|
+
)
|
419
|
+
expect(nt('*/10 * * * * *',local(1970,1,1,1,1,0))).to(
|
420
|
+
eq(local(1970,1,1,1,1,10))
|
421
|
+
)
|
422
|
+
expect(nt('*/10 * * * * *',local(1970,1,1,1,1,9))).to(
|
423
|
+
eq(local(1970,1,1,1,1,10))
|
424
|
+
)
|
425
|
+
expect(nt('*/10 * * * * *',local(1970,1,1,1,1,10))).to(
|
426
|
+
eq(local(1970,1,1,1,1,20))
|
427
|
+
)
|
428
|
+
expect(nt('*/10 * * * * *',local(1970,1,1,1,1,40))).to(
|
429
|
+
eq(local(1970,1,1,1,1,50))
|
430
|
+
)
|
431
|
+
expect(nt('*/10 * * * * *',local(1970,1,1,1,1,49))).to(
|
432
|
+
eq(local(1970,1,1,1,1,50))
|
433
|
+
)
|
434
|
+
expect(nt('*/10 * * * * *',local(1970,1,1,1,1,50))).to(
|
435
|
+
eq(local(1970,1,1,1,2,00)) # FAILS: skips a minute to 2:50, not 2:00
|
436
|
+
)
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
describe '#next_second' do
|
441
|
+
[
|
442
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1, 0), 0 ], # 0 sec to 0s mark
|
443
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1, 1), 9 ], # 9 sec to 10s mark
|
444
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1, 9), 1 ], # 1 sec to 10s mark
|
445
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1,10), 0 ], # 0 sec to 10s mark
|
446
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1,11), 9 ], # 9 sec to 20s mark
|
447
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1,19), 1 ], # 1 sec to 20s mark
|
448
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1,20), 0 ], # 0 sec to 20s mark
|
449
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1,21), 9 ], # 1 sec to 30s mark
|
450
|
+
# ...
|
451
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1,49), 1 ], # 9 sec to 50s mark
|
452
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1,50), 0 ], # 0 sec to 50s mark
|
453
|
+
[ '*/10 * * * * *', local(1970,1,1,1,1,51), 9 ], # FAILS: gives 59
|
454
|
+
].each do |cronline,now,sec|
|
455
|
+
it "understands that next_second('#{cronline}',#{now}) is #{sec}" do
|
456
|
+
expect(ns(cronline,now)).to eq(sec)
|
457
|
+
end
|
458
|
+
end
|
366
459
|
end
|
367
460
|
|
368
461
|
describe '#previous_time' do
|
@@ -417,6 +510,20 @@ describe Rufus::Scheduler::CronLine do
|
|
417
510
|
)
|
418
511
|
).to eq(ltz('America/New_York', 2015, 3, 9, 2, 0, 0))
|
419
512
|
end
|
513
|
+
|
514
|
+
it 'computes correctly when * 0,10,20' do
|
515
|
+
|
516
|
+
expect(
|
517
|
+
pt('* 0,10,20 * * *', lo(2000, 1, 1))).to eq(
|
518
|
+
lo(1999, 12, 31, 20, 59, 00))
|
519
|
+
end
|
520
|
+
|
521
|
+
it 'computes correctly when * */10' do
|
522
|
+
|
523
|
+
expect(
|
524
|
+
pt('* */10 * * *', lo(2000, 1, 1))).to eq(
|
525
|
+
lo(1999, 12, 31, 20, 59, 00))
|
526
|
+
end
|
420
527
|
end
|
421
528
|
|
422
529
|
describe '#matches?' do
|
@@ -543,6 +650,46 @@ describe Rufus::Scheduler::CronLine do
|
|
543
650
|
expect(Rufus::Scheduler::CronLine.new(
|
544
651
|
'10,20,30 * * * * *').frequency).to eq(10)
|
545
652
|
end
|
653
|
+
|
654
|
+
it 'spots B-A vs C-B asymmetry in five-field forms' do
|
655
|
+
|
656
|
+
expect(Rufus::Scheduler::CronLine.new(
|
657
|
+
'10,17,30 * * * *').frequency).to eq(7 * 60)
|
658
|
+
expect(Rufus::Scheduler::CronLine.new(
|
659
|
+
'10,23,30 * * * *').frequency).to eq(7 * 60)
|
660
|
+
expect(Rufus::Scheduler::CronLine.new(
|
661
|
+
'23,10,30 * * * *').frequency).to eq(7 * 60)
|
662
|
+
end
|
663
|
+
|
664
|
+
it 'spots B-A vs C-B asymmetry in six-field forms' do
|
665
|
+
|
666
|
+
expect(Rufus::Scheduler::CronLine.new(
|
667
|
+
'10,17,30 * * * * *').frequency).to eq(7)
|
668
|
+
expect(Rufus::Scheduler::CronLine.new(
|
669
|
+
'10,23,30 * * * * *').frequency).to eq(7)
|
670
|
+
expect(Rufus::Scheduler::CronLine.new(
|
671
|
+
'23,10,30 * * * * *').frequency).to eq(7)
|
672
|
+
end
|
673
|
+
|
674
|
+
it 'handles crontab steps syntax in five-field forms' do
|
675
|
+
|
676
|
+
expect(Rufus::Scheduler::CronLine.new(
|
677
|
+
'*/10 * * * *').frequency).to eq(10 * 60)
|
678
|
+
expect(Rufus::Scheduler::CronLine.new(
|
679
|
+
'* */10 * * *').frequency).to eq(60) # "*" all minutes [0..59]
|
680
|
+
expect(Rufus::Scheduler::CronLine.new(
|
681
|
+
'0 */10 * * *').frequency).to eq(4 * 60 * 60) # 2000 to 0000
|
682
|
+
end
|
683
|
+
|
684
|
+
it 'handles crontab steps syntax in six-field forms' do
|
685
|
+
|
686
|
+
expect(Rufus::Scheduler::CronLine.new(
|
687
|
+
'*/10 * * * * *').frequency).to eq(10)
|
688
|
+
expect(Rufus::Scheduler::CronLine.new(
|
689
|
+
'* */10 * * * *').frequency).to eq(1) # "*" all seconds [0..59]
|
690
|
+
expect(Rufus::Scheduler::CronLine.new(
|
691
|
+
'0 */10 * * * *').frequency).to eq(10 * 60)
|
692
|
+
end
|
546
693
|
end
|
547
694
|
|
548
695
|
describe '#brute_frequency' do
|
@@ -574,6 +721,42 @@ describe Rufus::Scheduler::CronLine do
|
|
574
721
|
expect(Rufus::Scheduler::CronLine.new(
|
575
722
|
'1 2 3 4 5').brute_frequency).to eq(31622400)
|
576
723
|
end
|
724
|
+
|
725
|
+
it 'spots B-A vs C-B asymmetry in five-field forms' do
|
726
|
+
|
727
|
+
expect(Rufus::Scheduler::CronLine.new(
|
728
|
+
'10,17,30 * * * *').brute_frequency).to eq(7 * 60)
|
729
|
+
expect(Rufus::Scheduler::CronLine.new(
|
730
|
+
'10,23,30 * * * *').brute_frequency).to eq(7 * 60)
|
731
|
+
end
|
732
|
+
|
733
|
+
it 'spots B-A vs C-B asymmetry in six-field forms' do
|
734
|
+
|
735
|
+
expect(Rufus::Scheduler::CronLine.new(
|
736
|
+
'10,17,30 * * * * *').brute_frequency).to eq(7)
|
737
|
+
expect(Rufus::Scheduler::CronLine.new(
|
738
|
+
'10,23,30 * * * * *').brute_frequency).to eq(7)
|
739
|
+
end
|
740
|
+
|
741
|
+
it 'handles crontab modulo syntax in five-field forms' do
|
742
|
+
|
743
|
+
expect(Rufus::Scheduler::CronLine.new(
|
744
|
+
'*/10 * * * *').brute_frequency).to eq(10 * 60)
|
745
|
+
expect(Rufus::Scheduler::CronLine.new(
|
746
|
+
'* */10 * * *').brute_frequency).to eq(60) # "*" all minutes [0..59]
|
747
|
+
expect(Rufus::Scheduler::CronLine.new(
|
748
|
+
'0 */10 * * *').brute_frequency).to eq(4 * 60 * 60) # 2000 to 0000
|
749
|
+
end
|
750
|
+
|
751
|
+
it 'handles crontab modulo syntax in six-field forms' do
|
752
|
+
|
753
|
+
expect(Rufus::Scheduler::CronLine.new(
|
754
|
+
'*/10 * * * * *').brute_frequency).to eq(10)
|
755
|
+
expect(Rufus::Scheduler::CronLine.new(
|
756
|
+
'* */10 * * * *').brute_frequency).to eq(1) # "*" all seconds [0..59]
|
757
|
+
expect(Rufus::Scheduler::CronLine.new(
|
758
|
+
'0 */10 * * * *').brute_frequency).to eq(10 * 60)
|
759
|
+
end
|
577
760
|
end
|
578
761
|
|
579
762
|
context 'summer time' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-08-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|