sof-cycle 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +6 -1
- data/Rakefile +1 -1
- data/checksums/sof-cycle-0.1.0.gem.sha512 +1 -0
- data/checksums/sof-cycle-0.1.1.gem.sha512 +1 -0
- data/lib/sof/cycle/version.rb +1 -1
- data/lib/sof/cycle.rb +7 -149
- data/lib/sof/cycles/calendar.rb +40 -0
- data/lib/sof/cycles/dormant.rb +36 -0
- data/lib/sof/cycles/end_of.rb +37 -0
- data/lib/sof/cycles/lookback.rb +41 -0
- data/lib/sof/cycles/volume_only.rb +29 -0
- data/lib/sof/cycles/within.rb +24 -0
- data/lib/sof/{cycle/parser.rb → parser.rb} +8 -8
- data/lib/sof/{cycle/time_span.rb → time_span.rb} +1 -7
- data/lib/sof-cycle.rb +16 -0
- metadata +13 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a371875b67c2b91bcda00cd042bfa8f4daed5c0ecdbdff66b5680f546b039435
|
4
|
+
data.tar.gz: 720805643f533158704ad8316a95f0cf1d31b02681a4a7654a4e859951216242
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48aa749e3b0c8a8c810d8e863025af1dadc964348f4f98670f03fade2da9aded8be063c2fe7893ee50b3f9836de3658dc93137a8c41fa9e7afd33e8a51e8c3b3
|
7
|
+
data.tar.gz: 18148c4e037cd7edd5749ac2c216d13e63ac581065a2a6d45101947dfa5b9d041e611bbc64d36d20336c846cc0272c7eb3eeb077831372661de1512d2f0e3f2c
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [0.1.1] - 2024-08-09
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- Basic example in README.md
|
13
|
+
- Add `Cycles::EndOf` to handle cycles that cover through the end of the nth
|
14
|
+
subsequent period
|
15
|
+
- Add predicate methods for each `Cycle` subclass. E.g. `#dormant?`, `#within?`, etc
|
16
|
+
- Refactor into namespaces
|
17
|
+
|
8
18
|
## [0.1.0] - 2024-07-09
|
9
19
|
|
10
20
|
### Added
|
data/README.md
CHANGED
@@ -14,7 +14,12 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
14
14
|
|
15
15
|
## Usage
|
16
16
|
|
17
|
-
|
17
|
+
```ruby
|
18
|
+
cycle = SOF::Cycle.load({ volume: 3, kind: :lookback, period: :day, period_count: 3 })
|
19
|
+
cycle.to_h # => { volume: 3, kind: :lookback, period: :day, period_count: 3 }
|
20
|
+
cycle.notation # => "V3L3D"
|
21
|
+
cycle.to_s # => "3x in the prior 3 days"
|
22
|
+
```
|
18
23
|
|
19
24
|
## Development
|
20
25
|
|
data/Rakefile
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
9a87a33268363c7f7afbb084677ff7e37c9b1102992b8082cac7529cfb3871fc92e8218d14de218a04b26afb415505286a76f948094b3cd5032b52dcf81645c6
|
@@ -0,0 +1 @@
|
|
1
|
+
53766201b732ae80e67079d1efeda25c86f144cc59c1aed2a210a8d068a689409bfd1fc0e6be7b769ae15500c3224d2c5c7854385ac84b60e44a54f94bb22c65
|
data/lib/sof/cycle/version.rb
CHANGED
data/lib/sof/cycle.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
4
|
-
require "forwardable"
|
5
|
-
require_relative "cycle/parser"
|
6
|
-
require_relative "cycle/time_span"
|
7
|
-
require "active_support/core_ext/date/conversions"
|
8
|
-
require "active_support/core_ext/string/filters"
|
3
|
+
require_relative "parser"
|
9
4
|
|
10
5
|
module SOF
|
11
6
|
class Cycle
|
@@ -32,6 +27,8 @@ module SOF
|
|
32
27
|
:humanized_period, :period_key, :active?] => :@parser
|
33
28
|
delegate [:kind, :volume_only?, :valid_periods] => "self.class"
|
34
29
|
delegate [:period_count, :duration] => :time_span
|
30
|
+
delegate [:calendar?, :dormant?, :end_of?, :lookback?, :volume_only?,
|
31
|
+
:within?] => :kind_inquiry
|
35
32
|
|
36
33
|
# Turn a cycle or notation string into a hash
|
37
34
|
def self.dump(cycle_or_string)
|
@@ -83,7 +80,7 @@ module SOF
|
|
83
80
|
# @return [Cycle] a Cycle object representing the provide string notation
|
84
81
|
def self.for(notation)
|
85
82
|
return notation if notation.is_a? Cycle
|
86
|
-
return notation if notation.is_a?
|
83
|
+
return notation if notation.is_a? Cycles::Dormant
|
87
84
|
parser = Parser.new(notation)
|
88
85
|
unless parser.valid?
|
89
86
|
raise InvalidInput, "'#{notation}' is not a valid input"
|
@@ -94,7 +91,7 @@ module SOF
|
|
94
91
|
end.new(notation, parser:)
|
95
92
|
return cycle if parser.active?
|
96
93
|
|
97
|
-
|
94
|
+
Cycles::Dormant.new(cycle, parser:)
|
98
95
|
end
|
99
96
|
|
100
97
|
# Return the appropriate class for the give notation id
|
@@ -150,6 +147,8 @@ module SOF
|
|
150
147
|
ERR
|
151
148
|
end
|
152
149
|
|
150
|
+
def kind_inquiry = ActiveSupport::StringInquirer.new(kind.to_s)
|
151
|
+
|
153
152
|
def validate_period
|
154
153
|
return if valid_periods.empty?
|
155
154
|
|
@@ -208,146 +207,5 @@ module SOF
|
|
208
207
|
end
|
209
208
|
|
210
209
|
def as_json(...) = notation
|
211
|
-
|
212
|
-
class Dormant
|
213
|
-
def initialize(cycle, parser:)
|
214
|
-
@cycle = cycle
|
215
|
-
@parser = parser
|
216
|
-
end
|
217
|
-
|
218
|
-
attr_reader :cycle, :parser
|
219
|
-
|
220
|
-
def to_s
|
221
|
-
cycle.to_s + " (dormant)"
|
222
|
-
end
|
223
|
-
|
224
|
-
def covered_dates(...) = []
|
225
|
-
|
226
|
-
def expiration_of(...) = nil
|
227
|
-
|
228
|
-
def satisfied_by?(...) = false
|
229
|
-
|
230
|
-
def cover?(...) = false
|
231
|
-
|
232
|
-
def method_missing(method, ...) = cycle.send(method, ...)
|
233
|
-
|
234
|
-
def respond_to_missing?(method, include_private = false)
|
235
|
-
cycle.respond_to?(method, include_private)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
class Within < self
|
240
|
-
@volume_only = false
|
241
|
-
@notation_id = "W"
|
242
|
-
@kind = :within
|
243
|
-
@valid_periods = %w[D W M Y]
|
244
|
-
|
245
|
-
def to_s = "#{volume}x within #{date_range}"
|
246
|
-
|
247
|
-
def date_range
|
248
|
-
return humanized_span unless active?
|
249
|
-
|
250
|
-
[start_date, final_date].map { _1.to_fs(:american) }.join(" - ")
|
251
|
-
end
|
252
|
-
|
253
|
-
def final_date(_ = nil) = time_span.end_date(start_date)
|
254
|
-
|
255
|
-
def start_date(_ = nil) = from_date.to_date
|
256
|
-
end
|
257
|
-
|
258
|
-
class VolumeOnly < self
|
259
|
-
@volume_only = true
|
260
|
-
@notation_id = nil
|
261
|
-
@kind = :volume_only
|
262
|
-
@valid_periods = []
|
263
|
-
|
264
|
-
class << self
|
265
|
-
def handles?(sym) = sym.nil? || super
|
266
|
-
|
267
|
-
def validate_period(period)
|
268
|
-
raise InvalidPeriod, <<~ERR.squish unless period.nil?
|
269
|
-
Invalid period value of '#{period}' provided. Valid periods are:
|
270
|
-
#{valid_periods.join(", ")}
|
271
|
-
ERR
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
def to_s = "#{volume}x total"
|
276
|
-
|
277
|
-
def covered_dates(dates, ...) = dates
|
278
|
-
|
279
|
-
def cover?(...) = true
|
280
|
-
end
|
281
|
-
|
282
|
-
class Lookback < self
|
283
|
-
@volume_only = false
|
284
|
-
@notation_id = "L"
|
285
|
-
@kind = :lookback
|
286
|
-
@valid_periods = %w[D W M Y]
|
287
|
-
|
288
|
-
def to_s = "#{volume}x in the prior #{period_count} #{humanized_period}"
|
289
|
-
|
290
|
-
def volume_to_delay_expiration(completion_dates, anchor:)
|
291
|
-
oldest_relevant_completion = completion_dates.min
|
292
|
-
[completion_dates.count(oldest_relevant_completion), volume].min
|
293
|
-
end
|
294
|
-
|
295
|
-
# "Absent further completions, you go red on this date"
|
296
|
-
# @return [Date, nil] the date on which the cycle will expire given the
|
297
|
-
# provided completion dates. Returns nil if the cycle is already unsatisfied.
|
298
|
-
def expiration_of(completion_dates)
|
299
|
-
anchor = completion_dates.max_by(volume) { _1 }.min
|
300
|
-
return unless satisfied_by?(completion_dates, anchor:)
|
301
|
-
|
302
|
-
window_end anchor
|
303
|
-
end
|
304
|
-
|
305
|
-
def final_date(anchor)
|
306
|
-
return if anchor.nil?
|
307
|
-
|
308
|
-
time_span.end_date(anchor.to_date)
|
309
|
-
end
|
310
|
-
alias_method :window_end, :final_date
|
311
|
-
|
312
|
-
def start_date(anchor)
|
313
|
-
time_span.begin_date(anchor.to_date)
|
314
|
-
end
|
315
|
-
alias_method :window_start, :start_date
|
316
|
-
end
|
317
|
-
|
318
|
-
class Calendar < self
|
319
|
-
@volume_only = false
|
320
|
-
@notation_id = "C"
|
321
|
-
@kind = :calendar
|
322
|
-
@valid_periods = %w[M Q Y]
|
323
|
-
|
324
|
-
class << self
|
325
|
-
def frame_of_reference = "total"
|
326
|
-
end
|
327
|
-
|
328
|
-
def to_s
|
329
|
-
"#{volume}x every #{period_count} calendar #{humanized_period}"
|
330
|
-
end
|
331
|
-
|
332
|
-
# "Absent further completions, you go red on this date"
|
333
|
-
# @return [Date, nil] the date on which the cycle will expire given the
|
334
|
-
# provided completion dates. Returns nil if the cycle is already unsatisfied.
|
335
|
-
def expiration_of(completion_dates)
|
336
|
-
anchor = completion_dates.max_by(volume) { _1 }.min
|
337
|
-
return unless satisfied_by?(completion_dates, anchor:)
|
338
|
-
|
339
|
-
window_end(anchor) + duration
|
340
|
-
end
|
341
|
-
|
342
|
-
def final_date(anchor)
|
343
|
-
return if anchor.nil?
|
344
|
-
time_span.end_date_of_period(anchor.to_date)
|
345
|
-
end
|
346
|
-
alias_method :window_end, :final_date
|
347
|
-
|
348
|
-
def start_date(anchor)
|
349
|
-
time_span.begin_date_of_period(anchor.to_date)
|
350
|
-
end
|
351
|
-
end
|
352
210
|
end
|
353
211
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SOF
|
4
|
+
module Cycles
|
5
|
+
class Calendar < Cycle
|
6
|
+
@volume_only = false
|
7
|
+
@notation_id = "C"
|
8
|
+
@kind = :calendar
|
9
|
+
@valid_periods = %w[M Q Y]
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def frame_of_reference = "total"
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
"#{volume}x every #{period_count} calendar #{humanized_period}"
|
17
|
+
end
|
18
|
+
|
19
|
+
# "Absent further completions, you go red on this date"
|
20
|
+
# @return [Date, nil] the date on which the cycle will expire given the
|
21
|
+
# provided completion dates. Returns nil if the cycle is already unsatisfied.
|
22
|
+
def expiration_of(completion_dates)
|
23
|
+
anchor = completion_dates.max_by(volume) { _1 }.min
|
24
|
+
return unless satisfied_by?(completion_dates, anchor:)
|
25
|
+
|
26
|
+
window_end(anchor) + duration
|
27
|
+
end
|
28
|
+
|
29
|
+
def final_date(anchor)
|
30
|
+
return if anchor.nil?
|
31
|
+
time_span.end_date_of_period(anchor.to_date)
|
32
|
+
end
|
33
|
+
alias_method :window_end, :final_date
|
34
|
+
|
35
|
+
def start_date(anchor)
|
36
|
+
time_span.begin_date_of_period(anchor.to_date)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SOF
|
4
|
+
module Cycles
|
5
|
+
class Dormant
|
6
|
+
def initialize(cycle, parser:)
|
7
|
+
@cycle = cycle
|
8
|
+
@parser = parser
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :cycle, :parser
|
12
|
+
|
13
|
+
def kind = :dormant
|
14
|
+
|
15
|
+
def dormant? = true
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
cycle.to_s + " (dormant)"
|
19
|
+
end
|
20
|
+
|
21
|
+
def covered_dates(...) = []
|
22
|
+
|
23
|
+
def expiration_of(...) = nil
|
24
|
+
|
25
|
+
def satisfied_by?(...) = false
|
26
|
+
|
27
|
+
def cover?(...) = false
|
28
|
+
|
29
|
+
def method_missing(method, ...) = cycle.send(method, ...)
|
30
|
+
|
31
|
+
def respond_to_missing?(method, include_private = false)
|
32
|
+
cycle.respond_to?(method, include_private)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SOF
|
4
|
+
module Cycles
|
5
|
+
class EndOf < Cycle
|
6
|
+
@volume_only = false
|
7
|
+
@notation_id = "E"
|
8
|
+
@kind = :end_of
|
9
|
+
@valid_periods = %w[W M Q Y]
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
return dormant_to_s if dormant?
|
13
|
+
|
14
|
+
"#{volume}x by #{final_date.to_fs(:american)}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def final_date(_ = nil) = time_span
|
18
|
+
.end_date(start_date)
|
19
|
+
.end_of_month
|
20
|
+
|
21
|
+
def start_date(_ = nil) = from_date.to_date
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def dormant_to_s
|
26
|
+
<<~DESC.squish
|
27
|
+
#{volume}x by the last day of the #{subsequent_ordinal}
|
28
|
+
subsequent #{period}
|
29
|
+
DESC
|
30
|
+
end
|
31
|
+
|
32
|
+
def subsequent_ordinal
|
33
|
+
ActiveSupport::Inflector.ordinalize(period_count - 1)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SOF
|
4
|
+
module Cycles
|
5
|
+
class Lookback < Cycle
|
6
|
+
@volume_only = false
|
7
|
+
@notation_id = "L"
|
8
|
+
@kind = :lookback
|
9
|
+
@valid_periods = %w[D W M Y]
|
10
|
+
|
11
|
+
def to_s = "#{volume}x in the prior #{period_count} #{humanized_period}"
|
12
|
+
|
13
|
+
def volume_to_delay_expiration(completion_dates, anchor:)
|
14
|
+
oldest_relevant_completion = completion_dates.min
|
15
|
+
[completion_dates.count(oldest_relevant_completion), volume].min
|
16
|
+
end
|
17
|
+
|
18
|
+
# "Absent further completions, you go red on this date"
|
19
|
+
# @return [Date, nil] the date on which the cycle will expire given the
|
20
|
+
# provided completion dates. Returns nil if the cycle is already unsatisfied.
|
21
|
+
def expiration_of(completion_dates)
|
22
|
+
anchor = completion_dates.max_by(volume) { _1 }.min
|
23
|
+
return unless satisfied_by?(completion_dates, anchor:)
|
24
|
+
|
25
|
+
window_end anchor
|
26
|
+
end
|
27
|
+
|
28
|
+
def final_date(anchor)
|
29
|
+
return if anchor.nil?
|
30
|
+
|
31
|
+
time_span.end_date(anchor.to_date)
|
32
|
+
end
|
33
|
+
alias_method :window_end, :final_date
|
34
|
+
|
35
|
+
def start_date(anchor)
|
36
|
+
time_span.begin_date(anchor.to_date)
|
37
|
+
end
|
38
|
+
alias_method :window_start, :start_date
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SOF
|
4
|
+
module Cycles
|
5
|
+
class VolumeOnly < Cycle
|
6
|
+
@volume_only = true
|
7
|
+
@notation_id = nil
|
8
|
+
@kind = :volume_only
|
9
|
+
@valid_periods = []
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def handles?(sym) = sym.nil? || super
|
13
|
+
|
14
|
+
def validate_period(period)
|
15
|
+
raise InvalidPeriod, <<~ERR.squish unless period.nil?
|
16
|
+
Invalid period value of '#{period}' provided. Valid periods are:
|
17
|
+
#{valid_periods.join(", ")}
|
18
|
+
ERR
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s = "#{volume}x total"
|
23
|
+
|
24
|
+
def covered_dates(dates, ...) = dates
|
25
|
+
|
26
|
+
def cover?(...) = true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SOF
|
4
|
+
module Cycles
|
5
|
+
class Within < Cycle
|
6
|
+
@volume_only = false
|
7
|
+
@notation_id = "W"
|
8
|
+
@kind = :within
|
9
|
+
@valid_periods = %w[D W M Y]
|
10
|
+
|
11
|
+
def to_s = "#{volume}x within #{date_range}"
|
12
|
+
|
13
|
+
def date_range
|
14
|
+
return humanized_span unless active?
|
15
|
+
|
16
|
+
[start_date, final_date].map { _1.to_fs(:american) }.join(" - ")
|
17
|
+
end
|
18
|
+
|
19
|
+
def final_date(_ = nil) = time_span.end_date(start_date)
|
20
|
+
|
21
|
+
def start_date(_ = nil) = from_date.to_date
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "cycle"
|
4
4
|
require "active_support/core_ext/hash/keys"
|
5
5
|
require "active_support/core_ext/object/blank"
|
6
6
|
require "active_support/core_ext/object/inclusion"
|
@@ -10,22 +10,22 @@ require "active_support/isolated_execution_state"
|
|
10
10
|
module SOF
|
11
11
|
# This class is not intended to be referenced directly.
|
12
12
|
# This is an internal implementation of Cycle behavior.
|
13
|
-
class
|
13
|
+
class Parser
|
14
14
|
extend Forwardable
|
15
15
|
PARTS_REGEX = /
|
16
16
|
^(?<vol>V(?<volume>\d*))? # optional volume
|
17
|
-
(?<set>(?<kind>L|C|W) # kind
|
17
|
+
(?<set>(?<kind>L|C|W|E) # kind
|
18
18
|
(?<period_count>\d+) # period count
|
19
19
|
(?<period_key>D|W|M|Q|Y)?)? # period_key
|
20
20
|
(?<from>F(?<from_date>\d{4}-\d{2}-\d{2}))?$ # optional from
|
21
21
|
/ix
|
22
22
|
|
23
|
-
def self.dormant_capable_kinds = %w[W]
|
23
|
+
def self.dormant_capable_kinds = %w[E W]
|
24
24
|
|
25
|
-
def self.for(
|
26
|
-
return
|
25
|
+
def self.for(notation_or_parser)
|
26
|
+
return notation_or_parser if notation_or_parser.is_a? self
|
27
27
|
|
28
|
-
new(
|
28
|
+
new(notation_or_parser)
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.load(hash)
|
@@ -50,7 +50,7 @@ module SOF
|
|
50
50
|
|
51
51
|
# Return a TimeSpan object for the period and period_count
|
52
52
|
def time_span
|
53
|
-
@time_span ||=
|
53
|
+
@time_span ||= TimeSpan.for(period_count, period_key)
|
54
54
|
end
|
55
55
|
|
56
56
|
def valid? = match.present?
|
@@ -1,15 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "../cycle"
|
4
|
-
require "active_support/deprecator"
|
5
|
-
require "active_support/deprecation"
|
6
|
-
require "active_support/core_ext/numeric/time"
|
7
|
-
require "active_support/core_ext/integer/time"
|
8
|
-
require "active_support/core_ext/string/conversions"
|
9
3
|
module SOF
|
10
4
|
# This class is not intended to be referenced directly.
|
11
5
|
# This is an internal implementation of Cycle behavior.
|
12
|
-
class
|
6
|
+
class TimeSpan
|
13
7
|
extend Forwardable
|
14
8
|
# TimeSpan objects map Cycle notations to behaviors for their periods
|
15
9
|
#
|
data/lib/sof-cycle.rb
CHANGED
@@ -1 +1,17 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
require "active_support/deprecator"
|
3
|
+
require "active_support/deprecation"
|
4
|
+
require "active_support/core_ext/numeric/time"
|
5
|
+
require "active_support/core_ext/integer/time"
|
6
|
+
require "active_support/core_ext/string/conversions"
|
7
|
+
require "active_support/core_ext/date/conversions"
|
8
|
+
require "active_support/core_ext/string/filters"
|
9
|
+
require "active_support/inflector"
|
10
|
+
require "active_support/string_inquirer"
|
11
|
+
|
12
|
+
require_relative "sof/cycle/version"
|
1
13
|
require_relative "sof/cycle"
|
14
|
+
|
15
|
+
Dir[File.join(__dir__, "sof", "cycles", "*.rb")].each { |file| require file }
|
16
|
+
|
17
|
+
require_relative "sof/time_span"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sof-cycle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Gay
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: forwardable
|
@@ -50,11 +50,19 @@ files:
|
|
50
50
|
- CHANGELOG.md
|
51
51
|
- README.md
|
52
52
|
- Rakefile
|
53
|
+
- checksums/sof-cycle-0.1.0.gem.sha512
|
54
|
+
- checksums/sof-cycle-0.1.1.gem.sha512
|
53
55
|
- lib/sof-cycle.rb
|
54
56
|
- lib/sof/cycle.rb
|
55
|
-
- lib/sof/cycle/parser.rb
|
56
|
-
- lib/sof/cycle/time_span.rb
|
57
57
|
- lib/sof/cycle/version.rb
|
58
|
+
- lib/sof/cycles/calendar.rb
|
59
|
+
- lib/sof/cycles/dormant.rb
|
60
|
+
- lib/sof/cycles/end_of.rb
|
61
|
+
- lib/sof/cycles/lookback.rb
|
62
|
+
- lib/sof/cycles/volume_only.rb
|
63
|
+
- lib/sof/cycles/within.rb
|
64
|
+
- lib/sof/parser.rb
|
65
|
+
- lib/sof/time_span.rb
|
58
66
|
homepage: https://github.com/SOFware/sof-cycle
|
59
67
|
licenses: []
|
60
68
|
metadata:
|
@@ -75,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
83
|
- !ruby/object:Gem::Version
|
76
84
|
version: '0'
|
77
85
|
requirements: []
|
78
|
-
rubygems_version: 3.
|
86
|
+
rubygems_version: 3.4.13
|
79
87
|
signing_key:
|
80
88
|
specification_version: 4
|
81
89
|
summary: Parse and interact with SOF cycle notation.
|