oneclick / rubyinstaller2

MSYS2 based RubyInstaller for Windows
https://rubyinstaller.org
BSD 3-Clause "New" or "Revised" License
644 stars 248 forks source link

The exists method was removed on Ruby v3.2. As a result of that Rails v6.1.7 can not be used with it because Webpacker fails on calling the exists? method. #331

Closed desnw closed 1 year ago

desnw commented 1 year ago

Hello, I originally reported this issue to Rails but they said that they don't do bug fixes on Rails v6.1x anymore and since this is more of a Ruby bug (or perhaps not thinking through the removal of the Dir.exists? and File.exists? methods) I thought I would report it here. I also care about the Ruby/Rails environment very much and I didn't want to see Ruby v3.2 not have the ability to rub a Rails v6.1.7 application.

I have been developing with Ruby and Ruby on Rails for about 2 1/2 years now mostly with v2.7.2 of Ruby and Rails 6.1.7. I apologize in advance if I am not submitting this issue request properly; if I am doing something wrong please let me know what it is. I went to rubyinstaller.org and on the bug report section it sent me here so I hope this is the right place?

What problems are you experiencing?

Install 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)

Expected behavior

I would expect it to finish installing the rails v6.1.7 new application with webpacker. I thought I might have read something that said in Ruby v3.2.0 they removed the "exists?" method?!? If that is true then how can we use Rails v6.1.7 with Ruby 3.2.0?
Would someone need to go to the source file and change the "exists?" method to "exist?", I think that is what they might have re-named it to if I understood it correctly. New information about Ruby 3.2 is obviously limited as it only came out on Christmas of 2022.

Actual behavior

Crashes at the webpacker install portion: 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)

System configuration

Rails v6.1.7, Ruby v3.2

