Project

General

Profile

Actions

Misc #19352

closed

Feature #17391 was not such a good idea because now Ruby 3.2 can not install Rails v5 or v6 if they use webpacker.

Added by Milella@Hotmail.com (Scott Milella) over 1 year ago. Updated 12 months ago.

Status:
Closed
Assignee:
-
[ruby-core:111890]

Description

Hello,

I tried logging a GitHub issue to Rails to make them aware of this issue but they said they are no longer bugfixing Rails v6.1 anymore.
So since this IS a Ruby issue at its core this might be the best place for this.

You removed 2 methods from Ruby 3.2 namely:
Dir.exists? [Feature #17391]
File.exists? [Feature #17391]

The reason cited was that it was deprecated since v2 and MAYBE it might be a good idea to remove it in v3.
I disagree.
It will alienate Rails v5 and v6 from at the very least making a new rails app because when the webpacker install is called it uses one or both of those methods.
take a look at this log:

Here is what I did:

Windows 10/11
Installed prerequisites: NodeJS, Yarn, Git, SQLite3 etc.
Install Ruby on Windows using RubyInstaller v3.2.0 filename: "rubyinstaller-devkit-3.2.0-1-x64.exe"
Installed newest rails via gem install rails (installed v7.0.4.1 and it successfully installed)
Install rails via gem install rails -v 6.1.7 (successfully installed)

rails _6.1.7_ new testapp

Here is the install log around the failure point:

Bundle complete! 15 Gemfile dependencies, 78 gems now installed.
Use bundle info [gemname] to see where a bundled gem is installed.
run bundle binstubs bundler
rails webpacker:install
create config/webpacker.yml
Copying webpack core config
create config/webpack
create config/webpack/development.js
create config/webpack/environment.js
create config/webpack/production.js
create config/webpack/test.js
Copying postcss.config.js to app root directory
create postcss.config.js
Copying babel.config.js to app root directory
create babel.config.js
Copying .browserslistrc to app root directory
create .browserslistrc
rails aborted!
NoMethodError: undefined method `exists?' for Dir:Class

Tasks: TOP => app:template
(See full trace by running task with --trace)

Is there any way we can reverse the removal of those 2 methods?
Otherwise you are again alienating Rails v5 (with webpacker) and v6 which a L O T of Rails apps runs on.
Why would you want to release a new version of Ruby that PREVENTS backwards compatibility.

It does work properly on Ruby 3.1, but if you try Ruby 3.2 you will get the method error on exists?.

Thank You,
Scott

Updated by austin (Austin Ziegler) over 1 year ago

I do not believe that this should be reversed.

There’s an older post at FastRuby indicating version compatibility, which mostly captures something that I believe that I read about Rails / Ruby compatibility some time ago: the target Ruby versions are (current - 2)..(current) as of release, and any upwards compatibility with Ruby versions is either incidental or an explicit patch. So Rails 6.0 was supported on Ruby 2.5, 2.6, and 2.7 — but not Ruby 3.0 or higher. Rails 6.1 supported 2.5, 2.6, 2.7, and 3.0, but not necessarily 3.1 or higher.

Inasmuch as Rails 5.x and Rails 6.x might work on Ruby 3.2, it isn’t a recommended combination.

That said, this is easily monkey patched:

unless Dir.respond_to?(:exists?)
  class << Dir
    alias_method :exists?, :exist?
  end
end

unless File.respond_to?(:exists?)
  class << File
    alias_method :exists?, :exist?
  end
end

There might, however, be other changes which are incompatible.

Updated by aidog (Andi Idogawa) over 1 year ago

Personally, I preferred exists? over exist? but I can live with the change.
"If the file xy.txt exists then ...": if File.exists?("xy.txt") do

I made a gem to monkeypatch the exists? functionality.
The code from austin might however be a bit more elegant, so I took the liberty of incorporating that code into the gem.

https://rubygems.org/gems/file_exists
https://github.com/largo/file_exists
Related discussion: https://github.com/oneclick/rubyinstaller2/issues/331
https://stackoverflow.com/questions/48192762/did-ruby-deprecate-the-wrong-file-exists-method

Is there a way to scan all gems on rubygems to find the ones that still use exists?

Updated by Milella@Hotmail.com (Scott Milella) over 1 year ago

That said, this is easily monkey patched:

unless Dir.respond_to?(:exists?)
  class << Dir
    alias_method :exists?, :exist?
  end
end

unless File.respond_to?(:exists?)
  class << File
    alias_method :exists?, :exist?
  end
end

There might, however, be other changes which are incompatible.

@austin (Austin Ziegler), That is AWESOME! Thank you for that!

Where would be the best place for that code go? In application.rb? or as an initializer or? What would you recommend?
I am asking mostly so that if someone searches this issue out and finds this I want good instructions on how to use that code for people who may not be very far along.

Updated by austin (Austin Ziegler) over 1 year ago

I’m not entirely sure, as I have never used a version of Rails that has webpacker (I last used Rails 4.2), so I don’t know its initialization process (whether it sees application.rb or an initializer). Worst case, you could put that code in something like lib/webpacker_ruby32_compatibility_shim.rb and then do RUBYOPTS="-Ilib -rwebpacker_ruby32_compatibility_shim". How you get that part into your production environment is only something that you can answer, but for testing / verification, it should be easy enough.

Actions #5

Updated by hsbt (Hiroshi SHIBATA) over 1 year ago

  • Status changed from Open to Closed

Updated by naruse (Yui NARUSE) over 1 year ago

  • Status changed from Closed to Open

As a maintainer of ruby_3_2 branch, I'm considering to revert the removal of Dir#exists?...

Actions #7

Updated by naruse (Yui NARUSE) over 1 year ago

  • Backport changed from 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN to 2.7: DONTNEED, 3.0: DONTNEED, 3.1: DONTNEED, 3.2: REQUIRED

Updated by hsbt (Hiroshi SHIBATA) over 1 year ago

FYI: https://github.com/rails/webpacker/pull/3306 is fix for this issue. We can resolve rails _6.1.7_ new issue to merge its PR and release new version of webpacker.

Updated by hsbt (Hiroshi SHIBATA) over 1 year ago

or you can create rails app with rails _6.1.7_ new --skip-webpack-install.

Updated by byroot (Jean Boussier) over 1 year ago

I merged the webpacker backport, if people absolutely want to use Ruby 3.2 with very old Rails stuff they can point their Gemfile to the git repo.

IMHO It's not worth bringing back File.exists?, it's really trivial to either fix or work around if somehow you are stuck with super old code.

Updated by Milella@Hotmail.com (Scott Milella) over 1 year ago

I think in the long run for Ruby and Rails leaving those 2 methods in place or putting an alias into the code would be a benefit to the community.
I also don't think I would call Rails 6.1.7 "very old code". There are thousands maybe hundreds of thousands of apps running on Rails 6 who may want to upgrade to Ruby v3.2 for the new features it brings. It's 2 methods that have been there for a very long time, why remove them at all? What benefit does it bring to remove them? Really I can't even see a benefit to remove them? If I am wrong please explain what benefit it brings to remove File.exists? and Dir.exists? On the other side there is a penalty in that if someone wants to upgrade their Ruby to v3.2 and they use Webpacker they are going to run into that issue. There could be other places those methods are used as well. Could even be a lot of gems that use those methods. I just don't see any upside to removing those 2 methods. If you go to Rubygems it lists Rails v6.7.2 is compatible with REQUIRED RUBY VERSION >= 2.5.0. So why make a change that breaks it that doesn't appear at face value to offer a benefit?

Updated by byroot (Jean Boussier) over 1 year ago

I just released webpacker 5.4.4, you can just upgrade now.

It's 2 methods that have been there for a very long time, why remove them at all?

They have been deprecated for over 12 years.

If you go to Rubygems it lists Rails v6.7.2 is compatible with REQUIRED RUBY VERSION >= 2.5.0

Sorry but that's a terrible argument. Gem maintainers don't know what future rubies will look like, nobody knows, hence why gems are never pushed with a max ruby version.

Updated by Milella@Hotmail.com (Scott Milella) over 1 year ago

byroot (Jean Boussier) wrote in #note-12:

I just released webpacker 5.4.4, you can just upgrade now.

Thank you for that! I will give that a try in a short while, appreciate that! :)

It's 2 methods that have been there for a very long time, why remove them at all?

They have been deprecated for over 12 years.

If you go to Rubygems it lists Rails v6.7.2 is compatible with REQUIRED RUBY VERSION >= 2.5.0

Sorry but that's a terrible argument. Gem maintainers don't know what future rubies will look like, nobody knows, hence why gems are never pushed with a max ruby version.

That was just one part (the last part) of what I said.

Again what is the BENEFIT of removing those methods? I understand they have been deprecated but if it is so obvious then why would webpacker have used those methods since it's creation date (December 07, 2016) which was after the deprecation? Can the deprecation of those 2 methods be reversed if it doesn't make sense to do so?

Updated by byroot (Jean Boussier) over 1 year ago

Again what is the BENEFIT of removing those methods?

Consistency.

https://bugs.ruby-lang.org/issues/9041

Updated by sawa (Tsuyoshi Sawada) over 1 year ago

(Scott Milella) wrote in #note-13:

Again what is the BENEFIT of removing those methods? I understand they have been deprecated but if it is so obvious then why would webpacker have used those methods since it's creation date (December 07, 2016) which was after the deprecation? Can the deprecation of those 2 methods be reversed if it doesn't make sense to do so?

You seem to be presupposing/suggesting that:

  1. If there is some benefit to deprecate a Ruby's feature, then that should have been so obvious to the developers of webpackers,
  2. If the benefit is so obvious, then the developers of webpacker must have become aware when the feature became deprecated,
  3. If the developers of webpacker used a deprecated feature, then it didn't make sense to deprecate the feature,

all of which is a logical leap, and does not make much sense to me.

Updated by Milella@Hotmail.com (Scott Milella) over 1 year ago

sawa (Tsuyoshi Sawada) wrote in #note-15:

(Scott Milella) wrote in #note-13:

Again what is the BENEFIT of removing those methods? I understand they have been deprecated but if it is so obvious then why would webpacker have used those methods since it's creation date (December 07, 2016) which was after the deprecation? Can the deprecation of those 2 methods be reversed if it doesn't make sense to do so?

You seem to be presupposing/suggesting that:

  1. If there is some benefit to deprecate a Ruby's feature, then that should have been so obvious to the developers of webpackers,
    That was not what I meant; my meaning was that if those RUBY methods were deprecated over 12 years ago and EVERYONE should have knew about as it was suggested then webpacker would have most likely used the non depreciated methods instead. My meaning was that it must not have been as obvious as it was being implied. I in no way fault the makers of webpacker for anything.
  1. If the benefit is so obvious, then the developers of webpacker must have become aware when the feature became deprecated.
    Not what I meant at all, I do not fault the makers of webpacker in anyway. Webpacker came into existence after those methods were deprecated and reached end of life before those methods were removed from Ruby v3.2.
  1. If the developers of webpacker used a deprecated feature, then it didn't make sense to deprecate the feature,
    Rails v6.1.7 with webpacker was the first issue I ran across using Ruby 3.2. I learned it was due to those 2 deprecated methods that were removed. My meaning was why remove 2 methods from Ruby that WE KNOW WILL causes an issue with Rails 6.1.7 using webpacker if it offers no benefit? I said above "Could even be a lot of gems that use those methods.". I reported the issue as soon as I ran across it because I didn't want to see issues with Rails 6.1.7 and Ruby 3.2 AND potentially other gems/apps as well. I don't know how far reaching the issue goes. It could only be an issue with Webpacker/Rails 6.1.7 and Ruby 3.2 for all I know.

all of which is a logical leap, and does not make much sense to me.

Again to be clear I don't have ANY issue with Ruby, Rails or Webpacker or ANYONE in the Ruby/Rails community at all.. I simply didn't want to see Ruby 3.2 have a problem with Rails 6.1.7 with webpacker if it could be avoided. I reported it in hopes of it being fixed so that the issue would not exist and affect anyone. I DID question the fact of removing 2 methods that don't offer a clear benefit if we KNOW it WILL cause a problem.

I apologize if I miscommunicated that in any way.

Scott

Updated by Milella@Hotmail.com (Scott Milella) over 1 year ago

I just released webpacker 5.4.4, you can just upgrade now.

THANK YOU @byroot (Jean Boussier)

I was able to do a rails 6.1.7 new testapp and it installed WITH webpacker and finished without issue.

Thank You VERY MUCH!

This is all I was trying to accomplish was getting the issue fixed, I AM VERY GREATFUL!

I don't know if anything else major or otherwise uses those 2 methods but I can say for sure rails 6.1.7 with webpacker is now working properly.

:)

Actions #18

Updated by jeremyevans0 (Jeremy Evans) 12 months ago

  • Tracker changed from Bug to Misc
  • ruby -v deleted (3.2)
  • Backport deleted (2.7: DONTNEED, 3.0: DONTNEED, 3.1: DONTNEED, 3.2: REQUIRED)
Actions #19

Updated by hsbt (Hiroshi SHIBATA) 12 months ago

  • Status changed from Open to Closed
Actions

Also available in: Atom PDF

Like2
Like2Like1Like0Like0Like1Like0Like0Like1Like0Like2Like0Like3Like0Like1Like0Like0Like1Like0Like0