How to add specific, not released yet commit to Rails current release? - ruby-on-rails

I would like to add this change https://github.com/rails/rails/commit/94584c2510743a45d9030d1b94dd33a074518b17 to release/version 6.0.3.3. How I can do this? Is it smart idea to do so? It sounds for me like I would like to cherry pick this change?

Do as follows:
Create rails fork of the unreleased version that you need
In your Gemfile, add gem 'rails', git: 'https://github.com/you/your-rails-fork'
Run bundle
When it is released, restore gem 'rails' in your Gemfile
It is not a bad idea to do so, as long as:
It actually gets released at some point and you get back to the community-kept official version when it does (for the security reasons mostly).
You don't introduce any custom changes in the forked repository - if you do, you might get in trouble when trying to get back to official rails.

Related

update gem version that is specified in another gem dependency

In my Gemfile, I'm including a gem that has a .gemspec that uses the pessimistic operator ~> to specify a version of the gem. However, I need to use a newer version of the gem. In my case I'm using spree 3-0-stable that has activemerchant set to '~> 1.47.0' https://github.com/spree/spree/blob/3-0-stable/core/spree_core.gemspec#L22 but I need use active merchant '~> 1.59.0'
I tried to specify version 1.59.0 in my Gemfile but bundle complains with:
You have requested:
activemerchant ~> 1.59.0
The bundle currently has activemerchant locked at 1.47.0. Try running
bundle update activemerchant
If you are updating multiple gems in your Gemfile at once, try passing
them all to bundle update
But the command bundle update activemerchant will only update to 1.47.x.
What's the rails-y way of accomplishing this? Aside from forking spree myself and updating the .gemspec? Obviously updates to the activemerchant gem might break the spree gem. But I can test with my app.
The maintainers of Bundler have recommended forking the relevant gem, then making a PR back onto the gem. Then link directly to the branch in that PR in your Gemfile. This encourages the community to rally around a solution.
I've documented the process in detail here: https://github.com/rubygems/rfcs/pull/13#issuecomment-770416467
You can't do it, the rubygems system doesn't allow that. You have to file an issue for the upstream gem dependency, and ask them to loosen their requirements.
It may be that the version of activemerchant you want actually won't work with the version of spree you want, it will break it. If so, spree code would have to be fixed to work with the new version of activemerchant. Or, it could work fine with the version you want, the restriction in spree is accidentally unneccesarily strict, in which case the spree gemspec would just have to be changed to allow it.
But there's no way for you to override it without changing the spree gemspec.
You could make your own fork of spree in which you change the gemspec -- but without knowing whether or not spree will really work with the version of activemerchant you want, that could be dangerous. And now you're on your own fork, so you won't be able to upgrade to new versions of spree without merging in their changes to your fork, etc.
Another thing is, it's a bit odd to be running off a spree 3-0-stable branch, instead of an actual released version of the gem. But I'm not familiar with spree's release management practices, perhaps this is what they encourage? At any rate, changing this probably won't fix your problem.
If your app is relatively new or simple, you could consider switching from spree to solidus, a fork of spree. Solidus forked off at spree 2.x though, so migration from spree 3.x might not be straightforward, especially if your app is established and somewhat complex. Although the solidus_core gem is also locked to activemerchant ~> 1.48.0, so it also won't allow anything but activemerchant 1.48.x. The solidus team is pretty responsive on their Slack channel, if you wanted to ask them what's up with that, if they know if later versions of activemerchant will work, if the dependency can be loosened. I have found the solidus maintainers to be very responsive, and likely to be interested in allowing later versions of activemerchant if it's feasible to do. I'm not familiar with the current Spree team and how they communicate with users (if they have a slack, or listserv, or are responsive on github issues, or what), but you could of course have the same conversation with them.

Working on gem within a Rails app

