Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow suspenders to be used with a range of Ruby versions #1129

Merged

Conversation

thiagoa
Copy link
Contributor

@thiagoa thiagoa commented Jun 30, 2023

Suspenders locks the user in a particular Ruby version (3.0.5 at the time of writing), a restriction that can sometimes be annoying. This PR enables Suspenders to be used with a range of safe Ruby versions, initially from 3.0.5 to 3.2.2.

Contrary to the Rails version, the Ruby version can be more flexible if our gems are compatible. Major Rails versions, on the other hand, tend to be a bit more disruptive and may require deeper changes to Suspenders. The last main breaking change was on Ruby 3.0, but we're already past that point.

.ruby-versions was the source of truth for the canonical Ruby version, but in this PR it represents the maximum version. Unfortunately, it is still needed by CI so we can't delete it. Note that even without such a file, rubybems validates the runtime Ruby version through the gemspec.

Closes #1073

@thiagoa thiagoa force-pushed the allow-suspenders-to-be-used-with-a-range-of-ruby-versions branch 2 times, most recently from c123ecb to 3fe8dd6 Compare June 30, 2023 19:33
@thiagoa thiagoa marked this pull request as ready for review June 30, 2023 19:50
@thiagoa thiagoa requested review from mike-burns and stevepolitodesign and removed request for stevepolitodesign June 30, 2023 19:50
@@ -1,8 +1,9 @@
module Suspenders
RAILS_VERSION = "~> 7.0.0".freeze
RUBY_VERSION = IO
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm missing something: we're no longer setting RUBY_VERSION, but we still reference it from elsewhere (e.g. app_builder.rb).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mike-burns Yeah, that can be confusing. It turns out RUBY_VERSION is a global/default Ruby constant, and we were overriding it. It says which Ruby version is running. The idea is to use the global constant to set up generated applications, as long as it is within the allowed range. Does that make sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ohh, that's what I was missing. Thanks for the reminder -- yes, RUBY_VERSION!

@thiagoa thiagoa force-pushed the allow-suspenders-to-be-used-with-a-range-of-ruby-versions branch from 3fe8dd6 to 6253423 Compare June 30, 2023 21:33
@thiagoa thiagoa force-pushed the allow-suspenders-to-be-used-with-a-range-of-ruby-versions branch 2 times, most recently from c8b7907 to 6b0df2a Compare July 7, 2023 16:46
Copy link
Contributor

@stevepolitodesign stevepolitodesign left a comment

Choose a reason for hiding this comment

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

Thank you for taking care of this! I tested this locally with 3.0.5 and 3.2.2 to confirm that the upper and lower bounds work.

I also tested with an unsupported version (3.0.3) and confirmed that it exists early.

❯ ./bin/suspenders ruby_out_of_range
warning: parser/current is loading parser/ruby30, which recognizes3.0.4-compliant syntax, but you are running 3.0.3.
Please see https://github.com/whitequark/parser#compatibility-with-ruby-mri.
      create
      create  README.md
      create  Rakefile
      create  .ruby-version
      create  config.ru
      create  .gitignore
      create  .gitattributes
      create  Gemfile
         run  git init from "."
