Ruby programmatically installing a gem - ruby

If I install a gem programmatically using Backticks in script with gem install gem_name as:
if not_gem_installed
`gem install my_gem`
end
require 'my_gem'
and then require the gem, a LoadError comes up. Any way to fix this?

I've tried installation of gems with backticks and found that I have the same issues as mentioned in question. I see that it's not the optimal choice for this job.
I would suggest to use Gem for search of gems and installation.
require 'rubygems/commands/install_command'
def find_or_install(gem_name)
Gem::Specification::find_by_name(gem_name)
rescue Gem::LoadError
install_gem(gem_name)
end
def install_gem(gem_name)
cmd = Gem::Commands::InstallCommand.new
cmd.handle_options [gem_name]
cmd.execute
rescue Gem::SystemExitException => e
puts "FAILURE: #{e.exit_code}"
end
https://gist.github.com/adamjmurray/3154437 - Gist with good examples

Since you are not using RubyGems, you need to require specific file from your gem's path. RubyGems overrides the require method so that it looks for paths file to include from gem paths in your Gemfile. So, make sure you specify correct path to your gem's main .rb file.
if not_gem_installed
`gem install my_gem`
end
require 'path/to/my_gem'
You can check the paths ruby will look into by printing the value of $: in your file/irb or by running gem environment command in your command line.
uzbekjon#mini:~$ gem environment
RubyGems Environment:
- RUBYGEMS VERSION: 2.5.1
- RUBY VERSION: 2.3.0 (2015-12-25 patchlevel 0) [x86_64-darwin15]
- INSTALLATION DIRECTORY: /Users/uzbekjon/.rvm/gems/ruby-2.3.0
- USER INSTALLATION DIRECTORY: /Users/uzbekjon/.gem/ruby/2.3.0
- RUBY EXECUTABLE: /Users/uzbekjon/.rvm/rubies/ruby-2.3.0/bin/ruby
- EXECUTABLE DIRECTORY: /Users/uzbekjon/.rvm/gems/ruby-2.3.0/bin
- SPEC CACHE DIRECTORY: /Users/uzbekjon/.gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /Users/uzbekjon/.rvm/rubies/ruby-2.3.0/etc
- GEM PATHS:
- /Users/uzbekjon/.rvm/gems/ruby-2.3.0
- /Users/uzbekjon/.rvm/gems/ruby-2.3.0#global
- GEM CONFIGURATION:
...
=== OR with $: ===
uzbekjon#mini:~$ irb
2.3.0 :001 > $:
=> ["/Users/uzbekjon/.rvm/gems/ruby-2.3.0#global/gems/did_you_mean-1.0.0/lib", "/Users/uzbekjon/.rvm/rubies/ruby-2.3.0/lib/ruby/site_ruby/2.3.0", "..."]
Alternatively
You can require simply use bundler in your script.
if not_gem_installed
`gem install my_gem`
end
require 'rubygems' # <= This line here
require 'path/to/my_gem'

Related

Making a Ruby Gem - Cannot Load Such File

