Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use gems not in a Gemfile when working with bundler?

Tags:

When using bundler with a project in general and Rails specifically, you have access only to gems defined in your Gemfile. While this makes sense, it can be limiting. Mostly I find it limiting when I want to use a certain RSpec formatter that the rest of the team doesn't use. Unless it's in the Gemfile, it isn't accessible.

Any way around it or I have to add it to Gemfile?

Update: my problem wasn't Bundler but Spork. When running RSpec without Spork I had no problem of using whatever formatter I wanted.

Update #2: it looks like that using Bundler is still the cause of the problem. The difference between using Spork and not using Spork, is that when running RSpec without Spork, it loads the formatter before loading your project and getting into the Bundler "sandbox".

With Bundler:

$ bundle exec irb >> require 'fivemat' LoadError: cannot load such file -- fivemat  from (irb):1:in `require' from (irb):1 from /Users/arikfr/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>' 

Without Bundler:

$ irb >> require 'fivemat' => true 
like image 819
arikfr Avatar asked Sep 02 '12 15:09

arikfr


People also ask

How do I remove gem from Gemfile lock?

You can run just bundle or bundle install to install gems based on your Gemfile. That will remove the instance of mygem from your Gemfile. lock file.

Where does bundler look for gems?

First, it says that bundler should look for gems declared in the Gemfile at https://rubygems.org by default. If some of your gems need to be fetched from a private gem server, this default source can be overridden for those gems. Next, you declare a few dependencies: on version 4.1.

How do I set gem version in Gemfile?

There are several ways to specify gem versions: Use a specific version: gem "name-of-gem", "1.0" . You can find specific versions on Rubygems.org (provided that's the source you”re using) by searching for your gem and looking at the “Versions” listed. Use a version operator: gem "name-of-gem", ">1.0" .


2 Answers

In ChiliProject we allow users to create a Gemfile.local which is included into the main Gemfile on load. This allows users to specify additional gems without having to change our Gemfile to ease updates.

For that, we have included the following code at the bottom of our Gemfile.

gemfile_local = File.expand_path('Gemfile.local', __dir__) if File.readable?(gemfile_local)   puts "Loading #{gemfile_local}..." if $DEBUG   instance_eval(File.read(gemfile_local)) end 

The Gemfile.local itself is excluded from the repository via .gitignore.

like image 135
Holger Just Avatar answered Oct 19 '22 03:10

Holger Just


I assume that none of these answers have been chosen as correct because they don't do a great job of solving the problem: having additional gems that you can use that by default don't require any changes to files already in the repository to achieve. That is, you don't have to modify any files, and you don't have to live with remembering not to check in your local changes. Here's how I do it.

The idea is basically inverting the dependencies of Holger's answer, such that there's no need to modify the shared Gemfile. Bundler allows one to specify which file is to be used as the gemfile, but strangely the documented methods do not apparently work with its configuration file and will not be fixed. There is a somewhat obscured feature of Bundler that any of the configuration options can be set in an environment variable or passed on the command line. Running all of your commands as bundle [command] --gemfile [yourgemfile] or BUNDLE_GEMFILE="[yourgemfile]" bundle [command] will cause Bundler to read whatever gemfile you want it to. I highly recommend using the environment variable approach, and either creating an alias or exporting the variable for your current session, particularly as I was unable to use the command line switch with the "exec" command.

Therefore, I run rspec like this: BUNDLE_GEMFILE="[mygemfile]" bundle exec rspec [filename], and I have the first part of this aliased as bem in my bashrc. Works like a charm.

Then, you should setup your source control to ignore your Gemfile, either in the project's .gitignore or, to keep the project entirely hygienic without changing even its .gitignore, to your personal global ignore file (which is by default in ~/.config/git/ignore and has the same format as a project's gitignore file).

One other thing to note is that Bundler will create a lockfile based on the Gemfile's name. This is super handy, as it keeps you from overwriting your project's Gemfile.lock if it's checked in, but you need to ignore this new lock file as well. If your gemfile is Foo.bar, look for Foo.bar.lock.

Finally, you can do something similar to Holger's suggestion in your custom Gemfile:

source "http://rubygems.org" gem "fivemat" instance_eval(File.read(File.dirname(__FILE__) + "/Gemfile")) 

and you're good to go, as long as you remember to specify your Gemfile.

like image 21
Matt Avatar answered Oct 19 '22 02:10

Matt