rufus-scheduler 3.1.10 → 3.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b6294bd5d0ba45b0ae97cd681c4a915d3f4f15d
4
- data.tar.gz: 1670414782d681e46791acd641524cde44aa8063
3
+ metadata.gz: c40e276338f283e1d434b24ff0914bb4f9e4772c
4
+ data.tar.gz: 6f675ccf7f32737bd45e96119db3f0217a9294c0
5
5
  SHA512:
6
- metadata.gz: 769cdd5e8e86acb0f4a7dfac068710a0cc12210604604cd7423ea896b9ce2bd68b4f7bd16932c9122577d1121ebc05db7e15af76403e63ff404a60e35d6c96f6
7
- data.tar.gz: cf3b2a402f6bad0411cdba7e9ce8a62021de7cd90bbfb4db321cd3b11b19af28dee9a87c3d1d481957f73a766cd84200a4eaccceb804365003f276876fb798b9
6
+ metadata.gz: 5a263aaebb6f8f434f7b1eeeb138e0e77d19dd11cb87dcb347be5543fd079e90ab4352aa3a3df297ea46fe8be76d2d25950dee02afbc427e49aab4d316fee385
7
+ data.tar.gz: 5037bcda9d0650d1404bc2c134cd3ad36e0b9fc90f95dfde27af416fb2a8794c844777ddfa42b24cbb5b07f0694c3a58b8006795321c2a3699404710c61d4860
data/CHANGELOG.txt CHANGED
@@ -2,6 +2,22 @@
2
2
  = rufus-scheduler CHANGELOG.txt
3
3
 
4
4
 
5
+ == rufus-scheduler - 3.2.1 released 2016-05-04
6
+
7
+ - accept '* * * * 5L' (last friday) (equivalent to '* * * * 5#-1')
8
+ - CronLine#to_a (#to_array aliasing to it)
9
+ - simplify .parse_duration (and trim input)
10
+ - raise on "*/0 * * * *", by https://github.com/simook
11
+ - introduce "days to end of month" in cron strings
12
+
13
+
14
+ == rufus-scheduler - 3.2.0 released 2015-12-28
15
+
16
+ - cache CronLine#brute_frequency results, gh-188 and gh-89
17
+ - "every" shift prevention by https://github.com/Korrigan
18
+ - Ruby warnings silenced by https://github.com/vivitar
19
+
20
+
5
21
  == rufus-scheduler - 3.1.10 released 2015-11-18
6
22
 
7
23
  - allow for :first_in => 0, gh-179 by https://github.com/JonMcPherson
data/CREDITS.txt CHANGED
@@ -4,6 +4,11 @@
4
4
 
5
5
  == Contributors
6
6
 