I'm attempting to build a Ruby gem using the instructions at http://guides.rubygems.org/make-your-own-gem/. The following seems to work fine and a *.gem file is generated.
gem build mygem.gemspec
The following also appears to be successful (only if prefaced with sudo):
sudo gem install mygem-0.0.1.gem
However, when I attempt to require 'mygem' inside irb, I get the following error:
LoadError: cannot load such file -- mygem
I've seen similar errors around Stackoverflow but haven't been able to figure out what's going wrong in my specific situation. I am able to require other gems (not mine) without problems. My gem does show up in the output of gem list but it will not load with require.
FWIW I am using rbenv, which is brand new to me.
Here is the output of gem env:
RUBYGEMS VERSION: 2.4.5
RUBY VERSION: 2.1.5 (2014-11-13 patchlevel 273) [x86_64-darwin14.0]
INSTALLATION DIRECTORY: /Users/speersj/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0
RUBY EXECUTABLE: /Users/speersj/.rbenv/versions/2.1.5/bin/ruby
EXECUTABLE DIRECTORY: /Users/speersj/.rbenv/versions/2.1.5/bin
SPEC CACHE DIRECTORY: /Users/speersj/.gem/specs
SYSTEM CONFIGURATION DIRECTORY: /Users/speersj/.rbenv/versions/2.1.5/etc
RUBYGEMS PLATFORMS:
ruby
x86_64-darwin-14
GEM PATHS:
/Users/speersj/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0
/Users/speersj/.gem/ruby/2.1.0
GEM CONFIGURATION:
:update_sources => true
:verbose => true
:backtrace => false
:bulk_threshold => 1000
REMOTE SOURCES:
https://rubygems.org/
SHELL PATH:
/Users/speersj/.rbenv/versions/2.1.5/bin
/Users/speersj/.rbenv/libexec
/Users/speersj/.rbenv/plugins/ruby-build/bin
/Users/speersj/.rbenv/shims
/Users/speersj/.rbenv/bin
/Library/Frameworks/Python.framework/Versions/3.4/bin
/usr/local/bin
/usr/local/sbin
/usr/local/heroku/bin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin
/usr/local/smlnj/bin
Gemspec:
Gem::Specification.new do |spec|
spec.name = 'mygem'
spec.version = '0.0.1'
spec.date = '2015-01-05'
spec.summary = "mygem"
spec.description = "Attempting to build a gem"
spec.authors = ["speersj"]
spec.email = # my email here
spec.files = ['lib/command.rb', 'lib/connection.rb']
spec.homepage = ''
spec.license = 'MIT'
end
The spec.files entry of your gemspec doesn’t include the mygem.rb file, so that file won‘t be in the gem when it is built. Only files listed in this entry will be included in the final gem.
The simplest solution would be to just add mygem.rb to the array:
spec.files = ['lib/command.rb', 'lib/connection.rb', 'lib/mygem.rb']
This is a fairly simple fix, you might want to do something more flexible like using a Dir glob:
spec.files = Dir['lib/**/*.rb']
In fact the Rubygems guide suggests you do something like this (text is from the end of that section):
If you’ve added more files to your gem, make sure to remember to add them to your gemspec’s files array before publishing a new gem! For this reason (among others), many developers automate this with Hoe, Jeweler, Rake, Bundler, or just a dynamic gemspec.
Also, you really do need to fix your permissions problem, you shouldn’t need sudo to install gems into your own home directory.
You can't use sudo to install a gem when using rbenv (or RVM), except for the "multi-user" or "system-wide" type installations which are specialized and very seldom what normal/regular users should be using.
sudo escalates your privileges to root, and root has no knowledge of the Rubies in a user's rbenv environment. As a result, root will use the default system Ruby, which will install the files there.
Instead, use a basic gem install, which will do the right thing.
Make sure you added all modified files into github repo before build your gem And then install the build gem.

Rubygems can't find sinatra directly after install

