How to switch between different version of gem installed? - ruby

I have three version of rack installed on local machine (rack (1.4.1, 1.3.6, 1.3.5)). For some gem (such as Cucumber), it requires a lower version of rack to be activated?
I have tried with bundle but there is no good.
When executed, cucumber will still use the activated rack with version 1.4.1 of the system. Bundlespecifies which gem should be installed but doesn't ensure which gem will be activated.
How could I activate certain version of rack?

You can specify a version in gemfile of your project
gem "rack", "1.3.5"
Pointed by matt:
To use gem specified in Gemfile:
bundle exec cucumber

Use bundler it will manage it for you.

Related

How can `gem list` show multiple `default` versions for a gem?

When I run gem list bundler, I get the following result
+ gem list bundler
*** LOCAL GEMS ***
bundler (default: 2.3.22, default: 2.1.4)
How is it possible that two versions are marked as default? Is there a way to update the default one?
Context
The reason I ended up looking into which is the default Bundler version is that I've been running into this warning on a self-managed CI machine on and off for a while:
Gem::LoadError: You have already activated bundler 2.3.22 [or whichever latest version is available], but your Gemfile requires bundler 2.1.4.
I looked into my Gemfile.lock and it requires bundler like this:
bundler (>= 1.12.0, < 3.0.0)
So I'm guessing at some point, Bundler activated (which I believe means selected for runtime use) version 2.1.4 because that was the default available one.
I hope to be able to forever prevent that error by forcing the latest version of bundler to be the one used at runtime, but I'm not sure how to achieve it.
That is, how can I get the gem list bundler output to not show default: 2.1.4?
Thanks for your help!
To delete the duplicate default versions
gem environment
you will find the installation directory:
INSTALLATION DIRECTORY: /home/seb/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0
in /specifications/default you will find your .gemspec files, you will remove your duplicate one
rm bundler-2.2.31.gemspec
to verify: gem list bundler
(2.2.31, 2.2.29, default: 2.2.15)
you can update the default version with gem install bundler:2.3.18 --default but it appears that bundler use a arbitrary version that fit his needs. If you want use a specific version to bundle the Gemfile, you add it in your gemfile
gem "bundler", "~> 2.3"
it will appear at the end of the gemfile.lock
BUNDLED WITH 2.3.18

How to specify minimum bundler version for Gemfile?

When my Gemfile is using :mri_20, and previous versions of bundler do not support that, is it a good idea to add
gem 'bundler', '~>1.3.5'
to the Gemfile? Is there a better way to enforce a minimum bundler version?
This won't have any affect on the bundler used to manage the gems in the Gemfile. The version of bundler that's used is the one that's available in your current ruby environment.
The best way to manage this is with gemsets - you can create a gemset with a known, working version of bundler and always switch to that gemset when working with that project.
To check the bundler version, run:
$ bundle --version
Bundler version 1.3.5
If you want to enforce the bundler version when running bundle install, put this at the top of the Gemfile:
# Gemfile
if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.3.5')
abort "Bundler version >= 1.3.5 is required"
end

Incompatible version for gem "activesupport" while installing "threetaps-client" gem

I'm fairly new to rails and I encountered this gem conflict, while running bundle install, between ActiveSupport and threetaps-client (which I need to use for my project).
I tried removing the Gemfile.lock file and running bundle install again but it gave me the same error message again. I also tried running bundle update which also gave the same result :(
Bundler could not find compatible versions for gem "activesupport":
In snapshot (Gemfile.lock):
activesupport (3.2.13)
In Gemfile:
threetaps-client (>= 0) ruby depends on
activesupport (~> 3.0.0) ruby
Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
The issue here is that you are using Rails 3.2 (and thus, activesupport 3.2). However, threetaps-client is version locked to rails/activesupport 3.0.x. The easiest solution to this would be to downgrade Rails to 3.0 in your Gemfile with:
gem "rails", "~> 3.0"
And then remove the Gemfile.lock and bundle install again. You should be good to go after that.
EDIT
I was able to get the gem to support activesupport 3.2 (I think). The tests do not pass on this branch, but they did not pass on master either. I assume this probably has to do with credentials or something. Update your Gemfile to use this repo for threetaps-client
gem "threetaps-client", git: "git#github.com:ehowe/3taps-Ruby-Client"
Insert required "your mileage may vary" warning here.

Problems with bundled gems and datamapper: conflict with muti_json version?

I have a site running with nginx/unicorn/sinatra (bundler/rvm).
After my last bundle update, I am getting an error:
in `raise_if_conflicts': Unable to activate dm-serializer-1.2.1, because multi_json-1.3.5 conflicts with multi_json (~> 1.0.3)
My Gemfile is:
source "http://rubygems.org"
gem 'unicorn'
gem 'sinatra'
gem 'datamapper'
gem 'dm-mysql-adapter'
gem 'haml'
gem 'sass'
gem 'omniauth-twitter'
Gemfile.lock does not have any reference to multi_json 1.0.3
Any ideas?
Solution was:
check Gemfile.lock to see which gem(s) bring in later version (in this case - omniauth-twitter)
Find a version of 'offender' that does not require too high version
Rollback later versions, lock to a proper version in Gemfile
In this particular case, Gemfile that works needed lines:
gem 'omniauth-twitter', '0.0.9'
gem 'multi_json', '~> 1.0.3'
One of the gems in your bundle has an older version of multi_json as a dependency it looks like. See if bundle viz tells you. You'll need to install the ruby-graphviz gem and graphviz itself if you don't have them installed already, though.
Another way to see what's up is to add multi_json to your gemfile at the version you're trying to upgrade to, then do a bundle install and see what errors come out.
This is how to fix this problem:
rvm uninstall multi_json
It will tell you that you have many versions installed, show you a list of them, and ask you which one exactly you want to uninstall.
Try the first one, if it tells you that it is used by some other gem, try the second one, and so on. Keep deleting all the unused versions until only one remains.
This is how I do it, but there may be some clearner solution. If anyone knows it, thanks for sharing it with us.

Confusion about bundler path

I opened a dedicated hosting account on DreamHost. I deployed an rails app to that. I got the following error.
You have already activated rack 1.2.1, but your Gemfile requires rack 1.3.6. Using bundle exec may solve this.
I checked the version.
$ gem list -d rack
rack (1.2.1, 1.1.0, 1.0.1, 1.0.0)
Author: Christian Neukirchen
Rubyforge: http://rubyforge.org/projects/rack
Homepage: http://rack.rubyforge.org
Installed at (1.2.1): /usr/lib/ruby/gems/1.8
(1.1.0): /usr/lib/ruby/gems/1.8
(1.0.1): /usr/lib/ruby/gems/1.8
(1.0.0): /usr/lib/ruby/gems/1.8
Rack 1.3.6 is not there. But when I checked it with "bundle show" it's already installed. (Actually I did "bundle install --deployment")
$ bundle show rack
/.../my_rails_app_root/vendor/bundle/ruby/1.8/gems/rack-1.3.6
And I have config/setup_load_paths.rb
if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
begin
rvm_path = File.dirname(File.dirname(ENV['MY_RUBY_HOME']))
rvm_lib_path = File.join(rvm_path, 'lib')
$LOAD_PATH.unshift rvm_lib_path
require 'rvm'
RVM.use_from_path! File.dirname(File.dirname(__FILE__))
rescue LoadError
# RVM is unavailable at this point.
raise "RVM ruby lib is currently unavailable."
end
end
ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', File.dirname(__FILE__))
require 'bundler/setup'
Actually I found a solution. Just "gem install rack -v 1.3.6" fixed the problem.
But why does passenger pick up system's rack gem(or user's rack gem) instead of bundle's rack gem? How do you avoid this problem?
Thanks.
Sam
Typically this is what you get when you run your app (e.g. rails server) without prefixing the command with bundle exec.
When you ran bundle install --deployment, bundler took your gems from ./vendor/cache and whacked them in ./vendor/bundle. From then on, Bundler knows where to find them, but you have to be running the app through Bundler.
Rubygems, however, does not know where these gems are, which is why they are not shown when you run the rubygems command gem list. When you installed Rack 1.3.6 using rubygems, naturally rubygems found it and your app started working.
Not using bundler to start your app lets rubygems satisfy the requirements of your app according to it's own method, and that is a fairly random - I would be quite surprised if your app is currently running all the same gem versions that you ran your tests on, for instance (Eek!)
The approach I usually take is to uninstall all the gems from the server, install a single version of rubygems and bundler, and then rely exclusively on Bundler to maintain my app's gems. The beauty of bundler is that it calculates a valid set of gems and reliably uses it.
Hope this helps!

Resources