Bundle install to development - ruby

For some reason when I run bundle install it installs to production:
Your bundle is complete! It was installed into ./RAILS_ENV=production
Arrrghh, how do I switch back to development??
Notes:
I haven't modified any environment files
When I run Rails.env from the console I get "development"
Gem file:
source 'http://rubygems.org'
gem 'rails', '3.0.3'
gem 'sqlite3-ruby', '1.3.2', :require => 'sqlite3'
group :development do
gem 'rspec-rails'
gem 'nokogiri'
gem 'will_paginate'
end
group :test do
gem 'rspec'
end
Also worth noting, it creates a folder in my app called RAILS_ENV=production which I posted a question about here which now I guess is linked to this issue.
Update
When I run bundle config I get the following information, you can clearly see the Path is set to the culprit! Any ideas how I change this? I tried re-installing the bundler gem but to no avail, maybe this is a bug within Bundler?
$ bundle config
Settings are listed in order of priority. The top value will be used.
disable_shared_gems
Set for your local app (/Users/zinc/ror/site/.bundle/config): "1"
path
Set for your local app (/Users/zinc/ror/site/.bundle/config): "RAILS_ENV=production"

The explanation to that is in in the bundler manual. Read the heading Grouping Your Dependencies. Specifically
Bundler will remember that you installed the gems using --without production. For curious readers, bundler stores the flag in APP_ROOT/.bundle/config. You can see all of the settings that bundler saved there by running bundle config, which will also print out global settings (stored in ~/.bundle/config), and settings set via environment variables. For more information on configuring bundler, please see Advanced Usage: Configuring Bundler.
And the solution is to pass a different value for the property or remove the file APP_ROOT/.bundle/config.

Ok I fixed this.
I simply removed the path from my bundle config file and it seems to default back to my original path. I somehow set this accidentally I guess.
Your bundle config file is located in:
APP_ROOT/.bundle/config

Related

How to work with gemspec add_runtime_dependency and `bundle install`

I have a codebase which has a gemspec file like:
require "rubygems"
::Gem::Specification.new do |specification|
specification.add_development_dependency "yard", "~> 0.9"
specification.add_runtime_dependency "dry-validation", "~> 0.13"
end
bundle install will install both dependency types. So I want to just install the runtime dependencies for my CI scripts. I see bundle install --with <group> exists, but I don't have groups. Run interactively, the returned specification has an empty result returned from .groups. I would love to rationalize these two worlds. Must I explicitly add a group for each gem dependency? Does add_runtime_dependency and add_development_dependency even make a difference?
from bundler's documentation
Because we have the gemspec method call in our Gemfile, Bundler will automatically add this gem to a group called “development” which then we can reference any time we want to load these gems with the following line:
Bundler.require(:default, :development)
in your case, if you wish to install all rubygems that are not for development, then try
bundle install --without development
for future bundler version, you can configure it locally (or globally)
bundle config set --local without 'development'
to make it all work, verify that you have a Gemfile in your project, which will look like
# frozen_string_literal: true
source 'https://rubygems.org'
gemspec

Bundler: using shared gem when it exists, rather than downloading from gem server

Say, I have Gemfile like following.
source "GEM_REPOSITORY"
gem 'gem_A'
# gem_A has no additional dependency
gem 'gem_B'
# gem_B depends on gem_B_1 and gem_B_2
When I run bundle install, I want Bundler to do the following.
If a gem already exists in "local system-wide gems", it copies the gem from local.
If a gem doesn't exist in local, it looks for GEM_REPOSITORY.
I looked for some related articles, and found some of likely-answers like
Ruby Bundler multiple sources in Gemfile
SOURCE PRIORITY
But none of the above looks like the answer for me.
Using source repository priority does't work. Because in the example above, if dependent gem (say, gem_B_1) exits in local but the target gem (gem_B) doesn't exist in local, it'll download both of above from the remote repository.
Are there any work around for doing this?
If not, don't you guys think it's necessary considering the cost of the implementation and the effect?
This is the current behavior.
When running gem install, directly or via bundle install, gem will first build a dependency graph with all the needed gems. If the gem is found locally it will use it, otherwise it will try to download it from the specified source.
If you want, try it yourself.
bundle gem gem_a
bundle gem gem_b
cd gem_a
vim gem_a.gemspec
add
spec.add_dependency 'multi_json', '~> 1.10.1'
or any dependency you want to the gem and run bundle install.
cd ../gem_b
vim Gemfile
and add
gem 'gem_a', path: '../gem_a'
then run
bundle install --verbose
you will see that the multi_json or whatever dependency of gem_a uses the local version and does not download anything.
This is of course also true for gems from remote sources.

