Bundler gem installed from github get installed in a different location - ruby

I am trying to install a gem from github like this:
gem 'omniauth', :git => "git://github.com/intridea/omniauth.git", :require => "omniauth"
The problem is that the gem is not actually being loaded. The ruby objects are not there.
So, bundle show omniauth shows me: Users/felipe/.rvm/gems/ruby-1.9.2-p136/bundler/gems/omniauth-5972c94792cf
The problem is that the gem is being installed to a different location from the regular ones. I expected it to be `/Users/felipe/.rvm/gems/ruby-1.9.2-p136/gems/``
Any idea on how to fix this?

I think you're missing these two lines:
require "rubygems"
require "bundler/setup"
as you can see in Bundler's source code, "bundler/setup" is going to put gems managed by Bundler in the Ruby's load path:
https://github.com/carlhuda/bundler/blob/1-0-stable/lib/bundler/setup.rb#L22
Hope this helps :)

try changing the bundler line to.
gem 'omniauth', :git => "git://github.com/intridea/omniauth.git", :require => 'oa-oauth'
The problem is that your :require property was pointing to the wrong file to load. It is not always the same name as the library, by the way, when both lib name and require are the same you don't need to specify it, only when they differs.

Related

Optional runtime dependency for Ruby gem with executables

I'm writing a gem aipp which exposes a few executables, nothing fancy here:
#!/usr/bin/env ruby
require 'aipp'
AIPP::NOTAM::Executable.new(File.basename($0)).run
Parts of the gem optionally use database adapters (pg or ruby-mysql gem). But since these can be a pain in the butt when the gem is used on the cloud, I'd like to really make them optional and not require them as runtime dependency in the .gemspec.
So I require them conditionally at runtime:
require 'pg' if ENV['AIPP_POSTGRESQL_URL']
require 'mysql' if ENV['AIPP_MYSQL_URL']
Unfortunately, that doesn't work as expected. When either of the environment variables is set and the executable is used, the require fails – probably because there's no dependency declared.
I've tried an inline Gemfile on the executable like the following. Works in development (repo checkout), but not when the gem is intalled via Rubygems:
#!/usr/bin/env ruby
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'aipp'
gem 'pg', '~> 1' if ENV['AIPP_POSTGRESQL_URL']
gem 'ruby-mysql', '~> 3' if ENV['AIPP_MYSQL_URL']
end
AIPP::NOTAM::Executable.new(File.basename($0)).run
What's the correct approach to require gems which are not listed as runtime dependency but installed additionally (via gem install or Gemfile)?
Maybe somebody knows of an existing gem which has already solved this problem somehow.
Thanks for your help!
I would use bundler groups for that.
gemfile do
source 'https://rubygems.org'
gem 'aipp'
group :database do
gem 'pg', '~> 1'
gem 'ruby-mysql'
end
end
There is more info about how to use them in the link.

Bundler's :require option in a gemfile?

How would one go about using Bundler's :require=> in a gemspec? For instance, I would like to only use sinatra/base as a runtime dependency. This works in a gemfile:
gem 'sinatra', :require => 'sinatra/base'
but does not work in the gemspec (even when bundler is required in the gemspec):
s.add_runtime_dependency 'sintatra', :require => 'sinatra/base'
The error is "Illformed requirement [{:require=>"sinatra/base"}]"
Anybody else find themselves in a similar situation?
In the gemspec file you can specify the gem's dependencies only. This file doesn't do require for you. You should require dependencies in the ruby code.
On the other hand you can create a Gemfile to help you in the development environment. But the Gemfile is not loaded when you are using the gem on other projects.

how do I require 'rake' to be able to use FileList in .gemspec?

I am using :path => '/path/to/gem' functionality of bundler to build and use a modified upstream gem, which uses Rake::FileList in its .gemspec.
At this stage, the bundle I'm installing is not yet activated, or maybe the order things are installed forbids bundler from using rake.
I am using ruby 1.8.7.
My Gemfile:
source 'http://rubygems.org'
gem "rake"
gem "foreign_gem", :path => '/home/user/src/foreign_gem'
The error I get:
$ bundle install
Unfortunately, a fatal error has occurred. Please see the Bundler
troubleshooting documentation at http://bit.ly/bundler-issues. Thanks!
/home/ilya/src/foreign_gem/foreign_gem.gemspec:11: uninitialized constant FileList (NameError)
from /home/user/.rbenv/versions/1.8.7-p358/lib/ruby/site_ruby/1.8/rubygems/specification.rb:426:in 'initialize'
from /home/user/src/foreign_gem/foreign_gem.gemspec:1:in 'new'
from /home/user/src/foreign_gem/foreign_gem.gemspec:1
You should be able to add require 'rake' at the top of your foreign_gem.gemspec file in order to use FileList.
I don't know if this is a best practice, but it should work.

Add the gem I'm developing to be loaded automatically by rubygems without build/install?

I'm developing a gem with Jeweler in a custom directory.
I want to be able to require the gem within any app (and also the executables files from $PATH), and without needing to build and install the gem each time I modify it.
I thought about 2 ways:
I make a symlink to $GEM_HOME/gems and $GEM_HOME/bin
I add the bin directory to $PATH and the lib directory to rubygems to be loaded.
But I bet there is a proper way to do this.
You can specify a local path in the gem command:
gem 'your-gem', '1.2.3', :path => 'path/to/your-gem'
Update: As #Nick points out in the comments,
This is specific to using bundler. In general, it's just require '/path/to/your-gem.
I'd like to add, however, that if you're using a custom-developed gem, bundle will probably make your life easier if you're not already using it. This is because with bundler, when you're done developing the gem (or at a stable/release point) you can load a gem directly from a github repository like this:
gem 'your-gem', :git => 'git#github.com:you/your-gem.git'
No need to mess around with your Gemfile
require 'bundler/setup' will put the right gem into your $LOAD_PATH and allow you to require it on the next line.
#!/usr/bin/env ruby
require 'bundler/setup'
require '<gem-name>'

Gem and bundler: Adding a development dependency with a relative path

I'm helping on the development of a series of interrelated gems. As such, I don't want them to have a hard dependency on each other, but I do want them to run tests in development that use each other. Simple right? Just use add_development_dependency in the gemspec, right? Well, there is one little wrinkle - the git repository contains all the gems, and so I want the Gemfile to point to the local copy of the gem. This works with a hard dependency. In the gemspec, I have this line for my hard dependency:
s.add_dependency "mygem-core"
And then in the Gemfile, I have this line:
gem "mygem-core", :path => "../mygem-core"
This works PERFECT. The dependency exists for when I push this package out, and when I'm testing, it will use the local copy of mygem-core. The problem is that when I put THIS in the gemspec:
s.add_development_dependency "mygem-runtime"
And then this in the Gemfile:
gem "mygem-runtime", :path => "../mygem-runtime"
Then I get an error when I run bundle:
You cannot specify the same gem twice coming from different sources. You specified that mygem-packager (>= 0) should come from source at ../mygem-packager and
Yes, that's not a typo at the end. There is literally a blank, empty space at the end for the second 'location'. Is there any smart ways to work around this? I want to add this as a development dependency, and use the local source. What am I missing?
It's probably better that you leave that gem out of the .gemspec manifest and put it in the Gemfile under the :development group.
# Gemfile
source :rubygems
gemspec
gem "mygem-runtime", :path => '../mygem-runtime', :group => :development
If your using Gemfile to specificy a local path to a gem you will need to remove it from gemspec. Bundler will parse gemspec and add the dependencies those bundler is installing, so its like having the gem specified twice.

Resources