문제

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.

도움이 되었습니까?

해결책

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.

다른 팁

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 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:

  1. create directory in app_name/vendor/gems/gem_name (optional) ... in my case /app_name/vendor/gems/typus

  2. 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"

  3. then from within your app directory (this installs the gem into your app):

    'gem unpack typus --target vendor/gems/typus'

  4. then bundle install

  5. 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:

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top