I believe it has to do with Ruby 3.2 because I was able to overcome the error by installing URU (Windows Ruby version manager. The ONLY ONE I could find for Windows). I installed Ruby 2.7.7 "rubyinstaller-devkit-2.7.7-1-x64.exe" and used URU to change to that version. If I do that and then I run rails 6.1.7 new testapp, it WILL FINISH the install properly. I do get some odd warnings about using some pre-initialized constants (found out it has to do with the net-http gem, if you add that gem into your gem file then the constant warnings go away, not sure why this is happening but it isn't really the topic of this request). See below, I have copied the same relevant section where it was failing before using Ruby 3.2

Use bundle info [gemname] to see where a bundled gem is installed. run bundle binstubs bundler rails webpacker:install C:/Ruby27-x64/lib/ruby/2.7.0/net/protocol.rb:66: warning: already initialized constant Net::ProtocRetryError C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:68: warning: previous definition of ProtocRetryError was here C:/Ruby27-x64/lib/ruby/2.7.0/net/protocol.rb:206: warning: already initialized constant Net::BufferedIO::BUFSIZE C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:214: warning: previous definition of BUFSIZE was here C:/Ruby27-x64/lib/ruby/2.7.0/net/protocol.rb:503: warning: already initialized constant Net::NetPrivate::Socket C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:541: warning: previous definition of Socket was here C:/Ruby27-x64/lib/ruby/2.7.0/net/protocol.rb:66: warning: already initialized constant Net::ProtocRetryError C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:68: warning: previous definition of ProtocRetryError was here C:/Ruby27-x64/lib/ruby/2.7.0/net/protocol.rb:206: warning: already initialized constant Net::BufferedIO::BUFSIZE C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:214: warning: previous definition of BUFSIZE was here C:/Ruby27-x64/lib/ruby/2.7.0/net/protocol.rb:503: warning: already initialized constant Net::NetPrivate::Socket C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:541: warning: previous definition of Socket was here 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 The JavaScript app source directory already exists apply C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/webpacker-5.4.3/lib/install/binstubs.rb Copying binstubs exist bin create bin/webpack create bin/webpack-dev-server append .gitignore Installing all JavaScript dependencies [5.4.3] run yarn add @rails/webpacker@5.4.3 from "." yarn add v1.22.19 I truncated the log here as it finishes the rest of the way and I am sure we all know what a finished installed Rails app looks like. Although if it would be of value let me know and I will include whatever else you want.

Thank You, Scott

MSP-Greg commented 1 year ago

Try Ruby 3.1, or upgrade Rails...

See NEWS for Ruby 3.2.0

desnw commented 1 year ago

Yes it does work with Ruby 3.1. I was hoping we could PREVENT the newest and best version of Ruby from Alienating one of the best versions of Rails so far v6.1.7. Why would you ever want to do that? I would like to see the newest version of Ruby continue to work with past things as well. If ruby is to survive which I would like to see it needs to retain some backwards compatibility. I think maybe someone just didn't think the removal of those 2 methods all the way through. I am hoping maybe they can go in and alias those 2 methods or something so it will continue to work, not entirely sure WHY they removed them in the first place. It seems to only effect the webpacker install portion as far as I could tell but since I couldn't get past the webpacker install portion I can't really say if it has any other issues beyond that.

MSP-Greg commented 1 year ago

If you really need to stay with Rails 6, you could find the code causing the problem, fork the repo, fix the issue, and point your Gemfile to it.

But, there may be additional problems once your app is installed.

JFYI, Ruby 2.3.0 shows the method as deprecated, so people had plenty of warning...

desnw commented 1 year ago

I wasn't logging this issue just for me I am doing it for the greater Ruby on Rails community. I wanted to do whatever I can do to prevent Ruby from loosing compatibility with already existing code out there to the tunes of what a million apps that run on Rails v6? It could also effect versions of 5 if they are running webpacker. I don't understand this compulsion in the Ruby/Rails community to remove syntax and break things?!? It seems like a gigantic step backwards.

Nobody else will fix this because webpacker is now End of life as they call it and they will no longer update Rails v6.1 anymore so Rails isn't going to fix it. On top of that webpacker isn't developed anymore. I don't use webpacker myself hardly ever but I know it is used a lot in the real world. Again I spotted a potential big issue I wanted the maker(s) of Ruby to be aware of.

Why bring out a new version of Ruby and alienate major rails versions and webpacker for the sake of removing 2 methods? Why? (that I know of so far).

If the Ruby developers decide not to fix it.... Well I tired to help stop an issue from hurting the Ruby and Rails community, all I can do.

Largo commented 1 year ago

Yes, I also didn't like the depreciation of exists? This is more of a topic for the ruby bugtracker. Luckily we can monkeypatch the method and avoid the whole problem. I'll make a gem...

https://rubygems.org/gems/file_exists https://github.com/Largo/file_exists

mohits commented 1 year ago

hi @desnw - unfortunately, it would not be correct for the Ruby Installer to add/ work around the main Ruby language.

There seem to be only a few ways to resolve this:

mohits commented 1 year ago

As answered by @MSP-Greg, see: https://github.com/rails/webpacker/pull/3250

MSP-Greg commented 1 year ago

The above PR/commit was done after the last release of webpacker.

See https://github.com/shakacode/shakapacker for a possible option.

And, I would suggest trying webpacker master/head, run its CI/tests, check it with a Rails app, then see if they will push another release. If they agree, they're only going to do one release.

Lastly, for something that has been deprecated for years, this isn't a Ruby core problem, and they shouldn't be expected to waste their time on compatibility with old code.

More people need to check their code with warnings on, or use RuboCop, or whatever...

mohits commented 1 year ago

Since it looks like there is nothing more that we can do on the RubyInstaller side, I will close this. Thanks for all the comments.

Largo commented 1 year ago

Since that particular deprecation can be a problem for a lot of projects, I made a workaround for those people by creating the file_exists gem. Just install the gem and add require 'file_exists' to the top of the first file of your code.

https://rubygems.org/gems/file_exists https://github.com/Largo/file_exists

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

desnw commented 1 year ago

@Largo , you are the man! Awesome! Thank You for the workaround, I never thought of just making a gem to monkey patch the methods back in. :) So I guess to make that work we would what have to do the new rails app with the --skip-webpack-install and then add that gem you made to the gem file and then run rails webpacker:install ?

@mohits, I apologize I thought this was an issue reporting for the Ruby Language I now see this is ONLY for the RubyInstaller itself, I apologize for that.

@MSP-Greg, Thank you for the information, much appreciated! To be clear again I was not really logging this issue for myself I was trying to prevent a future problem for people using Ruby 3.2 on Rails that uses webpacker which is still a LOT of apps. It makes no sense whatsoever to just remove methods that does nothing positive for the language itself but DOES break things. That is precisely the thought process I would like to see change in the Ruby/Rails community as it drives people from using the product(s).

Never a good idea to break backwards compatibility unless there is some MAJOR reason for it. The reason these methods were removed is because they were supposedly deprecated since Ruby 2.1. I don't agree that is a good reason to just remove something without examining the potential consequences. They didn't hurt anything all that time being there, no reason to just yank them without considering what it would do to things. This is only the FIRST THING I have come across with Ruby 3.2, I can only imagine how many other apps, gems etc still use those methods. Nobody would buy a new car if you could ONLY drive it on the newest roads would they? I want the Ruby language to survive if possible as I think Ruby is a great language and Rails is what keeps Ruby relevant so I just hate to see them make a mistake and alienate 2 major releases that a L O T of apps are running on.

I did sign up for an account on the Ruby bug site which I found last night and I did log a bug there. This is the issue I logged so there is a complete trail. https://bugs.ruby-lang.org/issues/19352

Thank you for the time of the people who responded.

mohits commented 1 year ago

@desnw - the confusion is understandable, and the apology is most unnecessary. Have a great day!

desnw commented 1 year ago

Lastly if I didn't make this clear before, this is ONLY A problem with Ruby 3.2, Ruby 3.1 works just fine as I tested it.