What's the easiest way to work on a plain-ole Ruby gem, and then quickly turn around and run it in a Rails app?
I like to keep application logic out of Rails. Encourages code reuse across projects, and keeps my Rails app clean. It produces, however, an ugly workflow:
Test my gem. rake test
Build my gem. gem build ...
Upload gem to private repository (currently using Gemfury). fury push ...
Update my gem from within Rails (bundle update ...)
Run my Rails code.
Yuck. I'd like to simply save my file in the library, and then watch it work in the Rails project.
Clojure's Leiningen has a concept called "checkouts", allowing you to work on several libraries within one.
Techniques, anyone?
Use Bundler's path directive.
gem 'my_gem', :path => "~/my_gem"
You'll still have to restart the Rails server every time your code changes to reload it, but you won't have to go through the whole build-and-publish step for each revision. Be sure to update your gem reference to something production-worthy before pushing your code.

Automatic identification of Ruby Gems no longer in use within Rails

Is it possible to automatically identify Ruby gems that are no longer in use within a Rails project?
For example if a fellow developer added gem 'nokogiri' to the Gemfile, for a piece of functionally, but the code that depended on that gem has now been removed. I am looking to port my entire project to jRuby so removing the gems that we no longer seems a very sensible starting point.
Thanks
Usually gems are used in a specific way, so for each one you will have to look for patterns manually.
For example, if I had to figure if Nokogiri is being used, I'd use git grep to find Nokogiri occurrences (I assume you use git):
git grep Nokogiri
If nothing is returned, you are probably not using it.
Another way is, if you have a test suite, is just to remove it and see if something breaks. Not foolproof, but if you have good tests it should be a pretty safe path.
On rubyforge there is a gem called gem_unused. It adds an 'unused' command to 'gem'. However, I am not able to test this as it seems to be failing on my system. (I'm new to the rails world so maybe this is an issue someone else could troubleshoot. I filed an issue on it on the maintainer's github)

Modify Gem, then ensure it gets reloaded?

I've got a gem that I'm modified a bit of code in, but when I bundle install or update, the changes to the gem aren't reflected in my app. Is there a way to ensure the changes are captured and reloaded in my app? Thanks.
You should never update code directly in the gem. Instead, choose from one of these options (from preferred to less preferred):
Send a pull request to the gem maintainer
Monkey patch the gem in your app
Fork the original gem and maintain your copy.
If you need help with any of this, that's a topic for another discussion, but please, don't edit code in the gem itself.
Make sure you modify the installed gem by using bundle open . Make the changes, save, then if your app is local and running in standard development mode (no caching) the changes will be immediate and worse case you can restart your app and they will be picked up. If not, you aren't making the change to the gem your app is using. A change like this will survive a bundle install, because bundler will have no reason to update your gem. However, if you run bundle update and a new version of the modified gem is installed it will get rid of your change. A good approach is to fork the original gem on github, make your change and have your app point to your forked copy on github.. then even when you deploy the app it will find and install your modified code. Also if the change is something useful for everyone, make a pull request to the original project.

How to get a rails commit into my gemmed version

Rails 2.3 was released last week and I installed it with gem install rails. Everything is working fine. However, I noticed a bug, so I searched a bit and sure enough a new commit was accepted 2 days ago that fixes the same bug I saw.
How can I get these latest changes into my version of rails that I'm running locally?
I tried gem update rails --include-dependencies but it doesn't update rails (as I assume because I already have the latest gem 2.3.2). So, how can I get the last few commits into my version of rails?
Thanks.
I've never used Edge Rails but I imagine that's what you'd need to do. Edge is the last commit and may have other bugs in it.
If the changes are small, just edit the code. Once you've done that you may be able to freeze the gems after you've edited them, but I'm not sure that freeze will freeze the rails code itself. If it does then everything should still work fine, otherwise you'd also need to edit it on your production gems too.
Hope this helps, doubtless some Rails Edge god will come along and tell us the easy way.
If you use git to checkout the release, then you can use git cherry-pick to grab the specific patches that you want for your own personal tree. google for git cherry-pick for more info (and if you aren't familiar with git, it's worth learning!)
I found some comprehensive instructions for this here:
http://www.napcsweb.com/blog/2008/04/24/create-a-new-edge-rails-project
If you freeze rails to the 2.3.2 version, you can then edit the file yourself and be sure that your application will use that edited version of rails.

Resources