fugit 1.9.0 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fugit might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0099e4aa474e4886e99da33f4b76abd19f259d3a6eb64cd2bfe12f99f6256a23'
4
- data.tar.gz: 38c3fbe7b620cc6460f1b7b7d3e96298400c82d7dec7ef9d4b543925dff6e74a
3
+ metadata.gz: d32bc8cbff08c0ca8fe2c2037454ca76c208878f26d71398cd46a93729958248
4
+ data.tar.gz: ce7d21ce4265c59def186f0e28271def0b74724c99c46814443182039f26cba1
5
5
  SHA512:
6
- metadata.gz: 75e41e393e779e06ec6280e6e2065877b4771fcca8b63307af13f7fe2407fc9a1fef75eca5a690fe9f3cec6b791deaa4c8b23c925326b24753c5ae8197d5a5bd
7
- data.tar.gz: e9ac1c2b0412a9e2549257b1d73490f4319335c847a6faff212dd8c8a9cbaa52787617491d76648763efbd24caffc39a91e08f06910970905dc810ef9fec36cc
6
+ metadata.gz: fe8facb5f36dd89ec4e03994c6474f3a6e8de371f05322b8c7983d2d9d8769889b475e35a2d0bcc74fb04b59f96ca857a16ffb6a3db50db41a36beff48c57c39
7
+ data.tar.gz: d928deee88172c20c15e6960bddfd30b77f3eb7fb0e0edd322baa9ce54932fe476afc7a21985fe3cc65dff3507acd29540f88b51ae27f3e458d060f083a11628
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
  # CHANGELOG.md
3
3
 
4
4
 
5
+ ## fugit 1.10.0 released 2024-02-22
6
+
7
+ * Implement `Fugit::Cron#within(time_start, time_end)`
8
+ * Implement `Fugit::Cron#within(time_range)`
9
+ * Implement iterator-returning `Fugit::Cron#next` and `#prev`
10
+
11
+
5
12
  ## fugit 1.9.0 released 2023-10-24
6
13
 
7
14
  * Let nat parse "last", gh-88
