diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 1bdc783e..50e69854 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -42,8 +42,57 @@ jobs: - lint strategy: matrix: - rails: ['7.2', '8.0', '8.1'] - ruby: ['3.2', '3.3', '3.4', '4.0'] + rails: ['6.1', '7.0', '7.1', '7.2', '8.0', '8.1'] + ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4', '4.0'] + exclude: + # Rails 6.1: Only supports Ruby 2.6-3.0 + - rails: '6.1' + ruby: '3.1' + - rails: '6.1' + ruby: '3.2' + - rails: '6.1' + ruby: '3.3' + - rails: '6.1' + ruby: '3.4' + - rails: '6.1' + ruby: '4.0' + # Rails 7.0 & 7.1: Require Ruby 2.7+, tested up to 3.3 + - rails: '7.0' + ruby: '2.6' + - rails: '7.0' + ruby: '3.4' + - rails: '7.0' + ruby: '4.0' + - rails: '7.1' + ruby: '2.6' + - rails: '7.1' + ruby: '3.4' + - rails: '7.1' + ruby: '4.0' + # Rails 7.2: Requires Ruby 3.1+ + - rails: '7.2' + ruby: '2.6' + - rails: '7.2' + ruby: '2.7' + - rails: '7.2' + ruby: '3.0' + # Rails 8.0 & 8.1: Require Ruby 3.2+ + - rails: '8.0' + ruby: '2.6' + - rails: '8.0' + ruby: '2.7' + - rails: '8.0' + ruby: '3.0' + - rails: '8.0' + ruby: '3.1' + - rails: '8.1' + ruby: '2.6' + - rails: '8.1' + ruby: '2.7' + - rails: '8.1' + ruby: '3.0' + - rails: '8.1' + ruby: '3.1' runs-on: ubuntu-latest env: RAILS_VERSION: ${{ matrix.rails }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b6dcae2..1799db44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for BYSETPOS with all rule frequencies (yearly, monthly, weekly, daily, hourly, minutely, secondly). ([#449](https://github.com/ice-cube-ruby/ice_cube/pull/449)) by [@nehresma](https://github.com/nehresma) and [@NicolasMarlier](https://github.com/NicolasMarlier) ### Changed -- Updated CI test matrix to support Rails 7.2, 8.0, 8.1 and Ruby 3.2, 3.3, 3.4, 4.0 by [@nehresma](https://github.com/nehresma) and [@pacso](https://github.com/pacso) +- Updated CI test matrix to support Rails 7.2, 8.0, 8.1 and Ruby 3.2, 3.3, 3.4, 4.0. ([#565](https://github.com/ice-cube-ruby/ice_cube/pull/565)) by [@nehresma](https://github.com/nehresma) and [@pacso](https://github.com/pacso) +- Added backwards compatibility for Ruby 2.6+ by replacing anonymous block arguments with explicit block parameters and adding Rails/Ruby version compatibility exclusions in CI test matrix. ([#562](https://github.com/ice-cube-ruby/ice_cube/pull/562)) by [@scpike](https://github.com/scpike) ## [0.17.0] - 2024-07-18 ### Added diff --git a/lib/ice_cube/input_alignment.rb b/lib/ice_cube/input_alignment.rb index 2cb14c1b..3cdd5070 100644 --- a/lib/ice_cube/input_alignment.rb +++ b/lib/ice_cube/input_alignment.rb @@ -8,16 +8,16 @@ def initialize(rule, value, rule_part) attr_reader :rule, :value, :rule_part - def verify(freq, options = {}, &) + def verify(freq, options = {}, &block) @rule.validations[:interval] or return case @rule when DailyRule - verify_wday_alignment(freq, &) + verify_wday_alignment(freq, &block) when MonthlyRule - verify_month_alignment(freq, &) + verify_month_alignment(freq, &block) else - verify_freq_alignment(freq, &) + verify_freq_alignment(freq, &block) end end diff --git a/lib/ice_cube/parsers/yaml_parser.rb b/lib/ice_cube/parsers/yaml_parser.rb index 2b979811..0a02c422 100644 --- a/lib/ice_cube/parsers/yaml_parser.rb +++ b/lib/ice_cube/parsers/yaml_parser.rb @@ -7,7 +7,12 @@ class YamlParser < HashParser attr_reader :hash def initialize(yaml) - @hash = YAML.safe_load(yaml, permitted_classes: [Date, Symbol, Time], aliases: true) + # Ruby 2.6-3.0 use positional args, Ruby 3.1+ uses keyword args for YAML.safe_load + @hash = if RUBY_VERSION < "3.1" + YAML.safe_load(yaml, [Date, Symbol, Time], [], true) + else + YAML.safe_load(yaml, permitted_classes: [Date, Symbol, Time], aliases: true) + end yaml.match SERIALIZED_START do |match| start_time = hash[:start_time] || hash[:start_date] TimeUtil.restore_deserialized_offset start_time, match[:tz] diff --git a/lib/ice_cube/rule.rb b/lib/ice_cube/rule.rb index 98d7e1fb..5e53bf20 100644 --- a/lib/ice_cube/rule.rb +++ b/lib/ice_cube/rule.rb @@ -36,13 +36,18 @@ def self.from_ical(ical) end # Yaml implementation - def to_yaml(*) - YAML.dump(to_hash, *) + def to_yaml(*args) + YAML.dump(to_hash, *args) end # From yaml def self.from_yaml(yaml) - from_hash YAML.safe_load(yaml, permitted_classes: [Date, Symbol, Time]) + # Ruby 2.6-3.0 use positional args, Ruby 3.1+ uses keyword args for YAML.safe_load + if RUBY_VERSION < "3.1" + from_hash YAML.safe_load(yaml, [Date, Symbol, Time]) + else + from_hash YAML.safe_load(yaml, permitted_classes: [Date, Symbol, Time]) + end end def to_hash diff --git a/lib/ice_cube/schedule.rb b/lib/ice_cube/schedule.rb index c7d9c75c..00fd2479 100644 --- a/lib/ice_cube/schedule.rb +++ b/lib/ice_cube/schedule.rb @@ -160,8 +160,8 @@ def all_occurrences_enumerator end # Iterate forever - def each_occurrence(&) - enumerate_occurrences(start_time, &).to_a + def each_occurrence(&block) + enumerate_occurrences(start_time, &block).to_a self end diff --git a/spec/examples/serialization_spec.rb b/spec/examples/serialization_spec.rb index 5583c23b..1d21cf8f 100644 --- a/spec/examples/serialization_spec.rb +++ b/spec/examples/serialization_spec.rb @@ -15,7 +15,12 @@ let(:start_time) { Time.now.in_time_zone("America/Vancouver") } it "serializes time as a Hash" do - hash = YAML.safe_load(yaml, permitted_classes: [Symbol, Time]) + # Ruby 2.6-3.0 use positional args, Ruby 3.1+ uses keyword args for YAML.safe_load + hash = if RUBY_VERSION < "3.1" + YAML.safe_load(yaml, [Symbol, Time]) + else + YAML.safe_load(yaml, permitted_classes: [Symbol, Time]) + end expect(hash[:start_time][:time]).to eq start_time.utc expect(hash[:start_time][:zone]).to eq "America/Vancouver" end diff --git a/spec/examples/to_yaml_spec.rb b/spec/examples/to_yaml_spec.rb index de7336cb..24bc1bd9 100644 --- a/spec/examples/to_yaml_spec.rb +++ b/spec/examples/to_yaml_spec.rb @@ -375,8 +375,14 @@ module IceCube symbol_yaml = Schedule.from_hash(symbol_data).to_yaml string_yaml = Schedule.from_hash(string_data).to_yaml - expect(YAML.safe_load(symbol_yaml, permitted_classes: [Symbol, Time])) - .to eq(YAML.safe_load(string_yaml, permitted_classes: [Symbol, Time])) + # Ruby 2.6-3.0 use positional args, Ruby 3.1+ uses keyword args for YAML.safe_load + if RUBY_VERSION < "3.1" + expect(YAML.safe_load(symbol_yaml, [Symbol, Time])) + .to eq(YAML.safe_load(string_yaml, [Symbol, Time])) + else + expect(YAML.safe_load(symbol_yaml, permitted_classes: [Symbol, Time])) + .to eq(YAML.safe_load(string_yaml, permitted_classes: [Symbol, Time])) + end end it "should raise an ArgumentError when trying to deserialize an invalid rule type" do