Different gem versions in different branch - ruby-on-rails

I'm still somewhat new to Git and Gemfiles.
I want to upgrade my gems but not all are backward compatible. As such, I want to create a separate branch while I fix my code to be compatible with new gem versions.
If i use git checkout -b mynewbranch and then change Gemfile and start running bundle update, will that confine my gem changes to just that branch?
What's the best approach here?

The versions of gems installed using the bundle install command and the gem versions that will be used is determined by the files Gemfile and Gemfile.lock.
Moving to another branch and updating using bundle update does not interfere with those old files in the old branch. It will update those files on the new branch and install new gems versions to your machine. You can update as much as you want, go back to the old branch and all former versions of gems will be used as expected.
Note that you might need to run commands using bundle exec in case you have multiple versions of same gem on the machine.

Related

How does bundler handle multiple 'bundle install' commands?

Say I have two different Rails apps with different gem versions specified in their respective Gemfiles. The first app's Gemfile specifies the latest versions of each gem. The second app's Gemfile specifies older versions of each gem.
If I run bundle install from the root of the first app's directory, and then run bundle install from the root of the second app's directory. Will all the gems on my local machine be reverted to an older state?
The reason I ask is that I want to clone an older rail app's repository from GitHub, run it on my local machine, and play around with it. Thanks!

Why do I need to "bundle install" before pushing a rails app to heroku?

I suppose the bundling is going to happen on the heroku servers anyway. What is the purpose of doing it on the local machine?
bundle install
This ensures that all gems specified in Gemfile, together with their dependencies, are available for your application. Running bundle install also generates a Gemfile.lock file, which should be added to your git repository. Gemfile.lock ensures that your deployed versions of gems on Heroku match the version installed locally on your development machine.
If the platforms section of your Gemfile contains Windows entries,
such as mswin or mingw, then the Gemfile.lock file will be ignored.
Heroku also uses that file to resolve and install your application dependencies automatically. All you need to do is to push it.
Refer this link : Click Here
This will update your Gemfile.lock, that heroku uses to install all your gems on your virtual server. The Gemfile.lock contains all information about your gems and their respective versions.
It has two purposes :
It ensures you that, on your machine, you have all the dependencies for your application satisfied;
It updates the Gemfile.lock file. While the Gemfile has the list of your app's gems, the Gemfile.lock has a more.. "detailed" version of it, with the gem's own dependencies, their version constraints... It basically is a snapshot of your project dependencies. This way, your app in production will run with the exact same versions of third-party code as do your code in local.
This ensures that all gems specified in Gemfile, together with their dependencies, are available for your application. Running bundle install also generates a Gemfile.lock file, which should be added to your git repository. Gemfile.lock ensures that your deployed versions of gems on Heroku match the version installed locally on your development machine.
Source: https://devcenter.heroku.com/articles/bundler

When my coworker runs "bundle install", will he install the newest gems or the ones in Gemfile.lock?

That's because on gembundler.com, it says:
Make sure to add Gemfile.lock to your
repository. This will ensure that
other developers on your app, as well
as your deployment environment, use
exactly the same third-party code as
you just installed.
so, suppose I just say
gem 'rails'
so when my coworker does a bundle install 3 months later, when Rails 3.0.6 or later is released, will he install 3.0.6, or the one in Gemfile.lock? (which is 3.0.5 as of right now)
If everything must be according exactly to Gemfile.lock, then what is the procedure to update Gemfile.lock? Make sure all the tests pass, and then somehow tell bunlder to upgrade all the gems to the latest versions, and run the tests again and make sure they pass, and then commit that newest Gemfile.lock?
bundle install will install gems versions found in Gemfile.lock. To update to newest allowed versions you should run bundle update (it also updates Gemfile.lock). If something goes wrong after update (e.g. tests fail) you can fall back to previous version of Gemfile.lock in repository and run bundle install again to get previously working versions of gems. Also, individual gems may be updated by bundle update <gem_name>, e.g. bundle update rails (that also resolves dependencies and updates Gemfile.lock).
The gembundler.com website has a lot of answers. You should check out the rationale page.

How to install authlogic in Rails 3?

I find that the the config/environment.rb file looks different in Rails version 3.0.
Also when i add the line "config.gem "authlogic".To environment.rb file
For Rails 3, you no longer edit config/environment.rb. You edit Gemfile, adding
gem 'authlogic'
to it, and then do a
bundle install
more info: http://gembundler.com/rails3.html
There will be a Gemfile.lock, and it lists all the gems and their versions in your project. Bundler's docs:
Whenever your Gemfile.lock changes,
always check it in to version control.
It keeps a history of the exact
versions of all third-party code that
you used to successfully run your
application.
When your co-developers (or you on
another machine) check out your code,
it will come with the exact versions
of all the third-party code your
application used on the machine that
you last developed on (in the
Gemfile.lock). When they run
bundle install, bundler will find the
Gemfile.lock and skip the dependency
resolution step. Instead, it will
install all of the same gems that you
used on the original machine.
Pretty basic step by step tutorial here: http://www.logansbailey.com/2010/10/06/how-to-setup-authlogic-in-rails-3/

How do I freeze gems into a Rails 3 application?