data/LICENSE.txt CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- Copyright (c) 2017-2023, John Mettraux, jmettraux+flor@gmail.com
2
+ Copyright (c) 2017-2024, John Mettraux, jmettraux+flor@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/README.md CHANGED
@@ -26,17 +26,21 @@ The intersection of those two projects is where fugit is born:
26
26
  * [parse-cron](https://github.com/siebertm/parse-cron) - parses cron expressions and calculates the next occurrence after a given date
27
27
  * [ice_cube](https://github.com/seejohnrun/ice_cube) - Ruby date recurrence library
28
28
  * [ISO8601](https://github.com/arnau/ISO8601) - Ruby parser to work with ISO8601 dateTimes and durations
29
+ * [chrono](https://github.com/r7kamura/chrono) - a chain of logics about chronology
30
+ * [CronCalc](https://github.com/mizinsky/cron_calc) - calculates cron job occurrences
31
+ * [Recurrence](https://github.com/fnando/recurrence) - a simple library to handle recurring events
29
32
  * ...
30
33
 
31
34
  ### Projects using fugit
32
35
 
33
36
  * [arask](https://github.com/Ebbe/arask) - "Automatic RAils taSKs" uses fugit to parse cron strings
34
37
  * [sidekiq-cron](https://github.com/ondrejbartas/sidekiq-cron) - recent versions of Sidekiq-Cron use fugit to parse cron strings
35
- * [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler) -
38
+ * [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler) - as seen above
36
39
  * [flor](https://github.com/floraison/flor) - used in the [cron](https://github.com/floraison/flor/blob/master/doc/procedures/cron.md) procedure
37
40
  * [que-scheduler](https://github.com/hlascelles/que-scheduler) - a reliable job scheduler for [que](https://github.com/chanks/que)
38
41
  * [serial_scheduler](https://github.com/grosser/serial_scheduler) - ruby task scheduler without threading
39
42
  * [delayed_cron_job](https://github.com/codez/delayed_cron_job) - an extension to Delayed::Job that allows you to set cron expressions for your jobs
43
+ * [GoodJob](https://github.com/bensheldon/good_job) - a multithreaded, Postgres-based, Active Job backend for Ruby on Rails
40
44
  * ...
41
45
 
42
46
  ## `Fugit.parse(s)`
@@ -92,7 +96,7 @@ As `Fugit.parse(s)` returns nil when it doesn't grok its input, and `Fugit.do_pa
92
96
 
93
97
  Sometimes you know a cron expression or an "every" natural expression will come in and you want to discard the rest.
94
98
 
95
- ```
99
+ ```ruby
96
100
  require 'fugit'
97
101
 
98
102
  Fugit.parse_cronish('0 0 1 jan *').class # ==> ::Fugit::Cron
@@ -122,8 +126,44 @@ c = Fugit::Cron.new('0 0 * * sun')
122
126
 
123
127
  p Time.now # => 2017-01-03 09:53:27 +0900
124
128
 
125
- p c.next_time # => 2017-01-08 00:00:00 +0900
126
- p c.previous_time # => 2017-01-01 00:00:00 +0900
129
+ p c.next_time.to_s # => 2017-01-08 00:00:00 +0900
130
+ p c.previous_time.to_s # => 2017-01-01 00:00:00 +0900
131
+
132
+ p c.next_time(Time.parse('2024-06-01')).to_s
133
+ # => "2024-06-02 00:00:00 +0900"
134
+ p c.previous_time(Time.parse('2024-06-01')).to_s
135
+ # => "2024-05-26 00:00:00 +0900"
136
+ #
137
+ # `Fugit::Cron#next_time` and `#previous_time` accept a "start time"
138
+
139
+ c = Fugit.parse_cron('0 12 * * mon#2')
140
+
141
+ # `#next` and `#prev` return Enumerable instances
142
+ #
143
+ c.next(Time.parse('2024-02-16 12:00:00'))
144
+ .take(3)
145
+ .map(&:to_s)
146
+ # => [ '2024-03-11 12:00:00',
147
+ # '2024-04-08 12:00:00',
148
+ # '2024-05-13 12:00:00' ]
149
+ c.prev(Time.parse('2024-02-16 12:00:00'))
150
+ .take(3)
151
+ .map(&:to_s)
152
+ # => [ '2024-02-12 12:00:00',
153
+ # '2024-01-08 12:00:00',
154
+ # '2023-12-11 12:00:00' ]
155
+
156
+ # `#within` accepts a time range and returns an array of Eo::EoTime
157
+ # instances that correspond to the occurrences of the cron within
158
+ # the time range
159
+ #
160
+ c.within(Time.parse('2024-02-16 12:00')..Time.parse('2024-08-01 12:00'))
161
+ .map(&:to_s)
162
+ # => [ '2024-03-11 12:00:00',
163
+ # '2024-04-08 12:00:00',
164
+ # '2024-05-13 12:00:00',
165
+ # '2024-06-10 12:00:00',
166
+ # '2024-07-08 12:00:00' ]
127
167
 
128
168
  p c.brute_frequency # => [ 604800, 604800, 53 ]
129
169
  # [ delta min, delta max, occurrence count ]
@@ -268,6 +308,18 @@ c.match?('2019-01-08') # => false, since (rweek + 1) % 2 == 1
268
308
  `tue%x+y` matches if Tuesday and `current_date.rweek + y % x == 0`
269
309
 
270
310
 
311
+ ### the second extension
312
+
313
+ Fugit accepts cron strings with five elements, `minute hour day-of-month month day-of-week`, the standard cron format or six elements `second minute hour day-of-month month day-of-week`.
314
+
315
+ ```ruby
316
+ c = Fugit.parse('* * * * *') # every minute
317
+ c = Fugit.parse('5 * * * *') # every hour at minute 5
318
+ c = Fugit.parse('* * * * * *') # every second
319
+ c = Fugit.parse('5 * * * * *') # every minute at second 5
320
+ ```
321
+
322
+
271
323
  ## `Fugit::Duration`
272
324
 
273
325
  A class `Fugit::Duration` to parse duration strings (vanilla [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler) ones and [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) ones).
@@ -401,7 +453,8 @@ Fugit::Nat.parse('every day at 16:15 and 18:30', multi: true)
401
453
  # ==> [ '15 16 * * *', '30 18 * * *' ] (two Fugit::Cron instances)
402
454
 
403
455
  Fugit::Nat.parse('every day at 16:15 and 18:30', multi: :fail)
404
- # ==> ArgumentError: multiple crons in "every day at 16:15 and 18:30" (15 16 * * * | 30 18 * * *)
456
+ # ==> ArgumentError: multiple crons in "every day at 16:15 and 18:30"
457
+ # (15 16 * * * | 30 18 * * *)
405
458
  Fugit::Nat.parse('every day at 16:15 nada 18:30', multi: true)
406
459
  # ==> nil
407
460
  ```
data/lib/fugit/cron.rb CHANGED
@@ -318,6 +318,53 @@ module Fugit
318
318
  t.time.translate(from.zone)
319
319
  end
320
320
 
321
+ # Used by Fugit::Cron#next and Fugit::Cron#prev
322
+ #
323
+ class CronIterator include ::Enumerable
324
+ attr_reader :cron, :start, :current, :direction
325
+ def initialize(cron, direction, start)
326
+ @cron = cron
327
+ @start = start
328
+ @current = start.dup
329
+ @direction = direction
330
+ end
331
+ def each
332
+ loop do
333
+ yield(@current = @cron.send(@direction, @current))
334
+ end
335
+ end
336
+ end
337
+
338
+ # Returns an ::Enumerable instance that yields each "next time" in
339
+ # succession
340
+ #
341
+ def next(from=::EtOrbi::EoTime.now)
342
+
343
+ CronIterator.new(self, :next_time, from)
344
+ end
345
+
346
+ # Returns an ::Enumerable instance that yields each "previous time" in
347
+ # succession
348
+ #
349
+ def prev(from=::EtOrbi::EoTime.now)
350
+
351
+ CronIterator.new(self, :previous_time, from)
352
+ end
353
+
354
+ # Returns an array of EtOrbi::EoTime instances that correspond to
355
+ # the occurrences of the cron within the given time range
356
+ #
357
+ def within(time_range, time_end=nil)
358
+
359
+ sta, ned =
360
+ time_range.is_a?(::Range) ? [ time_range.begin, time_range.end ] :
361
+ [ ::EtOrbi.make_time(time_range), ::EtOrbi.make_time(time_end) ]
362
+
363
+ CronIterator
364
+ .new(self, :next_time, sta)
365
+ .take_while { |eot| eot.to_t < ned }
366
+ end
367
+
321
368
  # Mostly used as a #next_time sanity check.
322
369
  # Avoid for "business" use, it's slow.
323
370
  #
data/lib/fugit.rb CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Fugit
5
5
 
6
- VERSION = '1.9.0'
6
+ VERSION = '1.10.0'
7
7
  end
8
8
 
9
9
  require 'time'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fugit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-23 00:00:00.000000000 Z
11
+ date: 2024-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: raabro