Rails: Handling different versions of gems - ruby-on-rails

I have a rails 5.2 application with rvm installed:
=> ruby-2.4.2 [ x86_64 ]
* ruby-2.4.4 [ x86_64 ]
# => - current
# =* - current && default
# * - default
I want to add the ability to take an automated backup of the database, so installed the backup gem. I understand that this shouldn't be added to the GemFile due to some of its dependencies being relatively old, so I used the command gem install backup-v5.0.0.beta2
When I run gem list there are a number of gems which have two version numbers, e.g. open4 (1.3.4, 1.3.0)
I am running into problems when I try to manually trigger the backup routine via backup perform -t db_backup --config-file /Users/<path_to_my_rails_project>/config/Backup/config.rb, which produces the error:
[error] CLI::Error
[error] --- Wrapped Exception ---
[error] Gem::LoadError: You have already activated open4 1.3.0, but your Gemfile requires open4 1.3.4. Prepending `bundle exec` to your command may solve this.
Following the steer in the error message, bundle exec backup perform -t db_backup --config-file /Users/<path_to_my_rails_project>/config/Backup/config.rb produces the error:
/Users/<my_username>/.rvm/gems/ruby-2.4.2/gems/bundler-1.16.6/lib/bundler/rubygems_integration.rb:462:in `block in replace_bin_path': can't find executable backup for gem backup. backup is not currently included in the bundle, perhaps you meant to add it to your Gemfile? (Gem::Exception)
Please could you advise how I should be installing the backup gem and running the task without hitting errors due to different versions of the same gem being installed

Ensure that you haven't version locked the gem like so: gem open4, '~> 1.3.4'
Try bundle update open4 backup. I would try the latest version of the gem as well.
Another option is to ditch this gem and try https://github.com/javan/whenever and just run a simple pg_dump, or not use any gems and add a cron job that creates a pg_dump with the timestamp in the filename.
These issues can be hard to debug, but my approach is to generally start removing gems and letting bundler figure out its dependency tree on its own. The more you define in your Gemfile them more chances bundler will have a version mismatch thus throwing an error like the one you're seeing.

Related

Install Ruby Gem + dependencies on specific folder and run that installation

I am currently attempting to install on a specific directory a set of gem files and run that installation (trying to avoid installing to default Ruby locations).
e.g. I have a folder with gems I plan to install locally, thus I run the following command:
gem install --force --install-dir .\install_3 --conservative --bindir .\install_3\bin --no-document --local *.gem
This then installs all gems available in that folder in my install_3 directory.
However, I am having trouble running the gems I installed in that directory.
My question is, how can I install Ruby gems in a specific folder and make sure I run the gem and its dependencies from my specified folder in --install-dir option?
When I try to run with the following script:
#setlocal
#set DIRNAME=%~dp0
cd %DIRNAME%
#set PATH=%PATH%;%DIRNAME%install_3\bin
#set TEMP=C:\TEMP
fluentd -c fluentd.conf
I get the following error:
Traceback (most recent call last):
2: from C:/Users/yytcadm/Desktop/fluentd_1.8.0_gems/install_3/bin/fluentd:23:in `<main>'
1: from C:/Ruby25-x64/lib/ruby/2.5.0/rubygems.rb:303:in `activate_bin_path'
C:/Ruby25-x64/lib/ruby/2.5.0/rubygems.rb:284:in `find_spec_for_exe': can't find gem fluentd (>= 0.a) with executable fluentd (Gem::GemNotFoundException)
Instead of fetching gems from my specified installation folder, it attempts to search for them in the default ruby gem folder.
Edit: It seems to throw an error on this line from my fluentd file:
load Gem.activate_bin_path('fluentd', 'fluentd', version)
I'm guessing I need to modify this to the custom path decided on my --install-dir option but my attempts have not been fruitful so far.
When you require a gem, Rubygems searchs for it inside the default gems folder. You can prevent Rubygems to do that by adding the paths of your gems to the $LOAD_PATH variable.
For example, if you have one gem at /home/user/custom_dir/my_gem, you can do something like this before requiring the gem:
$LOAD_PATH << "/home/user/custom_dir/my_gem/lib"
Another option is to use require_relative instead of require. If you app root is /home/user/my_app and inside that dir you have the gems like /home/user/my_app/gems, you can do somthing like:
require_relative 'gems/my_gem'
Check this talk https://www.youtube.com/watch?v=I0a5zv7uBHw it's really enlightening on how to require things.
Providing answer to those that might need it:
In order to correctly automate the installation of a specific gem + their dependencies:
bundle install
bundle package --all-platforms --all
This will fetch all dependent gems and place them on vendor/cache
If you install your gem + dependencies with the following command:
gem install --no-user-install --install-dir Install_Location --conservative --bindir Install_Location\bin --no-document --local YOUR_GEM_TO_INSTALL
You can then run your gem commands by setting the following:
Add Install_Location/bin to PATH
Append Install_Location to GEM_HOME
Append Install_Location to GEM_PATH
run the gem commands needed
This allowed me to have run gem commands without these appearing/affecting gems available in gem list.