I want to freeze a specific gem into my Rails application.
In rails 2 there was this command:
rake gems:unpack
I can't find that command in Rails 3.
So, the short answer is, you don't.
When you modify your Gemfile, and then run bundle install or bundle update, bundler handles the dependency resolution for you and determines the best (newest) versions of each gem you've required that satisfies the entire dependency chain (you won't get a new version that breaks another gem in the dependency list, etc.). You can also of course place a specific version, or a '>= 1.2.3' specification or whathaveyou in the Gemfile using the familiar syntax from the config.gem days, and bundler will make sure to satisfy that as well (or won't produce a Gemfile.lock if there is no valid resolution).
When Bundler does its business, it creates the Gemfile.lock file, which (and this is provided you use bundler alone for managing your gem on all workstations/environments/deployments) performs the same function as freezing all of the gems you've required. For free! (Check this file into version control!) If your new development intern pulls down your source on a fresh machine, it takes one bundle install and the exact same versions of the gems that you have installed are on her machine. Push to deployment, and do a bundle install --deployment there (or more likely, throw it in your Capfile), and the same gems are installed (this time into vendor/bundle, configurable). Bundler is used in Rails 3 to manage loading all of the gems, so wherever you've told bundler to install them (whatever your normal gem install location is by default, or BUNDLE_PATH (which is recorded in .bundle/config if you install with bundle install --path=foo otherwise), bundler will load the right ones, even when they differ from system gems.
You don't need to unpack the gems and check them in to your app, because it doesn't matter: you're guaranteeing the same versions are being called regardless of where they are installed, which will likely vary from machine to machine anyways (.bundle/ should not be checked in to the repo) - so why stick another 60-80 MB of files into your repo that you won't ever be changing or using? (incidentally, this is why I wouldn't recommend a bundle install --path=vendor/gems like nfm suggested - it's not necessarily wrong, there's just no benefit to it over the normal bundler workflow, and now your repo size just ballooned up).
DO NOT USE THE "RECOMMENDED" ANSWER BY NFM!
Instead, review the Bundler site, particularly the page on deployments:
http://gembundler.com/deploying.html
The short summary is to use specific versions in your Gemfile and run bundle install --deployment on each target system where you need the exact gem versions.
Using the --path option will install the gems, but it's not really what you want to do. As Matt Enright said, you just bloat your SCM with stuff that bundler can handle smartly on each target environment.
I haven't had to do this yet, but I believe it's all handled by bundler.
When you create a new rails3 app, the rails dependencies are put into your Gemfile. You can run bundle install to install them. By default, they are installed into your BUNDLE_PATH.
If you want to install them within your app, you can specify where: bundle install vendor/gems.
I had to do this for typus gem deployment on Heroku as you can't run a heroku rails generate typus on Heroku given it's a read only file system. I didn't want ALL gems put into my app, just the one that was causing me grief. Here are the steps that lead to success:
create directory in app_name/vendor/gems/gem_name (optional) ... in my case /app_name/vendor/gems/typus
add the following to gemfile (this tells bundle where to find and put the gem source):
gem 'typus', :git => 'https://github.com/fesplugas/typus.git', :path => "vendor/gems/typus"
then from within your app directory (this installs the gem into your app):
'gem unpack typus --target vendor/gems/typus'
then bundle install
then .. in my case... commit and push to repository and then deploy up to heroku... you may have to run a heroku rake db:migrate
Assuming you already have bundler gem installed:
$ bundle lock
$ git add Gemfile.lock
You can bundle install on dreamhost without any issues. If you are on shared the environment is already setup to store them locally in your home directory. If you are on a VPS or Dedicated you can run bundle install as root or just add this to your .bash_profile
export GEM_HOME=$HOME/.gems
export GEM_PATH=$GEM_HOME:/usr/lib/ruby/gems/1.8
I think what you are looking for is
bundle package
checkout the man pages here:
http://gembundler.com/man/bundle-package.1.html
I second the answer by tsega (updated by coreyward). "bundle package" is the generic answer.
The poster didn't ask WHETHER to freeze his gems. He wanted to know HOW. Answers like "Just don't do it" aren't helpful at all. Yes, it turned out his specific problem was a little different than that, but while "bundle package" might have been overkill it still solves the problem.
I have worked on a lot of systems, and on some you just don't have full access. Installing gems on some systems just isn't an option. So unless you package them, in general you're screwed. There are different workarounds for different hosts and systems, but none for some.
Pod - If you need to modify the gem, the best practice to do this would be forking the project, making the change, then using the 'git' flag in bundler:
git 'some_gem', :git => 'git://github.com/me/my_forked_some_gem.git'
This way you'll be notified when the gem is updated.
The command that you want is bundle package which just unpacks the gems and dependencies at vendor/cache folder.
But just a notice, the :git => .... kind of gems wont get packaged. You have to hack a way out for :git => ... related gems to get packed.
Cleaner instructions for the gem unpack and :path => option:
https://stackoverflow.com/a/8913286/555187
A lot of comments are somewhat saying that it's not useful to use the bundle install --path vendor/gems, but those people who are using Dreamhost, it should note that you cannot use bundle install in Dreamhost.
The solution is to get all the gems into the vendor folder and upload the whole thing to the Dreamhost directory.
There are other solutions to turn around this, but it's much more complicated to do.
Well I have to modify slightly one of the gems I need. So I need to keep it inside my Repo. So what NFM mentioned is what I probably need.

Resources