RubyMine 6.0.2 with "debugger" gem without modifying Gemfile.lock?

I am using RubyMine (v6.0.2), but my teammates are not, so they need the "debugger" gem in the gemfile. I can conditionally un-require the Gemfile when running RubyMine (so the Gemfile can be shared and identical), but since the 'debugger' gem is not included, the Gemfile.lock file changes depending on whether the project was last run with RubyMine or not. This creates a lot of noise in redundant Gemfile.lock changes.
I've tried using 'debugger-xml' gem; that doesn't solve the issue.
So -- how can I run RubyMine 6.0.2, with the 'debugger' gem in the Gemfile, without having Gemfile.lock change?
I've been working on this issue from the other side of the table. I use the debugger gem, but have team mates that use RubyMine.
We discussed several potential solutions but they all involved conditional checks in the Gemfile that would result in a modified Gemfile.lock.
I googled around for a better solution and found this SO post: How to use gems not in a Gemfile when working with bundler?
Combining a few of the answers in there, I came up with this solution:
Remove the debugger gem from the Gemfile.
Create a Gemfile.local with the contents below.
Add Gemfile.local to the .gitignore file if using git.
Create a function and shell alias.
Start rails with $ be rails s
How it all works!
Bundler will use the file named Gemfile by default, but this behavior can be overridden by specifying a BUNDLE_GEMFILE environment variable. Bundler will use/create the lock file with the same name as the BUNDLE_GEMFILE.
The shell function __bundle_exec_custom will check to see if there is a Gemfile.local file in the CWD. If there is, then the BUNDLE_GEMFILE variable is set and used. Otherwise, the default Gemfile is used.
This will allow a developer to use any gems that they want for local development without having to impact the application as a whole.
Gemfile.local:
source "https://rubygems.org"
gemfile = File.join(File.dirname(__FILE__), 'Gemfile')
if File.readable?(gemfile)
puts "Loading #{gemfile}..." if $DEBUG
instance_eval(File.read(gemfile))
end
gem 'debugger'
Function and shell alias:
__bundle_exec_custom () {
if [ -f Gemfile.local ]
then
BUNDLE_GEMFILE="Gemfile.local" bundle exec $#
else
bundle exec $#
fi
}
# Rails aliases
alias be='__bundle_exec_custom'
I think I found it. Apparently, RubyMine does not deal well with the debugger gem being required into the Rails app, but has no issue with the gem just being installed.
The solution then is to include the gem in the Gemfile (and Gemfile.lock) but only require it outside RubyMine.
gem 'debugger', {group: [:test, :development]}.
merge(ENV['RM_INFO'] ? {require: false} : {})
The above code is from this comment on the JetBrains bug tracker, through this comment on a similar question.
It checks for the presence of the RM_INFO environment variable, which is set by RubyMine. The important thing is that it only affects whether the gem is required and thus should not change Gemfile.lock between installs.
I may have an even better solution that seems to be working for me in my Rails 4 app...
In your Gemfile, move all your debugging-related gems to their own group, as such:
group :pry do
gem 'pry', '>= 0.10.0'
gem 'pry-debugger', '>= 0.2.3'
gem 'pry-highlight', '>= 0.0.1'
end
In config/application.rb you will a find something like the following:
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
Add the following just below that:
Bundler.require(:pry) unless ENV['RM_INFO'] || Rails.env.production?
You may wish to modify the unless condition to suit your needs, but the important part is that RubyMine will set RM_INFO, which you can use to detect and therefore exclude gems from being required.
This will eliminate the ping-pong effect of bundling in RubyMine vs. command line, so this should work well in a mixed-IDE team.
One last note, if you're deploying to Heroku, you might want to exclude the :pry group from being installed on deploy:
$ heroku config:set BUNDLE_WITHOUT="development:test:pry"