Installing bundler gives me "you don't have write permissions" error

I had used ruby version manager (rvm) to install a new version of ruby. Running the command rvm rubiesshows all the version of rubies that are installed. The list is given below.
rvm rubies
ruby-1.9.3-p551 [ x86_64 ]
ruby-2.1.5 [ x86_64 ]
ruby-2.2.4 [ x86_64 ]
* ruby-2.3.0 [ x86_64 ]
ruby-2.3.1 [ x86_64 ]
# => - current
# =* - current && default
# * - default
I tried to run the command bundle exec rake rb:mgirate and I get the following error.
/usr/local/rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/dependency.rb:319:in `to_specs': Could not find 'bundler' (>= 0.a) among 5 total gem(s) (Gem::LoadError)
Checked in 'GEM_PATH=:/nix/.nix-profile/lib/ruby/gems', execute `gem env` for more information
The error states that bundler isn't installed. I ran the command gem install bundle and I get the following error.
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /nix/.nix-profile/lib/ruby/gems directory.
It says that I don't have write permissions. I googled the error and it has something to do with updating ruby and ruby version. The reason why I updated to a new ruby version was because heroku run rake db:seed wasn't seeding data in production. I though it might be due to compatibility issues. Therefore, I decided to update to the new version of ruby. The servers, postgresql and everything else works fine. I can't run bundle because I can't install the gem. Any hep would be greatly appreciated. Thanks!
The problem was fixed by switching to the ruby version 2.3.0 by running the command rvm user 2.3.0. Once that is done you should restart the workspace. The reason for the error was the fact that when you switch ruby version it also changes gem files. Therefore, it wasn't able to recognize the gems.
hey just add "sudo" at the beginning of your command. It will definitely work, because as the error says you don't have write permission. And if you will check the permission of that directory than you will find that only owner has write permission and as sudo takes us to the owner mode from user mode. Hence you will not get this error again. Please let me know if it doesn't works.

Using different gem dependencies in a ruby gem

I am using a hand crafted gem in my Rails application which itself has a dependency to a Gem i need to replace for Ruby version >= 2.0.
I found a nice way to inject dependencies dynamically by using Gem extensions.
Installing my gem with sudo gem install ... works just fine, dependencies will be installed according to my ruby version conditional inside mkrf_conf.rb:
require 'rubygems/dependency_installer'
di = Gem::DependencyInstaller.new
if RUBY_VERSION < '2.0'
puts "Using vanilla httpclient because of Ruby #{RUBY_VERSION}"
di.install 'httpclient', '2.3.3'
else
# https://github.com/nahi/httpclient/pull/163
puts "Using patched httpclient by glebtv because of Ruby #{RUBY_VERSION}"
di.install 'glebtv-httpclient', '3.2.7'
end
puts "Writing fake Rakefile"
# Write fake Rakefile for rake since Makefile isn't used
File.open(File.join(File.dirname(__FILE__), 'Rakefile'), 'w') do |f|
f.write("task :default" + $/)
end
I'm using this gem inside my Rails app (plain reference inside the Gem file). I'm not using rvm on my development VM, all gems reside in the system gem path. Usually, bundler asks for a sudo password (running Ubuntu) when it installs new gems. When I'm trying to bundle now, bundler fails building the native gem extensions due to insufficiant permissions:
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
/usr/local/bin/ruby mkrf_conf.rb
/usr/local/lib/ruby/site_ruby/1.9.1/rubygems/package.rb:359:in `initialize': Permission denied - /usr/local/lib/ruby/gems/1.9.1/gems/httpclient-2.3.3/bin/httpclient (Errno::EACCES)
I'm absolutely clueless how to avoid running bundler with sudo. As far as I understand from reading bundler's source, bundler should detect if sudo is necessary when installing new gems. But I'm also using gems in my project that have native C extensions (nokogiri, mysql2, ...) and those will be built correctly. Also, the bundler man page states that starting bundler with sudo bundle is something that is to be avoided.
Is the way I'm trying to inject dependencies into my Gem depending on the Ruby version not the way-to-go?
Any hint or help is really appreciated.
the problem is that you install your gem with sudo (super user permission) then you cannot access it, use RVM and install the gems without sudo it will solve your problem.

