34

There is a common pattern:

there are many developers working on one project and the Gemfile(.lock) is shared via SCM. But what if some developers want to use different tools for testing and development? How to do it?

The problem is, that when you put conditional sections to your Gemfile, also the Gemfile.lock will be different for each developer and therefor you'll get conflict each time you commit to SCM.

Is there some simple, widely acknowledged solution?

Jakub
  • 735
  • 7
  • 19
  • 4
    I'm glad to hear it's not just me who is annoyed by bundler.. – August Lilleaas Nov 22 '10 at 10:23
  • actually, i am not really annoyed by it ;], more on the contrary, but it is quite young technology and its documentation is not very detailed (plus maybe options not so rich) – Jakub Nov 25 '10 at 15:53
  • 1
    the problem still becomes Gemfile.lock, rvm docs recommend checking it in... so maybe ignoring it locally would be a temporary fix – Scott Schulthess Apr 07 '11 at 21:09
  • You should check in your Gemfile.lock for apps but (maybe) not for Gems. Read this: http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/ – rubiii Sep 22 '11 at 16:31
  • For those wondering why you would want to do this in the first place: [*Jazz Hands*](https://github.com/nixme/jazz_hands) would be one example, I'm sure there are others. – Zaz Aug 09 '14 at 03:31

7 Answers7

19

I like to have this in my Gemfile:

local_gemfile = File.dirname(__FILE__) + "/Gemfile.local"
if File.file?(local_gemfile)
  require local_gemfile
end

I also have Gemfile.local and Gemfile.lock in gitignore. I know I'm not "supposed to", but I don't think the caveats (such as the ones you mention in your question) are worth it.

UPDATE for Bundler 1.0.10 as of March 3, 2011

local_gemfile = File.dirname(__FILE__) + "/Gemfile.local.rb"
if File.file?(local_gemfile)
  self.instance_eval(Bundler.read_file(local_gemfile))
end

I had to use this with Rails 3 and Bundler 1.0.10.

jakeonrails
  • 1,885
  • 15
  • 37
August Lilleaas
  • 54,010
  • 13
  • 102
  • 111
  • /home/jake/.rvm/rubies/ruby-1.8.7-p330/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `gem_original_require': no such file to load -- /home/jake/code/fullstop/Gemfile.local (LoadError) – jakeonrails Mar 09 '11 at 20:28
  • 2
    What do you do regarding your Gemfile.lock files? I tried to deploy this at my organisation but realised it would change between developers branches. – Karl Entwistle Jan 30 '13 at 16:26
  • Am I the only one for whom this fails when pushing to Heroku? (complains about a discrepancy between Gemfile and Gemfile.lock) – user456584 Mar 17 '13 at 02:52
3

If you check in something that depends on a gem that gem should be in the gemfile. If the code in the repository does not depend on a gem, there's no need to have it in the gemfile. So, unless your developers don't check in their tests (which would be weird) you would need all the test's dependencies if you want to run the whole tests suite anyway.

If the gems aren't necessary to run the app or its tests the gems don't need to be in the gemfile. Just have each developer create a gemset (I assume you're using RVM, if you don't you should) for the app and install whatever they need there, and then just add what the app needs to run to the gemfile.

Theo
  • 131,503
  • 21
  • 160
  • 205
  • 2
    What if developers are using different database engines in development? – Lars Haugseth Nov 22 '10 at 14:50
  • 1
    Why would they want to do that? Everyone has their preferences but you have to be pragmatic. – Petrik de Heus Nov 23 '10 at 09:42
  • @user438962 there are various reasons to prefer sqlite over postgres in some cases - mainly, ease of use – Scott Schulthess Apr 07 '11 at 21:08
  • @Petrik - Because I don't tell them how to set up their environment. I can only choose what is best for me... – B Seven Nov 08 '12 at 14:46
  • 2
    Developers SHOULD NOT be using different database engines in development! ORMs are not perfect and code might get checked in that works in one database environment and not the other. The local environments should also mirror production and therefore use the same database engine as production. – grant Jun 30 '15 at 14:42
  • 2
    This is answer is nonsense anyway. There are PLENTY of gems that have absolutely nothing to do with the code of a project. IRBTOOLS would be a perfect example of this. I should be able to have this as part of MY environment, not force everyone on my team to have it via the Gemfile. Having rvm include a gem like this in a global gemset is insufficient as rails console will break without bundler explicitly knowing to require it (in other words, it HAS to be in the project gemfile). It's a huge problem with Bundler in my opinion. – patrick Jan 12 '16 at 00:15
3

You can use Bundler's without flag to exclude groups.

If you have the following Gemfile

group :jakubs_testing_tools do
  gem "rspec"
  gem "faker"
end

You can exclude them with bundle install

$ bundle install --without jakubs_testing_tools

http://gembundler.com/groups.html

Petrik de Heus
  • 970
  • 6
  • 9
  • this would sound fair but we are 5 in the team so it does not scale great - but it is of course doable ... however what about the Gemfile.lock - how is it affected? – Jakub Nov 25 '10 at 15:55
2

It won't help you right now, but there's been an open feature request for Bundler to add support for a Gemfile.local for ages. It is planned for somewhere in the 1.x series, so stay tuned.

If your main problem is developer-specific IRB gems, there are a couple of workarounds in the issue's comments.

Jacob
  • 22,785
  • 8
  • 39
  • 55
  • [Current official decision](https://github.com/bundler/bundler/issues/183#issuecomment-22037131) is that it's not supported. The workarounds you link or the main answer here are good options – New Alexandria Nov 06 '13 at 19:03
  • which sucks because of the problem where your Gemfile.lock will have all this junk in it. – patrick Jan 12 '16 at 00:15
  • ...aaaand the issue is rejected and closed that now, there are some workarounds there though... – Andre Figueiredo Apr 12 '19 at 19:13
1

I suppose the install_if method (added recently) solves the problem:

install_if -> { `whoami`.strip == 'jakub' } do
  gem "pry-rails"
end

See http://bundler.io/v1.14/man/gemfile.5.html#INSTALL_IF

Jakub
  • 735
  • 7
  • 19
0

Each developer can create their own branch - Bundler works fine with different branches having different Gemfile contents. It's a good idea for developers to prefix branch names with their initials, to avoid confusion or collisions.

Stuart Ellis
  • 1,619
  • 2
  • 13
  • 15
  • 4
    Creating branches just to circumvent an oversight in Bundler? Yuck. I know branching in Git is cheap, but it's still an added overhead. – Lars Haugseth Nov 22 '10 at 14:55
  • 1
    I would call that rather an anti-pattern of SCM usage - sorry to say that. – Jakub Nov 25 '10 at 15:57
  • It's not an oversight in Bundler. The whole idea behind Bundler is to freeze all dependencies so that everyone gets the same environment! – rubiii Sep 22 '11 at 16:29
-1

(basically the same idea as in August Lilleaas's comment: gitignore)

Put the default/minimal Gemfile in SCM and then have developers change it on their systems and never commit. Have them add it to their inactive changeset in their SVN client (if they use one), other SCMs should have something similar.

This is how we do this in my company - works really well :)

Alex Kovshovik
  • 4,085
  • 4
  • 35
  • 36
  • 1
    To whomever gave the -1, please (always) specify why. – sscirrus Mar 13 '13 at 21:42
  • 2
    This doesn't solve the problem of differential Gemfile.lock files between developers (which should be checked in, and OP says that they are doing so). Developers could commit only certain changes to Gemfile.lock, but this is unwieldy. – Andy Triggs May 31 '13 at 12:10