How to use gem from GitHub on Heroku?

I've forked the redis depository on github to https://github.com/lmirosevic/redis-rb
I added it to my Gemfile:
gem 'redis', :github => 'lmirosevic/redis-rb'
And I require the gem inside my Sinatra app:
require 'redis'
However it fails with the following error:
/app/vendor/ruby-2.0.0/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require': cannot load such file -- redis (LoadError)
Any suggestions on what could be wrong? It seems like it should work!
EDIT
I should note that the bundler phase is fine. The problem seems to be in the require step.
Bundler gives me this output:
Using redis (3.0.4) from git://github.com/lmirosevic/redis-rb (at master)
I should also say that my directory structure is something like this. Not sure if this makes a difference.
/
.env
Gemfile
Gemfile.lock
Procfile
/lib
my_sinatra_app.rb
/config
...
You must have
require 'bundler/setup'
in your app or else you're not really using bundler: this is what ensures that the gem versions loaded are the ones in your gemfile and sets up load paths for anything not installed globally.
Calling Bunder.setup allows you to control what groups are used, but if just using the default group is fine then you don't need to do this.
If you aren't setting up bundler then your gemfile is used to install the required versions of the gems but then bundler is no longer used - your app will used whatever gems are installed, whether the versions match or not and you won't be able to use gems that aren't installed in the default gem load paths.

Gemfile - separating Production gems from Development gems

So I know that in a Gemfile I can do something like this:
group :development, :test do
gem 'gem1'
gem 'gem2'
end
What I am looking to accomplish is something like this:
group :production do
gem 'gem1'
gem 'gem2'
end
group :development, :test do
gem 'gem1', :path => '/Documents/Code/gem1/'
gem 'gem2', :path => '/Documents/Code/gem2/'
end
So our application uses 2 gems that we also develop locally. In order to improve time while developing on our local machines, we want to be able to point our dev environments to the local copies of the gems - this way it picks up all changes without needing to restart our rails server. Otherwise we would have to rebuild the gem, re-install the gem, and restart rails with every development change in the gem.
However, doing this gives me the following error:
You cannot specify the same gem twice coming from different sources. You specified that gem1 (>= 0) should come from an unspecfied source and source at /Documents/Code/gem1
I have tried even running something like bundle install --without production and I get the same error.
Does anyone know if it IS possible to do what I would like to do?
Thanks!
i think that there is a supported way to do it and some hacks to work around it.
supported way:
use bundle config with the local option as described here: http://bundler.io/v1.3/man/bundle-config.1.html
hacky way:
use env vars and execute bundler before using in production: http://www.cowboycoded.com/2010/08/10/using-2-sources-for-a-gem-in-different-environments-with-bundler/
there is a feature-request for this problem on github with several related issues and lots of comments: https://github.com/carlhuda/bundler/issues/396
the github issue phoet linked to is resolved, and is consistent with the supported way.
I dug around through the docs, you'll need to set the config variable and updated your gemfile to reference the branch as well.
e.g.
edit your Gemfile:
gem <gem_name>, git: <git_url>, branch: <branch>
on command line:
bundle config local.<gem_name> <local_path_to_gem>
I solved this by creating a new Gemfile that's identical to the original except for the target gem's source. Then, in config/boot.rb, I used:
require 'rails'
if Rails.env.development?
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../DevGemfile', __FILE__)
else
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../ProdGemfile', __FILE__)
end

Resources