sof-cycle 0.1.0 → 0.1.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 +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.
|