Error installing the json gem on Windows

I am new to ruby on rails, I am trying to get my first project working with git and heroku. I am following the tutorial by Michael Hartl. I was originally trying to
git push heroku master
but I dont have a GemFile.lock, so I have been trying bundle installs and bundle updates but nothing works because I dont have the json native gem.
bundle update
this is the command that reuturned this error, its not the whole error i left out all the gems i already have
Installing json (1.7.3) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
"C:/Program Files/ruby-1.9.3/bin/ruby.exe" extconf.rb
creating Makefile
make
Makefile:160: warning: overriding commands for target `C:/Program'
Makefile:153: warning: ignoring old commands for target `C:/Program'
C:/Program Files/ruby-1.9.3/bin/ruby -e "puts 'EXPORTS', 'Init_parser'" > parser-i386
mingw32.def
/bin/sh: C:/Program: No such file or directory
make: *** [parser-i386-mingw32.def] Error 127
Gem files will remain installed in C:/Program Files/ruby-1.9.3/lib/ruby/gems/1.9.1/gems/json-1.7.3 f
or inspection.
Results logged to C:/Program Files/ruby-1.9.3/lib/ruby/gems/1.9.1/gems/json-1.7.3/ext/json/ext/parser/gem_make.out
An error occured while installing json (1.7.3), and Bundler cannot continue.
Make sure that `gem install json -v '1.7.3'` succeeds before bundling.
If anybody knows how to fix my error so that i can move onto the next one or how i can get a working GemFile.lock, it would be appreciated.
Install json_pure instead on your development machine. This is a version of the json gem that does not require C-extensions (but is a bit slower).
On Heroku you should be able to go with the faster json directly.
If you want to build the C-extension on windows then you might want to look here:
The 'json' native gem requires installed build tools
You can create a windows-specific section in the Gemfile like so:
# Common gems
gem 'xyz'
...
# Platform specific gems
platforms :ruby do
gem 'json'
end
platforms :mswin, :mingw do
gem 'json_pure'
end
Windows isn't properly escaping the space in "C:\Program Files". I haven't used Windows in a while, but a quick search reveals a few fixes.
I had the same problem and found that in my config.yaml file, there was an installation of Ruby 1.9.2 that had a space in it. I had to uninstall that version of Ruby entirely, and remove it from the PATH in environment variables. Then, I re-installed the DevKit and it worked perfectly.

Gem error. can't activate faraday (>= 0.7.3, runtime) for ["youtube_it-2.1.1"], already activated faraday-0.5.7 for ["instagram-0.8"]"

I am making a Rails(3.0.4) application using the youtube_it API.
I installed the gem using gem install youtube_it, but when I run the script I get this error:
can't activate faraday (>= 0.7.3, runtime) for ["youtube_it-2.1.1"], already activated faraday-0.5.7 for ["instagram-0.8"]
How should I resolve this without removing the existing version of faraday?
First, you should be adding youtube_it to your Gemfile, then running bundle install.
This gives bundler enough information to figure out the dependency graph of all the gems your application needs. Bundler writes out the needed gems, their dependencies and versions to the Gemfile.lock file.
Second, when running the rails command, you shouldn't need to run bundle exec according to Yehuda Katz (http://yehudakatz.com/2011/05/30/gem-versioning-and-bundler-doing-it-right/). However, in my experience there have been times when bundle exec has been necessary even for the rails command.
In any case, running "bundle exec executable" will run your executable (rails, rake, etc) with the gems listed in the Gemfile.lock, avoiding the dreaded "can't activate -- already activated" error.
I don't think you can. You should update faraday to its latest version. Is there a valid reason not to?

Resources