7
+ - Kyle Simukka (https://githuc.om/simook) raise on "*/0 * * * *"
8
+ - Ryan McGeary (https://github.com/rmm5t) svg badges for the readme
9
+ - Balasankar C (https://github.com/balasankarc) fix CronJob spec vs December
10
+ - Matthieu Rosinski (https://github.com/Korrigan) prevent "every" shifts
11
+ - vivitar (https://github.com/vivitar) silenced a set of Ruby warnings
7
12
  - Jon McPherson (https://github.com/JonMcPherson) :first_in => 0 back
8
13
  - Calinoiu Alexandru Nicolae (https://github.com/alexandru-calinoiu) CronLine#prev_second fix
9
14
  - Alyssa Pohahau (https://github.com/alyssa) out of DST transition specs
@@ -43,6 +48,10 @@
43
48
 
44
49
  == Feedback
45
50
 
51
+ - Anjali Sharma - https://github.com/anjali-sharma - fix typographical error
52
+ - Jonathan Campos - https://github.com/jonbcampos - negative cron day idea
53
+ - Andrey Morskov - https://github.com/accessd - fix typographical error
54
+ - Eduardo Maia - https://github.com/emaiax - rufus and the Rails console
46
55
  - Suisea - https://github.com/suisea - readme rewording
47
56
  - Radek - http://stackoverflow.com/users/250422 - gh-166
48
57
  - Patrik Ragnarsson - https://github.com/dentarg - timeout vs nil, gh-156
data/LICENSE.txt CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- Copyright (c) 2005-2015, John Mettraux, jmettraux@gmail.com
2
+ Copyright (c) 2005-2016, John Mettraux, jmettraux@gmail.com
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
data/Makefile ADDED
@@ -0,0 +1,23 @@
1
+
2
+ NAME = \
3
+ $(shell ruby -e "s = eval(File.read(Dir['*.gemspec'][0])); puts s.name")
4
+ VERSION = \
5
+ $(shell ruby -e "s = eval(File.read(Dir['*.gemspec'][0])); puts s.version")
6
+
7
+
8
+ gemspec_validate:
9
+ @echo "---"
10
+ ruby -e "s = eval(File.read(Dir['*.gemspec'].first)); p s.validate"
11
+ @echo "---"
12
+
13
+ name: gemspec_validate
14
+ @echo "$(NAME) $(VERSION)"
15
+
16
+ build: gemspec_validate
17
+ gem build $(NAME).gemspec
18
+ mkdir -p pkg
19
+ mv $(NAME)-$(VERSION).gem pkg/
20
+
21
+ push: build
22
+ gem push pkg/$(NAME)-$(VERSION).gem
23
+
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  # rufus-scheduler
3
3
 
4
- [![Build Status](https://secure.travis-ci.org/jmettraux/rufus-scheduler.png)](http://travis-ci.org/jmettraux/rufus-scheduler)
5
- [![Gem Version](https://badge.fury.io/rb/rufus-scheduler.png)](http://badge.fury.io/rb/rufus-scheduler)
4
+ [![Build Status](https://secure.travis-ci.org/jmettraux/rufus-scheduler.svg)](http://travis-ci.org/jmettraux/rufus-scheduler)
5
+ [![Gem Version](https://badge.fury.io/rb/rufus-scheduler.svg)](http://badge.fury.io/rb/rufus-scheduler)
6
6
 
7
7
  Job scheduler for Ruby (at, cron, in and every jobs).
8
8
 
@@ -10,6 +10,8 @@ Job scheduler for Ruby (at, cron, in and every jobs).
10
10
 
11
11
  Quickstart:
12
12
  ```ruby
13
+ # quickstart.rb
14
+
13
15
  require 'rufus-scheduler'
14
16
 
15
17
  scheduler = Rufus::Scheduler.new
@@ -21,6 +23,7 @@ end
21
23
  scheduler.join
22
24
  # let the current thread join the scheduler thread
23
25
  ```
26
+ (run with `ruby quickstart.rb`)
24
27
 
25
28
  Various forms of scheduling are supported:
26
29
  ```ruby
@@ -59,9 +62,10 @@ It does not persist your schedules. When the process is gone and the scheduler i
59
62
 
60
63
  ## related and similar gems
61
64
 
62
- * [whenever](https://github.com/javan/whenever) - let cron call back your Ruby code, trusted and reliable cron drives your schedule
63
- * [clockwork](https://github.com/tomykaira/clockwork) - rufus-scheduler inspired gem
64
- * [crono](https://github.com/plashchynski/crono) - an in-Rails cron scheduler
65
+ * [Whenever](https://github.com/javan/whenever) - let cron call back your Ruby code, trusted and reliable cron drives your schedule
66
+ * [Clockwork](https://github.com/tomykaira/clockwork) - rufus-scheduler inspired gem
67
+ * [Crono](https://github.com/plashchynski/crono) - an in-Rails cron scheduler
68
+ * [PerfectSched](https://github.com/treasure-data/perfectsched) - highly available distributed cron built on [Sequel](http://sequel.jeremyevans.net) and more
65
69
 
66
70
  (please note: rufus-scheduler is not a cron replacement)
67
71
 
@@ -101,12 +105,6 @@ Go read [how to report bugs effectively](http://www.chiark.greenend.org.uk/~sgta
101
105
 
102
106
  Update: [help_help.md](https://gist.github.com/jmettraux/310fed75f568fd731814) might help help you.
103
107
 
104
- ### on StackOverflow
105
-
106
- Use this [form](http://stackoverflow.com/questions/ask?tags=rufus-scheduler+ruby). It'll create a question flagged "rufus-scheduler" and "ruby".
107
-
108
- Here are the [questions tagged rufus-scheduler](http://stackoverflow.com/questions/tagged/rufus-scheduler).
109
-
110
108
  ### on IRC
111
109
 
112
110
  I sometimes haunt #ruote on freenode.net. The channel is not dedicated to rufus-scheduler, so if you ask a question, first mention it's about rufus-scheduler.
@@ -123,6 +121,10 @@ Yes, issues can be reported in [rufus-scheduler issues](https://github.com/jmett
123
121
  * [I want a refund](http://blog.nodejitsu.com/getting-refunds-on-open-source-projects)
124
122
  * [Passenger and rufus-scheduler](http://stackoverflow.com/questions/18108719/debugging-rufus-scheduler/18156180#18156180)
125
123
  * [Passenger and rufus-scheduler (2)](http://stackoverflow.com/questions/21861387/rufus-cron-job-not-working-in-apache-passenger#answer-21868555)
124
+ * [Passenger in-depth spawn methods](https://www.phusionpassenger.com/library/indepth/ruby/spawn_methods/)
125
+ * [Passenger in-depth spawn methods (smart spawning)](https://www.phusionpassenger.com/library/indepth/ruby/spawn_methods/#smart-spawning-hooks)
126
+ * [The scheduler comes up when running the Rails console](https://github.com/jmettraux/rufus-scheduler#avoid-scheduling-when-running-the-ruby-on-rails-console)
127
+ * [I don't get any of this, I just want it to work in my Rails application](#so-rails)
126
128
 
127
129
 
128
130
  ## scheduling
@@ -179,6 +181,8 @@ Interval jobs, trigger, execute and then trigger again after the interval elapse
179
181
 
180
182
  Cron jobs are based on the venerable cron utility (```man 5 crontab```). They trigger following a pattern given in (almost) the same language cron uses.
181
183
 
184
+ ####
185
+
182
186
  ### #schedule_x vs #x
183
187
 
184
188
  schedule_in, schedule_at, schedule_cron, etc will return the new Job instance.
@@ -1346,7 +1350,6 @@ Rufus::Scheduler.parse('* * * * mon#1').next_time
1346
1350
  L can be used in the "day" slot:
1347
1351
 
1348
1352
  In this example, the cronline is supposed to trigger every last day of the month at noon:
1349
-
1350
1353
  ```ruby
1351
1354
  require 'rufus-scheduler'
1352
1355
  Time.now
@@ -1355,6 +1358,21 @@ Rufus::Scheduler.parse('00 12 L * *').next_time
1355
1358
  # => 2013-10-31 12:00:00 +0900
1356
1359
  ```
1357
1360
 
1361
+ #### negative day (x days before the end of the month)
1362
+
1363
+ It's OK to pass negative values in the "day" slot:
1364
+ ```ruby
1365
+ scheduler.cron '0 0 -5 * *' do
1366
+ # do it at 00h00 5 days before the end of the month...
1367
+ end
1368
+ ```
1369
+
1370
+ Negative ranges (`-10--5-`: 10 days before the end of the month to 5 days before the end of the month) are OK, but mixed positive / negative ranges will raise an `ArgumentError`.
1371
+
1372
+ Negative ranges with increments (`-10---2/2`) are accepted as well.
1373
+
1374
+ Descending day ranges are not accepted (`10-8` or `-8--10` for example).
1375
+
1358
1376
 
1359
1377
  ## a note about timezones
1360
1378
 
@@ -1427,6 +1445,34 @@ The rufus-scheduler singleton is instantiated in the ```config/initializers/sche
1427
1445
 
1428
1446
  *Warning*: this works well with single-process Ruby servers like Webrick and Thin. Using rufus-scheduler with Passenger or Unicorn requires a bit more knowledge and tuning, gently provided by a bit of googling and reading, see [Faq](#faq) above.
1429
1447
 
1448
+ ### avoid scheduling when running the Ruby on Rails console
1449
+
1450
+ (Written in reply to https://github.com/jmettraux/rufus-scheduler/issues/186 )
1451
+
1452
+ If you don't want rufus-scheduler to kick in when running the Ruby on Rails console, you can wrap your initializer in a conditional:
1453
+
1454
+ ```ruby
1455
+ #
1456
+ # config/initializers/scheduler.rb
1457
+
1458
+ require 'rufus-scheduler'
1459
+
1460
+ s = Rufus::Scheduler.singleton
1461
+
1462
+
1463
+ unless defined?(Rails::Console)
1464
+ # only schedule when not running from the Ruby on Rails console
1465
+
1466
+ s.every '1m' do
1467
+
1468
+ Rails.logger.info "hello, it's #{Time.now}"
1469
+ Rails.logger.flush
1470
+ end
1471
+ end
1472
+ ```
1473
+
1474
+ It should work for Ruby on Rails 3 and 4.
1475
+
1430
1476
  ### rails server -d
1431
1477
 
1432
1478
  (Written in reply to https://github.com/jmettraux/rufus-scheduler/issues/165 )
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -42,8 +42,8 @@ class Rufus::Scheduler
42
42
  attr_reader :hours
43
43
  attr_reader :days
44
44
  attr_reader :months
45
+ #attr_reader :monthdays # reader defined below
45
46
  attr_reader :weekdays
46
- attr_reader :monthdays
47
47
  attr_reader :timezone
48
48
 
49
49
  def initialize(line)
@@ -67,7 +67,7 @@ class Rufus::Scheduler
67
67
  @seconds = offset == 1 ? parse_item(items[0], 0, 59) : [ 0 ]
68
68
  @minutes = parse_item(items[0 + offset], 0, 59)
69
69
  @hours = parse_item(items[1 + offset], 0, 24)
70
- @days = parse_item(items[2 + offset], 1, 31)
70
+ @days = parse_item(items[2 + offset], -30, 31)
71
71
  @months = parse_item(items[3 + offset], 1, 12)
72
72
  @weekdays, @monthdays = parse_weekdays(items[4 + offset])
73
73
 
@@ -188,9 +188,9 @@ class Rufus::Scheduler
188
188
 
189
189
  # Returns an array of 6 arrays (seconds, minutes, hours, days,
190
190
  # months, weekdays).
191
- # This method is used by the cronline unit tests.
191
+ # This method is mostly used by the cronline specs.
192
192
  #
193
- def to_array
193
+ def to_a
194
194
 
195
195
  [
196
196
  toa(@seconds),
@@ -203,6 +203,7 @@ class Rufus::Scheduler
203
203
  @timezone
204
204
  ]
205
205
  end
206
+ alias to_array to_a
206
207
 
207
208
  # Returns a quickly computed approximation of the frequency for this
208
209
  # cron line.
@@ -223,6 +224,10 @@ class Rufus::Scheduler
223
224
  }[1]
224
225
  end
225
226
 
227
+ # Caching facility. Currently only used for brute frequencies.
228
+ #
229
+ @cache = {}; class << self; attr_reader :cache; end
230
+
226
231
  # Returns the shortest delta between two potential occurences of the
227
232
  # schedule described by this cronline.
228
233
  #
@@ -239,16 +244,13 @@ class Rufus::Scheduler
239
244
  # Of course, this method can get VERY slow if you call on it a second-
240
245
  # based cronline...
241
246
  #
242
- # Since it's a rarely used method, I haven't taken the time to make it
243
- # smarter/faster.
244
- #
245
- # One obvious improvement would be to cache the result once computed...
246
- #
247
- # See https://github.com/jmettraux/rufus-scheduler/issues/89
248
- # for a discussion about this method.
249
- #
250
247
  def brute_frequency
251
248
 
249
+ key = "brute_frequency:#{@original}"
250
+
251
+ delta = self.class.cache[key]
252
+ return delta if delta
253
+
252
254
  delta = 366 * DAY_S
253
255
 
254
256
  t0 = previous_time(Time.local(2000, 1, 1))
@@ -268,7 +270,7 @@ class Rufus::Scheduler
268
270
  t0 = t1
269
271
  end
270
272
 
271
- delta
273
+ self.class.cache[key] = delta
272
274
  end
273
275
 
274
276
  def next_second(time)
@@ -318,33 +320,33 @@ class Rufus::Scheduler
318
320
 
319
321
  return nil if item == '*'
320
322
 
321
- items = item.downcase.split(',')
322
-
323
323
  weekdays = nil
324
324
  monthdays = nil
325
325
 
326
- items.each do |it|
326
+ item.downcase.split(',').each do |it|
327
+
328
+ WEEKDAYS.each_with_index { |a, i| it.gsub!(/#{a}/, i.to_s) }
327
329
 
328
- if m = it.match(/^(.+)#(l|-?[12345])$/)
330
+ it = it.gsub(/([^#])l/, '\1#-1')
331
+ # "5L" == "5#-1" == the last Friday
332
+
333
+ if m = it.match(/\A(.+)#(l|-?[12345])\z/)
329
334
 
330
335
  fail ArgumentError.new(
331
336
  "ranges are not supported for monthdays (#{it})"
332
337
  ) if m[1].index('-')
333
338
 
334
- expr = it.gsub(/#l/, '#-1')
339
+ it = it.gsub(/#l/, '#-1')
335
340
 
336
- (monthdays ||= []) << expr
341
+ (monthdays ||= []) << it
337
342
 
338
343
  else
339
344
 
340
- expr = it.dup
341
- WEEKDAYS.each_with_index { |a, i| expr.gsub!(/#{a}/, i.to_s) }
342
-
343
345
  fail ArgumentError.new(
344
- "invalid weekday expression (#{it})"
345
- ) if expr !~ /^0*[0-7](-0*[0-7])?$/
346
+ "invalid weekday expression (#{item})"
347
+ ) if it !~ /\A0*[0-7](-0*[0-7])?\z/
346
348
 
347
- its = expr.index('-') ? parse_range(expr, 0, 7) : [ Integer(expr) ]
349
+ its = it.index('-') ? parse_range(it, 0, 7) : [ Integer(it) ]
348
350
  its = its.collect { |i| i == 7 ? 0 : i }
349
351
 
350
352
  (weekdays ||= []).concat(its)
@@ -371,13 +373,13 @@ class Rufus::Scheduler
371
373
  Set.new(r)
372
374
  end
373
375
 
374
- RANGE_REGEX = /^(\*|\d{1,2})(?:-(\d{1,2}))?(?:\/(\d{1,2}))?$/
376
+ RANGE_REGEX = /\A(\*|-?\d{1,2})(?:-(-?\d{1,2}))?(?:\/(\d{1,2}))?\z/
375
377
 
376
378
  def parse_range(item, min, max)
377
379
 
378
380
  return %w[ L ] if item == 'L'
379
381
 
380
- item = '*' + item if item.match(/^\//)
382
+ item = '*' + item if item[0, 1] == '/'
381
383
 
382
384
  m = item.match(RANGE_REGEX)
383
385
 
@@ -385,8 +387,10 @@ class Rufus::Scheduler
385
387
  "cannot parse #{item.inspect}"
386
388
  ) unless m
387
389
 
390
+ mmin = min == -30 ? 1 : min # days
391
+
388
392
  sta = m[1]
389
- sta = sta == '*' ? min : sta.to_i
393
+ sta = sta == '*' ? mmin : sta.to_i
390
394
 
391
395
  edn = m[2]
392
396
  edn = edn ? edn.to_i : sta
@@ -395,16 +399,28 @@ class Rufus::Scheduler
395
399
  inc = m[3]
396
400
  inc = inc ? inc.to_i : 1
397
401
 
402
+ fail ArgumentError.new(
403
+ "#{item.inspect} positive/negative ranges not allowed"
404
+ ) if (sta < 0 && edn > 0) || (sta > 0 && edn < 0)
405
+
406
+ fail ArgumentError.new(
407
+ "#{item.inspect} descending day ranges not allowed"
408
+ ) if min == -30 && sta > edn
409
+
398
410
  fail ArgumentError.new(
399
411
  "#{item.inspect} is not in range #{min}..#{max}"
400
412
  ) if sta < min || edn > max
401
413
 
414
+ fail ArgumentError.new(
415
+ "#{item.inspect} increment must be greater than zero"
416
+ ) if inc == 0
417
+
402
418
  r = []
403
419
  val = sta
404
420
 
405
421
  loop do
406
422
  v = val
407
- v = 0 if max == 24 && v == 24
423
+ v = 0 if max == 24 && v == 24 # hours
408
424
  r << v
409
425
  break if inc == 1 && val == edn
410
426
  val += inc
@@ -420,9 +436,19 @@ class Rufus::Scheduler
420
436
  value = time.send(accessor)
421
437
 
422
438
  return true if values.nil?
423
- return true if values.include?('L') && (time + DAY_S).day == 1
424
439
 
425
- return true if value == 0 && accessor == :hour && values.include?(24)
440
+ if accessor == :day
441
+
442
+ values.each do |v|
443
+ return true if v == 'L' && (time + DAY_S).day == 1
444
+ return true if v.to_i < 0 && (time + (1 - v) * DAY_S).day == 1
445
+ end
446
+ end
447
+
448
+ if accessor == :hour
449
+
450
+ return true if value == 0 && values.include?(24)
451
+ end
426
452
 
427
453
  values.include?(value)
428
454
  end
@@ -465,7 +491,7 @@ class Rufus::Scheduler
465
491
  neg = neg - 1
466
492
  end
467
493
 
468
- [ "#{WEEKDAYS[date.wday]}##{pos}", "#{WEEKDAYS[date.wday]}##{neg}" ]
494
+ [ "#{date.wday}##{pos}", "#{date.wday}##{neg}" ]
469
495
  end
470
496
  end
471
497
  end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -391,7 +391,7 @@ module Rufus
391
391
  attr_reader :paused_at
392
392
 
393
393
  attr_reader :first_at
394
- attr_accessor :last_at
394
+ attr_reader :last_at
395
395
  attr_accessor :times
396
396
 
397
397
  def initialize(scheduler, duration, opts, block)
@@ -543,9 +543,12 @@ module Rufus
543
543
 
544
544
  return if is_post
545
545
 
546
+ n = Time.now
547
+
546
548
  @next_time =
547
- if @first_at == nil || @first_at < Time.now
548
- (trigger_time || Time.now) + @frequency
549
+ if @first_at == nil || @first_at < n
550
+ nt = (@next_time || trigger_time || n) + @frequency
551
+ nt > n ? nt : (trigger_time || n) + @frequency
549
552
  else
550
553
  @first_at
551
554
  end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -41,7 +41,7 @@ class Rufus::Scheduler
41
41
  end
42
42
 
43
43
  #
44
- # The standard flock mecha, with its own class thanks to @ecin
44
+ # The standard flock mechanism, with its own class thanks to @ecin
45
45
  #
46
46
  class FileLock
47
47
 
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -125,38 +125,24 @@ module Rufus
125
125
  #
126
126
  def self.parse_duration(string, opts={})
127
127
 
128
- string = string.to_s
128
+ s = string.to_s.strip
129
+ mod = s[0, 1] == '-' ? -1 : 1
130
+ s = s[1..-1] if mod == -1
129
131
 
130
- return 0.0 if string == ''
132
+ ss = mod < 0 ? '-' : ''
133
+ r = 0.0
131
134
 
132
- m = string.match(/^(-?)([\d\.#{DURATION_LETTERS}]+)$/)
133
-
134
- return nil if m.nil? && opts[:no_error]
135
- fail ArgumentError.new("cannot parse '#{string}'") if m.nil?
136
-
137
- mod = m[1] == '-' ? -1.0 : 1.0
138
- val = 0.0
139
-
140
- s = m[2]
135
+ s.scan(/(\d*\.\d+|\d+\.?)([#{DURATION_LETTERS}]?)/) do |f, d|
136
+ ss += "#{f}#{d}"
137
+ r += f.to_f * (DURATIONS[d] || 1.0)
138
+ end
141
139
 
142
- while s.length > 0
143
- m = nil
144
- if m = s.match(/^(\d+|\d+\.\d*|\d*\.\d+)([#{DURATION_LETTERS}])(.*)$/)
145
- val += m[1].to_f * DURATIONS[m[2]]
146
- elsif s.match(/^\d+$/)
147
- val += s.to_i
148
- elsif s.match(/^\d*\.\d*$/)
149
- val += s.to_f
150
- elsif opts[:no_error]
151
- return nil
152
- else
153
- fail ArgumentError.new("cannot parse '#{string}' (especially '#{s}')")
154
- end
155
- break unless m && m[3]
156
- s = m[3]
140
+ if ss == '-' || ss != string.to_s.strip
141
+ return nil if opts[:no_error]
142
+ fail ArgumentError.new("invalid time duration #{string.inspect}")
157
143
  end
158
144
 
159
- mod * val
145
+ mod * r
160
146
  end
161
147
 
162
148
  class << self
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -85,7 +85,7 @@ class Rufus::Scheduler
85
85
  @seconds
86
86
  end
87
87
 
88
- #DELTA_TZ_REX = /^[+-][0-1][0-9]:?[0-5][0-9]$/
88
+ #DELTA_TZ_REX = /\A[+-][0-1][0-9]:?[0-5][0-9]\z/
89
89
 
90
90
  def self.envtzable?(s)
91
91
 
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -39,7 +39,7 @@ module Rufus
39
39
  require 'rufus/scheduler/job_array'
40
40
  require 'rufus/scheduler/locks'
41
41
 
42
- VERSION = '3.1.10'
42
+ VERSION = '3.2.1'
43
43
 
44
44
  #
45
45
  # A common error class for rufus-scheduler
@@ -385,7 +385,7 @@ module Rufus
385
385
  #
386
386
  def scheduled?(job_or_job_id)
387
387
 
388
- job, job_id = fetch(job_or_job_id)
388
+ job, _ = fetch(job_or_job_id)
389
389
 
390
390
  !! (job && job.unscheduled_at.nil? && job.next_time != nil)
391
391
  end
@@ -441,7 +441,7 @@ module Rufus
441
441
  if format == :timeline
442
442
  a = []
443
443
  h.each { |j, ts| ts.each { |t| a << [ t, j ] } }
444
- a.sort_by { |(t, j)| t }
444
+ a.sort_by { |(t, _)| t }
445
445
  else
446
446
  h
447
447
  end
@@ -21,14 +21,13 @@ job scheduler for Ruby (at, cron, in and every jobs).
21
21
 
22
22
  #s.files = `git ls-files`.split("\n")
23
23
  s.files = Dir[
24
- 'Rakefile',
24
+ 'Makefile',
25
25
  'lib/**/*.rb', #'spec/**/*.rb', 'test/**/*.rb',
26
26
  '*.gemspec', '*.txt', '*.rdoc', '*.md'
27
27
  ]
28
28
 
29
29
  #s.add_runtime_dependency 'tzinfo'
30
30
 
31
- s.add_development_dependency 'rake'
32
31
  s.add_development_dependency 'rspec', '>= 2.13.0'
33
32
  s.add_development_dependency 'chronic'
34
33
  s.add_development_dependency 'tzinfo'
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rufus-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.10
4
+ version: 3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-17 00:00:00.000000000 Z
11
+ date: 2016-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rake
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '>='
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '>='
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rspec
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -73,7 +59,7 @@ executables: []
73
59
  extensions: []
74
60
  extra_rdoc_files: []
75
61
  files:
76
- - Rakefile
62
+ - Makefile
77
63
  - lib/rufus/scheduler/cronline.rb
78
64
  - lib/rufus/scheduler/job_array.rb
79
65
  - lib/rufus/scheduler/jobs.rb
@@ -87,7 +73,6 @@ files:
87
73
  - CHANGELOG.txt
88
74
  - CREDITS.txt
89
75
  - LICENSE.txt
90
- - t.txt
91
76
  - TODO.txt
92
77
  - README.md
93
78
  homepage: http://github.com/jmettraux/rufus-scheduler
data/Rakefile DELETED
@@ -1,83 +0,0 @@
1
-
2
- require 'rubygems'
3
-
4
- require 'rake'
5
- require 'rake/clean'
6
- require 'rdoc/task'
7
-
8
-
9
- #
10
- # clean
11
-
12
- CLEAN.include('pkg', 'rdoc')
13
-
14
-
15
- #
16
- # test / spec
17
-
18
- #task :spec => :check_dependencies do
19
- task :spec do
20
- exec 'rspec spec/'
21
- end
22
- task :test => :spec
23
-
24
- task :default => :spec
25
-
26
-
27
- #
28
- # gem
29
-
30
- GEMSPEC_FILE = Dir['*.gemspec'].first
31
- GEMSPEC = eval(File.read(GEMSPEC_FILE))
32
- GEMSPEC.validate
33
-
34
-
35
- desc %{
36
- builds the gem and places it in pkg/
37
- }
38
- task :build do
39
-
40
- sh "gem build #{GEMSPEC_FILE}"
41
- sh "mkdir -p pkg"
42
- sh "mv #{GEMSPEC.name}-#{GEMSPEC.version}.gem pkg/"
43
- end
44
-
45
- desc %{
46
- builds the gem and pushes it to rubygems.org
47
- }
48
- task :push => :build do
49
-
50
- sh "gem push pkg/#{GEMSPEC.name}-#{GEMSPEC.version}.gem"
51
- end
52
-
53
-
54
- #
55
- # rdoc
56
- #
57
- # make sure to have rdoc 2.5.x to run that
58
-
59
- Rake::RDocTask.new do |rd|
60
-
61
- rd.main = 'README.txt'
62
- rd.rdoc_dir = "rdoc/#{GEMSPEC.name}"
63
-
64
- rd.rdoc_files.include('README.rdoc', 'CHANGELOG.txt', 'lib/**/*.rb')
65
-
66
- rd.title = "#{GEMSPEC.name} #{GEMSPEC.version}"
67
- end
68
-
69
-
70
- #
71
- # upload_rdoc
72
-
73
- desc %{
74
- upload the rdoc to rubyforge
75
- }
76
- task :upload_rdoc => [ :clean, :rdoc ] do
77
-
78
- account = 'jmettraux@rubyforge.org'
79
- webdir = '/var/www/gforge-projects/rufus'
80
-
81
- sh "rsync -azv -e ssh rdoc/#{GEMSPEC.name} #{account}:#{webdir}/"
82
- end
83
-
data/t.txt DELETED
@@ -1,31 +0,0 @@
1
-
2
- JRUBY
3
-
4
- 1) Rufus::Scheduler::CronLine fall time correctly decrements every minute through a DST transition
5
-
6
- Failure/Error: expect(points).to eq([
7
-
8
- expected: ["0101-8(0901)", "0100-8(0900)", "0159-7(0859)", "0158-7(0858)"]
9
- got: ["0101-7(0801)", "0100-7(0800)", "0059-7(0759)", "0058-7(0758)"]
10
-
11
- (compared using ==)
12
- # ./spec/cronline_spec.rb:1013:in `(root)'
13
- # ./spec/spec_helper.rb:69:in `in_zone'
14
- # ./spec/cronline_spec.rb:1001:in `(root)'
15
-
16
-
17
- RUBY1.8
18
-
19
- 1) Rufus::Scheduler::CronLine fall time correctly decrements every minute through a DST transition
20
-
21
- Failure/Error: expect(points).to eq([
22
-
23
- expected: ["0101-8(0901)", "0100-8(0900)", "0159-7(0859)", "0158-7(0858)"]
24
- got: ["0101-7(0801)", "0100-7(0800)", "0059-7(0759)", "0058-7(0758)"]
25
-
26
- (compared using ==)
27
- # ./spec/cronline_spec.rb:1013
28
- # ./spec/spec_helper.rb:69:in `call'
29
- # ./spec/spec_helper.rb:69:in `in_zone'
30
- # ./spec/cronline_spec.rb:1001
31
-