Initialized empty Git repository in /Users/polito/Sites/suspenders/ruby_out_of_range/.git/
      create  app
      create  app/assets/config/manifest.js
      create  app/assets/stylesheets/application.css
      create  app/channels/application_cable/channel.rb
      create  app/channels/application_cable/connection.rb
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/jobs/application_job.rb
      create  app/mailers/application_mailer.rb
      create  app/models/application_record.rb
      create  app/views/layouts/application.html.erb
      create  app/views/layouts/mailer.html.erb
      create  app/views/layouts/mailer.text.erb
      create  app/assets/images
      create  app/assets/images/.keep
      create  app/controllers/concerns/.keep
      create  app/models/concerns/.keep
      create  bin
      create  bin/rails
      create  bin/rake
      create  bin/setup
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/cable.yml
      create  config/puma.rb
      create  config/storage.yml
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/assets.rb
      create  config/initializers/content_security_policy.rb
      create  config/initializers/cors.rb
      create  config/initializers/filter_parameter_logging.rb
      create  config/initializers/inflections.rb
      create  config/initializers/new_framework_defaults_7_0.rb
      create  config/initializers/permissions_policy.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/master.key
      append  .gitignore
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  lib
      create  lib/tasks
      create  lib/tasks/.keep
      create  lib/assets
      create  lib/assets/.keep
      create  log
      create  log/.keep
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/apple-touch-icon-precomposed.png
      create  public/apple-touch-icon.png
      create  public/favicon.ico
      create  public/robots.txt
      create  tmp
      create  tmp/.keep
      create  tmp/pids
      create  tmp/pids/.keep
      create  tmp/cache
      create  tmp/cache/assets
      create  vendor
      create  vendor/.keep
      create  storage
      create  storage/.keep
      create  tmp/storage
      create  tmp/storage/.keep
      remove  config/initializers/cors.rb
      remove  config/initializers/new_framework_defaults_7_0.rb
       force  Gemfile
         run  bundle install
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...
Bundler found conflicting requirements for the Ruby version:
  In Gemfile:
    Ruby (~> 3.0.3.0)

    suspenders was resolved to 20230113.0, which depends on
      Ruby (>= 3.0.5, <= 3.2.2)

However, I wonder if this can be improved? Right now, Suspenders::AppGenerator.start is still invoked if the RUBY_VERSION is out of range. I wonder if we could add a guard to the executable?

#!/usr/bin/env ruby
# ...

lower_bounds = Gem::Version.new(Suspenders::RUBY_VERSION_RANGE.first)
upper_bounds = Gem::Version.new(Suspenders::RUBY_VERSION_RANGE.last)
current_ruby_version = Gem::Version.new(RUBY_VERSION)

if current_ruby_version >= lower_bounds && current_ruby_version <= upper_bounds
  Suspenders::AppGenerator.start
else
  abort "Your version of Ruby #{current_ruby_version} is not supported"
end

@thiagoa
Copy link
Contributor Author

thiagoa commented Aug 18, 2023

@stevepolitodesign Thank you, that's more user-friendly and still attains the same goal. I'll try that out.

Suspenders locks the user in a particular Ruby version (3.0.5 at the
time of writing), a restriction that can sometimes be annoying. This
PR enables Suspenders to be used with a range of safe Ruby versions,
initially from 3.0.5 to 3.2.2

Contrary to the Rails version, the Ruby version can be more flexible
if our gems are compatible. Major Rails versions, on the other hand,
tend to be a bit more disruptive and may require deeper changes to
Suspenders. [The last main breaking
change](https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/)
was on Ruby 3.0, but we're already past that point.

`.ruby-versions` was the source of truth for the canonical Ruby
version, but in this PR it represents the maximum version.
Unfortunately, it is still needed by CI so we can't delete it. Note
that even without such a file, rubybems validates the runtime Ruby
version through the gemspec.

Closes #1073
@thiagoa thiagoa force-pushed the allow-suspenders-to-be-used-with-a-range-of-ruby-versions branch from 6b0df2a to 335683e Compare August 18, 2023 19:55
@thiagoa
Copy link
Contributor Author

thiagoa commented Aug 18, 2023

@stevepolitodesign How does it look now? I thought we could check at the beginning of the script to fail as early as possible.

@stevepolitodesign
Copy link
Contributor

@stevepolitodesign How does it look now? I thought we could check at the beginning of the script to fail as early as possible.

@thiagoa thank you! I tested locally, and this works as expected.

❯ ruby -v
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [arm64-darwin21]
❯ ./bin/suspenders unsupported_version
Your version of Ruby 3.0.3 is not supported. Versions from 3.0.5 to 3.2.2 are supported.

@thiagoa thiagoa merged commit 761c413 into main Aug 21, 2023
1 check passed
@thiagoa thiagoa deleted the allow-suspenders-to-be-used-with-a-range-of-ruby-versions branch August 21, 2023 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make suspenders command smarter regarding the Ruby version
3 participants