Skip to content

Restore support for Ruby 2.7 – Ruby 3.1#561

Merged
bastelfreak merged 1 commit into
voxpupuli:masterfrom
koic:restore_support_for_ruby_2_7_to_3_1
Feb 11, 2026
Merged

Restore support for Ruby 2.7 – Ruby 3.1#561
bastelfreak merged 1 commit into
voxpupuli:masterfrom
koic:restore_support_for_ruby_2_7_to_3_1

Conversation

@koic

@koic koic commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Unlike applications, libraries provide value by remaining usable for a broad range of users, even when that means supporting older Ruby versions beyond Ruby's own EOL timeline.

I maintain RuboCop, a Ruby linter. Because linters need to work across the ecosystem, they often need to keep compatibility with older Ruby versions to some extent.

For the MCP Ruby SDK, which depends on the json-schema gem, I would like to support Ruby 2.7, which RuboCop still supports. To make that possible, the json-schema gem also needs to support Ruby 2.7.
modelcontextprotocol/ruby-sdk#206

The trade-off is that json-schema development would be limited to features available in Ruby 2.7+. However, since json-schema is widely used, supporting Ruby 2.7 is likely to be worthwhile.

For example, bundled gems such as csv (Ruby >= 2.5), bigdecimal (Ruby >= 2.5), json (Ruby >= 2.7), and language_server-protocol (Ruby >= 2.5) tend to keep compatibility with older Ruby versions.

Unlike dropping support, which imposes restrictions on users, this change broadens compatibility and doesn't introduce breaking changes.

Development Note

voxpupuli-rubocop supports Ruby 3.2+, but this PR does not change that. Since RuboCop can configure the runtime Ruby version and the target Ruby version for analysis independently, CI will continue to run RuboCop on Ruby 3.2+, as before.

Due to Bundler's dependency resolution behavior, the add_development_dependency entries in the gemspec have been moved to the Gemfile. Dependency flow needs to be controlled from the Gemfile, which cannot be done from the gemspec.

In addition, when setting TargetRubyVersion: 2.7 for RuboCop, the following RuboCop offenses were resolved.

$ bundle exec rubocop
(snip)

Offenses:

lib/json-schema.rb:17:1: W: [Correctable] Lint/NonDeterministicRequireOrder: Sort files before requiring them.
Dir[File.join(File.dirname(__FILE__), 'json-schema/attributes/**/*.rb')].each { |file| require file }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lib/json-schema/attributes/formats/date.rb:6:16: C: [Correctable] Style/MutableConstant: Freeze mutable objects assigned to constants.
      REGEXP = /\A\d{4}-\d{2}-\d{2}\z/
               ^^^^^^^^^^^^^^^^^^^^^^^
lib/json-schema/attributes/formats/date_time.rb:6:16: C: [Correctable] Style/MutableConstant: Freeze mutable objects assigned to constants.
      REGEXP = /\A\d{4}-\d{2}-\d{2}T(\d{2}):(\d{2}):(\d{2})([.,]\d+)?(Z|[+-](\d{2})(:?\d{2})?)?\z/
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lib/json-schema/attributes/formats/time.rb:6:16: C: [Correctable] Style/MutableConstant: Freeze mutable objects assigned to constants.
      REGEXP = /\A(\d{2}):(\d{2}):(\d{2})\z/
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test/support/test_helper.rb:9:1: W: [Correctable] Lint/NonDeterministicRequireOrder: Sort files before requiring them.
Dir[File.join(File.expand_path(__dir__), '*.rb')].each do |support_file|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

120 files inspected, 5 offenses detected, 5 offenses autocorrectable

@ekohl ekohl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with a wider compatibility range for libraries. The code changes are actually tiny and not clunky/complex.

@ekohl ekohl added the enhancement New feature or request label Jan 5, 2026
@ekohl

ekohl commented Jan 5, 2026

Copy link
Copy Markdown
Member

To elaborate a bit: IMHO dropping support for older versions should only be done if it reduces the maintenance burden in a non-trivial way.

I'm leaving this open for a bit so other maintainers can also weigh in.

@bastelfreak

Copy link
Copy Markdown
Member

@koic can you rebase against our latest master branch please? Can you estimate how long you need the Ruby 2.7 support?

## Summary

Unlike applications, libraries provide value by remaining usable for a broad range of users,
even when that means supporting older Ruby versions beyond Ruby's own EOL timeline.

I maintain RuboCop, a Ruby linter. Because linters need to work across the ecosystem,
they often need to keep compatibility with older Ruby versions to some extent.