I can't figure out why rubygems is unable to find sinatra on the require "sinatra" line in the following code. I've tried to write the ruby to ensure that sinatra is installed..
Ruby
$:.push("/home/xxxx/ruby/gems")
require 'rubygems'
begin
gem "sinatra"
rescue LoadError
system("gem install sinatra")
Gem.clear_paths
end
require 'sinatra'
get "/" do
"Hello, world!"
end
Error - on line: require 'sinatra'
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require': no such file to load -- sinatra (LoadError)
from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `require'
I'm running the script through SSH with the bash command 'ruby app.rb', if that's relevant.
Gem env returns: (where /home/xxxx/ruby/gems is the correct location of the gems)
RubyGems Environment:
- RUBYGEMS VERSION: 1.8.25
- RUBY VERSION: 1.8.7 (2012-06-29 patchlevel 370) [x86_64-linux]
- INSTALLATION DIRECTORY: /home/xxxx/ruby/gems
- RUBY EXECUTABLE: /usr/bin/ruby
- EXECUTABLE DIRECTORY: /home/xxxx/ruby/gems/bin
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-linux
- GEM PATHS:
- /home/xxxx/ruby/gems
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :benchmark => false
- :backtrace => false
- :bulk_threshold => 1000
- "gempath" => []
- "gem" => "--remote --gen-rdoc --run-tests"
- "rdoc" => "--inline-source --line-numbers"
- "gemhome" => "/home/xxxx/ruby/gems"
- REMOTE SOURCES:
- http://rubygems.org/
I would recommend using bundler.
First, gem install bundler on both your dev machine and on the server.
Next create a file named Gemfile which contains something like this:
source "https://rubygems.org"
gem "sinatra"
# add a "gem" line for any other gems your application needs
(The command bundle init will create a skeleton Gemfile for you).
Then you do a "bundle install" to install the gems. This will create a "Gemfile.lock" file which gives the exact version of each gem. That file gets checked into your version control along with the Gemfile.
Once that code has been distributed to the server, then "bundle install" on the server to get the exact same gems installed there.
In your application, do not:
require "rubygems"
Modify $:
Install missing gems
On the server where you want to run your application, instead of just ruby app, you will run bundle exec ruby app.

Can't get awesome_print gem to work

awesome_print looks like a pretty nice gem, so I wanted to try it out.
I went to one of my projects and did:
gem install awesome_print
and it says one gem installed, documentation installed, etc.
Then, while I am in that project, I went to my Rails console to try it out, but when I did a require "awesome_print" as their help file says, I get a "cannot load such file".
Has anyone got this to work?
gem install will put the gem code on your computer, but unless the gem's source code files are on your load path, require won't be able to find them. bundle exec looks at the nearest Gemfile.lock and adds the source code for all the gems listed there to your load path. Rails initialization includes getting Bundler to do this for you.
One solution is to add awesome_print to your Gemfile. However, this will cause your application to have awesome_print as a dependency. Alternatively you can manually add the awesome_print library to your load path after starting up the Rails console and then requiring it:
$ rails c
> $LOAD_PATH << path/to/awesome_print-x.x.x/lib
> require 'awesome_print'
> ap {foo: {bar: {baz: :qux}}}
If you're using RVM, the path is likely to be something like:
~/.rvm/rubies/ruby-x.x.x-pxxx#your_gemset_name/gems/awesome_print-x.x.x/lib
Add it to your Gemfile like this:
gem 'awesome_print', :require => 'ap'
I add it to the development group, since that's the only time I need it. The gem doesn't have any other gem dependencies, so I routinely add it to my Gemfile.
Also, add these two lines to your ~/.irbrc file to set ap to be your default pager:
require "awesome_print"
AwesomePrint.irb!
Note that if you use this, however, any projects where awesome_print is not installed in its Gemfile will raise this error when you run rails c:
cannot load such file -- awesome_print
Depending on whatever else you may have in your ~/.irbrc file, this can cause other side effects, such as messing up your prompt. To avoid these, simply add the two lines to the very end of that file.
install it :
$ gem install awesome_print
include it in you GemFile, if you want :
gem 'awesome_print', :require => 'ap'
add this line to the file ~/.irbrc :
require 'awesome_print'
AwesomePrint.irb!
restart your shell!
just a note: I did this and it didnt work right away, probably need to restart the computer... or I just needed to close all shell tabs and open the terminal again!
Install the gem on your machine
gem install awesome_print
Get the path to which it has installed
gem which awesome_print
Add the following configuration to your ~/.irbrc and ~/.pryrc. This will load Awesome Print whenever you fire an IRB or a pry session.
*Remember $LOAD_PATH will hold whatever you got from typing gem which awesome_print
# ~/.irbc and ~/.pryrc
$LOAD_PATH << "~/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/awesome_print-1.8.0/lib/"
require "awesome_print"
AwesomePrint.irb!
If you are looking to install it without having it in your Gemfile, this is how to do it:
$ gem install awesome_print
I was running into an issue where it was installing successfully but it not in the right directory.
In that case just put this in your .bashrc, this will set the load path:
export PATH="/home/user/.gem/ruby/2.3.0/bin:$PATH"
PATH="`ruby -e 'puts Gem.user_dir'`/bin:$PATH"
replace 2.3.0 with the version of ruby you are working with.
replace user with your username or if you are using vagrant then replace with vagrant
reload your .bashrc or exit the Terminal to reload changes, then install the gem again.
In my case, I struggled with PATHs and such, while missing something obvious!
# which ruby
/usr/bin/ruby
# ruby -v
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin17]
# locate bin/ruby
/usr/bin/ruby
/usr/local/Cellar/ruby/2.7.2/bin/ruby
/usr/local/opt/ruby/bin/ruby
# /usr/local/opt/ruby/bin/ruby -v
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin17]
#
Aha! Version crud. I was running an old ruby. Thanks, Apple!
# sudo mv /usr/bin/ruby /usr/bin/ruby_2.3.7
# sudo ln /usr/local/opt/ruby/bin/ruby /usr/bin/ruby
Solved the problem!
There is probably something I could have told brew to do to fix things, but I was impatient. :-)

Gem found in irb, not in Ruby

I have some gems installed, and I'm trying to use them in a Ruby app:
require 'rubygems'
require 'mygem'
When I run the app, though, I get this error: <internal:lib/rubygems/custom_require>:29:inrequire': no such file to load -- mygem (LoadError)`
But if I try requiring the gem inside irb (making sure to `require 'rubygems' first), it works fine. What am I supposed to do? I tried googling for this problem, but didn't understand.
Running a which on ruby, gem, and irb shows that they're all in /opt/local/bin/, i.e.,
> which ruby
/opt/local/bin/ruby
> which gem
/opt/local/bin/gem
> which irb
/opt/local/bin/irb
Update to answer the questions posed (yep, irb and ruby are pointing to different folders):
$LOAD_PATH and $: in irb both contain seem to be pointing to ruby 1.8 folders:
/opt/local/lib/ruby/site_ruby/1.8
/opt/local/lib/ruby/site_ruby/1.8/i686-darwin10
/opt/local/lib/ruby/site_ruby
/opt/local/lib/ruby/vendor_ruby/1.8
/opt/local/lib/ruby/vendor_ruby/1.8/i686-darwin10
/opt/local/lib/ruby/vendor_ruby
/opt/local/lib/ruby/1.8
/opt/local/lib/ruby/1.8/i686-darwin10
.
$: in ruby points to ruby 1.9.1 folders:
/usr/local/lib/ruby/site_ruby/1.9.1
/usr/local/lib/ruby/site_ruby/1.9.1/i386-darwin9.8.0
/usr/local/lib/ruby/site_ruby
/usr/local/lib/ruby/vendor_ruby/1.9.1
/usr/local/lib/ruby/vendor_ruby/1.9.1/i386-darwin9.8.0
/usr/local/lib/ruby/vendor_ruby
/usr/local/lib/ruby/1.9.1
/usr/local/lib/ruby/1.9.1/i386-darwin9.8.0
gem env shows
RubyGems Environment:
- RUBYGEMS VERSION: 1.4.1
- RUBY VERSION: 1.8.7 (2010-12-23 patchlevel 330) [i686-darwin10]
- INSTALLATION DIRECTORY: /opt/local/lib/ruby/gems/1.8
- RUBY EXECUTABLE: /opt/local/bin/ruby
- EXECUTABLE DIRECTORY: /opt/local/bin
- RUBYGEMS PLATFORMS:
- ruby
- x86-darwin-10
- GEM PATHS:
- /opt/local/lib/ruby/gems/1.8
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :benchmark => false
- :backtrace => false
- :bulk_threshold => 1000
- "gempath" => ["/opt/local/lib/ruby/gems/1.8"]
- :sources => ["http://rubygems.org/", "http://gems.github.com", "http://gems.github.com"]
- REMOTE SOURCES:
- http://rubygems.org/
- http://gems.github.com
- http://gems.github.com
Gem.path in irb points to
/Users/grautur/.gem/ruby/1.8
/usr/local/lib/ruby/gems/1.8
Gem.path in ruby points to
/Users/grautur/.gem/ruby/1.9.1
/usr/local/lib/ruby/gems/1.9.1
I'm not sure what's going on. However, the following may help.
In irb, do
require 'rubygems'
require 'mygem'
puts $:
and then, in ruby, do
require 'rubygems'
puts $:
and show us what you get if you haven't worked it out.
Edit: also print out the results of doing gem env on the command line.
Edit 2: See what happens if you type in puts Gem.path after you've required rubygems in both irb and ruby. See thanks to Matt for describing Rubygems
You may try to add gem 'mygem' before the require, but that should not be necessary.
You will have to add gem install mygem in your Gamefile and then run bundle install command. Your application will work correctly after doing this.
I had a similar problem. The solution I found eventually was to setup rvm (ruby version manager) on my system and use it to setup a new ruby environment. it also makes it easy to switch between ruby versions of sets of gems.

Ruby 1.9.1 Load Path Craziness

Ok, I've just spent the 4 hours trying to figure this one out without success. I've tried all the usual suspects and googled every combination of ruby 1.9.1, load path, gems, mac os x,freebsd,prawn and other stuff. The bottom line is this:
When I compile ruby1.9.1-p129 from sources on mac os x 10.5, the default load path ($:) I get is:
ruby -e "puts $:"
/usr/local/lib/ruby/gems
/usr/local/lib/ruby/site_ruby/1.9.1
/usr/local/lib/ruby/site_ruby/1.9.1/i386-darwin9.7.0
/usr/local/lib/ruby/site_ruby
/usr/local/lib/ruby/vendor_ruby/1.9.1
/usr/local/lib/ruby/vendor_ruby/1.9.1/i386-darwin9.7.0
/usr/local/lib/ruby/vendor_ruby
/usr/local/lib/ruby/1.9.1
/usr/local/lib/ruby/1.9.1/i386-darwin9.7.0
.
when I install the prawn gem, for example, I get:
gem which prawn
(checking gem prawn-0.5.0.1 for prawn)
/prawn.rb
and when I try to require it I get:
ruby -e "require 'prawn'"
-e:1:in `require': no such file to load -- prawn (LoadError)
from -e:1:in `'
The only way I've been able to resolve this is by doing something stupid like this:
$: << "/usr/local/lib/ruby/gems/1.9.1/gems/prawn-0.5.0.1/lib"
which, of course, is utterly ridiculous. So the question is how do I get ruby 1.9.1 to recognize and follow the correct gems path? I've never had this issue with 1.8.7 so I'm assuming it 1.9.1 specific. I feel I'm missing something completely obvious here and any help would be much appreciated!
setting GEM_PATH=/usr/local/lib/ruby/gems/1.9.1
solved the problem. I knew it was something simple. Just aggravates me that it took ALL DAY to figure out!! This is due to never having this issue with 1.8.7 and of course NOT RTFM!!
same problem on kubuntu karmic.
installation:
$ sudo apt-get install build-essential ruby1.9.1-full libsqlite3 libsqlite3-dev rubygems1.9
$ sudo gem install sqlite3-ruby rails thin --no-rdoc --no-ri
result:
$ ruby -e "require 'rubygems'; require 'sqlite3'"
-e:1:in `require': no such file to load -- sqlite3 (LoadError)
from -e:1:in `<main>'
solution:
$ export GEM_PATH=/usr/lib/ruby1.9.1/gems/1.9.1/
Next time you have such an issue, don't forget to run gem env from the command line. This is what happens on Windows, but the principle is much the same:
C:\Documents and Settings\a.grimm>gem env
RubyGems Environment:
- RUBYGEMS VERSION: 1.3.5
- RUBY VERSION: 1.9.1 (2010-01-10 patchlevel 378) [i386-mingw32]
- INSTALLATION DIRECTORY: C:/Ruby19/lib/ruby/gems/1.9.1
- RUBY EXECUTABLE: C:/Ruby19/bin/ruby.exe
- EXECUTABLE DIRECTORY: C:/Ruby19/bin
- RUBYGEMS PLATFORMS:
- ruby
- x86-mingw32
- GEM PATHS:
- C:/Ruby19/lib/ruby/gems/1.9.1
- C:/Documents and Settings/a.grimm/.gem/ruby/1.9.1
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :benchmark => false
- :backtrace => false
- :bulk_threshold => 1000
- REMOTE SOURCES:
- http://gems.rubyforge.org/
require 'rubygems'
require 'prawn'
Unless things have changed in 1.9 that you no longer need to require rubygems first.
I'm looking for a different answer to the same problem. In some situations (ie. system start up tasks) setting environment variables before ruby runs is impossible.
Is there some way in running ruby (v >= 1.9.1) code to require gems? Without setting GEM_PATH?

Resources