For the MCP Ruby SDK, which depends on the `json-schema` gem, I would like to support Ruby 2.7,
which RuboCop still supports. To make that possible, the `json-schema` gem also needs to support Ruby 2.7.
modelcontextprotocol/ruby-sdk#206

The trade-off is that `json-schema` development would be limited to features available in Ruby 2.7+.
However, since `json-schema` is widely used, supporting Ruby 2.7 is likely to be worthwhile.

For example, bundled gems such as `csv` (Ruby >= 2.5), `bigdecimal` (Ruby >= 2.5), `json` (Ruby >= 2.7),
and `language_server-protocol` (Ruby >= 2.5) tend to keep compatibility with older Ruby versions.

Unlike dropping support, which imposes restrictions on users, this change broadens compatibility and
doesn't introduce breaking changes.

## Development Note

`voxpupuli-rubocop` supports Ruby 3.2+, but this PR does not change that.
Since RuboCop can configure the runtime Ruby version and the target Ruby version for analysis independently,
CI will continue to run RuboCop on Ruby 3.2+, as before.

Due to Bundler's dependency resolution behavior, the `add_development_dependency` entries in the gemspec have been moved to the Gemfile.
Dependency flow needs to be controlled from the Gemfile, which cannot be done from the gemspec.

In addition, when setting `TargetRubyVersion: 2.7` for RuboCop, the following RuboCop offenses were resolved.

```console
$ bundle exec rubocop
(snip)

Offenses:

lib/json-schema.rb:17:1: W: [Correctable] Lint/NonDeterministicRequireOrder: Sort files before requiring them.
Dir[File.join(File.dirname(__FILE__), 'json-schema/attributes/**/*.rb')].each { |file| require file }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lib/json-schema/attributes/formats/date.rb:6:16: C: [Correctable] Style/MutableConstant: Freeze mutable objects assigned to constants.
      REGEXP = /\A\d{4}-\d{2}-\d{2}\z/
               ^^^^^^^^^^^^^^^^^^^^^^^
lib/json-schema/attributes/formats/date_time.rb:6:16: C: [Correctable] Style/MutableConstant: Freeze mutable objects assigned to constants.
      REGEXP = /\A\d{4}-\d{2}-\d{2}T(\d{2}):(\d{2}):(\d{2})([.,]\d+)?(Z|[+-](\d{2})(:?\d{2})?)?\z/
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lib/json-schema/attributes/formats/time.rb:6:16: C: [Correctable] Style/MutableConstant: Freeze mutable objects assigned to constants.
      REGEXP = /\A(\d{2}):(\d{2}):(\d{2})\z/
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test/support/test_helper.rb:9:1: W: [Correctable] Lint/NonDeterministicRequireOrder: Sort files before requiring them.
Dir[File.join(File.expand_path(__dir__), '*.rb')].each do |support_file|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

120 files inspected, 5 offenses detected, 5 offenses autocorrectable
```
@koic koic force-pushed the restore_support_for_ruby_2_7_to_3_1 branch from 863b917 to dbf0f97 Compare January 20, 2026 07:30
@koic

koic commented Jan 20, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I've rebased the changes.

It’s hard to make a definitive statement about how long support for older Ruby versions such as Ruby 2.7 should be maintained, but the more widely used a gem is, the stronger the case becomes for supporting a broader range of Ruby versions. As a reference point, the recently added development dependency minitest_reporters_github also appears to support Ruby 2.7 and above.
https://rubygems.org/gems/minitest_reporters_github/versions/1.1.0

As far as I know, Ruby 2.7 is still actively used in runtime, so continuing Ruby 2.7 support for a while seems reasonable. Recently, there have also been requests for Ruby 2.7 runtime support for the mcp gem that uses this json-schema gem.
modelcontextprotocol/ruby-sdk#206 (comment)

Realistically, the following comment from @ekohl seems to capture the point well:

To elaborate a bit: IMHO dropping support for older versions should only be done if it reduces the maintenance burden in a non-trivial way.

@koic

koic commented Jan 20, 2026

Copy link
Copy Markdown
Contributor Author

The Ruby 4.0 CI build failure is expected to be resolved in theforeman/minitest_reporters_github#7 and is unrelated to the changes in this PR.

@bastelfreak bastelfreak merged commit b718bc4 into voxpupuli:master Feb 11, 2026
22 of 24 checks passed
@koic koic deleted the restore_support_for_ruby_2_7_to_3_1 branch February 11, 2026 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants