【问题标题】:How do I freeze gems into a Rails 3 application?如何将 gem 冻结到 Rails 3 应用程序中?
【发布时间】:2010-08-05 03:23:59
【问题描述】:

我想将一个特定的 gem 冻结到我的 Rails 应用程序中。

在 rails 2 中有这个命令:

rake gems:unpack

我在 Rails 3 中找不到该命令。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 rubygems bundler


    【解决方案1】:

    所以,简短的回答是,你没有。

    当您修改 Gemfile,然后运行 ​​bundle installbundle update 时,bundler 会为您处理依赖关系解析并确定满足整个依赖关系链(您不会得到破坏依赖列表中另一个 gem 的新版本,等等)。当然,您也可以使用 config.gem 日中熟悉的语法在 Gemfile 中放置特定版本或“> = 1.2.3”规范或whathaveyou,并且捆绑器也将确保满足这一点(或赢了)如果没有有效的分辨率,则不会生成 Gemfile.lock)。

    当 Bundler 执行其业务时,它会创建 Gemfile.lock 文件,该文件(前提是您单独使用 bundler 来管理所有工作站/环境/部署上的 gem)执行与冻结您的所有 gem 相同的功能'已经要求。免费! (将此文件检查到版本控制中!)如果您的新开发实习生在新机器上下载您的源代码,则需要一个 bundle install 并且您已安装的 gem 的完全相同版本在她的机器上。推送到部署,并在那里执行bundle install --deployment(或者更有可能将其放入您的 Capfile),然后安装相同的 gem(这次进入供应商/捆绑包,可配置)。 Bundler 在 Rails 3 中用于管理加载所有 gem,所以无论你告诉 bundler 安装它们(默认情况下你的正常gem install 位置是什么,或BUNDLE_PATH(如果记录在 .bundle/config否则使用 bundle install --path=foo 安装),捆绑程序将加载正确的,即使它们与系统 gem 不同。

    您不需要解压 gem 并将它们签入到您的应用程序中,因为这无关紧要:您保证无论安装在哪里都会调用相同的版本,这可能会因机器而异无论如何都要进行机器处理(.bundle/ 不应该签入到 repo 中) - 那么为什么要将另外 60-80 MB 的文件粘贴到你永远不会更改或使用的 repo 中呢? (顺便说一句,这就是为什么我不推荐 bundle install --path=vendor/gems like nfm suggested 的原因 - 这不一定是错误的,与正常的打包程序工作流程相比,它没有任何好处,现在你的 repo 大小刚刚膨胀)。

    【讨论】:

    • 为什么不把这一点说得更清楚些?我继承了一个在 Heroku 上运行的现有 Rails 2.x 应用程序,但我很难弄清楚为什么要将 gem 安装在 .\vendor\plugins 下而不是将它们添加到打包程序 Gemfile 中。
    • 我对此的最佳猜测是,因为在 Bundler 之前,最佳实践是“供应商一切”,这样您就可以在所有工作区/部署目标中拥有一致的安装集(追溯到 @ 987654322@,据我所知),并且当您看到捆绑的 gem 卡在 vendor 中时,它只是使用旧模式并没有充分利用 Bundler。
    • ——你几乎肯定是正确的。有助于理解可用的许多不同选项的是,虽然(Rails)插件可以打包为(Ruby)gem,但gem 并不总是插件。但我终于意识到.\vendor\plugins 下安装了“gems”的原因仅仅是(a)它们插件,并且(b)之前的开发人员选择采用(合理的)约定该文件夹中的供应商(插件)gem(而不是说.\vendor\gems)。
    • 这里的一个大问题是应用程序使用的上下文很重要。进行部署的环境可能会受到限制——可能不支持捆绑安装。在 Site5 共享虚拟主机上,由于 RubyGems 的内存问题,您无法安装 gems...在这种情况下,存储到 SVN/Git 不是一个糟糕的方法。
    • 从 git repo 引用 if 时,我无法弄清楚为什么我没有使用 gem 的边缘版本,但 bundle update 修复了所有问题。谢谢!
    【解决方案2】:

    不要使用 NFM 的“推荐”答案!

    相反,请查看 Bundler 站点,尤其是有关部署的页面: http://gembundler.com/deploying.html

    简短的总结是在您的 Gemfile 中使用特定版本,并在您需要确切 gem 版本的每个目标系统上运行 bundle install --deployment

    使用--path 选项将安装gem,但这并不是您真正想要做的。正如 Matt Enright 所说,您只需使用捆绑程序可以在每个目标环境中智能处理的东西来膨胀您的 SCM。

    【讨论】:

    • 我以前使用 rails:freeze 的一个原因是我可以破解 rails 代码,通常是为了帮助我调试它。 bundle 包只给了我 .gem 文件。
    • 如果你在目标系统上没有root,并且无法安装gems怎么办?例如,如果您在托管公司拥有生产服务器?
    【解决方案3】:

    我还没有这样做,但我相信这一切都由bundler 处理。

    当您创建一个新的 rails3 应用程序时,rails 依赖项将放入您的Gemfile。您可以运行bundle install 来安装它们。默认情况下,它们会安装到您的BUNDLE_PATH

    如果您想在您的应用中安装它们,您可以指定位置:bundle install vendor/gems

    【讨论】:

    • 你也可以运行“bundle pack”,它们最终会出现在“vendor/cache/”目录中。
    • 为了澄清(作为对此答案的评论,基于其他答案 [和这些答案的 cmets]),如果您使用 Bundler 进行管理,冻结 gem 不再像以前那样有用您的 gem 依赖项,因为 Bundler 提供了以前通过冻结 gem 提供的大部分功能。
    • 正如其他答案和 cmets 所说,只有当您需要将宝石冻结到您的应用中时,这才是正确的方法,通常是因为您已经修改了它们。
    【解决方案4】:

    我必须为 Heroku 上的 typus gem 部署执行此操作,因为您无法在 Heroku 上运行 heroku rails generate typus,因为它是只读文件系统。我不希望所有的宝石都放入我的应用程序中,只是让我感到悲伤的那个。以下是通向成功的步骤:

    1. 在 app_name/vendor/gems/gem_name 中创建目录(可选)...在我的例子中是 /app_name/vendor/gems/typus

    2. 将以下内容添加到 gemfile(这会告诉 bundle 在哪里可以找到和放置 gem 源):

      gem 'typus', :git => 'https://github.com/fesplugas/typus.git', :path => "vendor/gems/typus"

    3. 然后从您的应用目录中(这会将 gem 安装到您的应用中):

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

    4. 然后bundle install

    5. 然后 .. 在我的情况下... 提交并推送到存储库,然后部署到 heroku... 您可能需要运行 heroku rake db:migrate

    【讨论】:

    • gem unpack 不使用捆绑器,因此它不知道 Gemfile 中指定的 git repo。相反,它将转到 ruby​​gems 并尝试从那里获取最新版本。
    【解决方案5】:

    假设您已经安装了bundler gem

    • $ bundle lock
    • $ git add Gemfile.lock

    【讨论】:

    • 最新的捆绑器现在在捆绑安装时默认锁定。
    【解决方案6】:

    您可以在 Dreamhost 上捆绑安装而不会出现任何问题。如果您处于共享状态,则环境已经设置为将它们本地存储在您的主目录中。如果您在 VPS 或专用服务器上,您可以以 root 身份运行 bundle install 或将其添加到您的 .bash_profile

    export GEM_HOME=$HOME/.gems
    export GEM_PATH=$GEM_HOME:/usr/lib/ruby/gems/1.8
    

    【讨论】:

      【解决方案7】:

      我认为你正在寻找的是

      bundle package
      

      在此处查看手册页: http://gembundler.com/man/bundle-package.1.html

      【讨论】:

        【解决方案8】:

        我支持 tsega 的答案(由 coreyward 更新)。 “捆绑包”是通用答案。

        海报并没有问是否要冻结他的宝石。他想知道HOW。诸如“不要这样做”之类的答案根本没有帮助。是的,事实证明他的具体问题与此略有不同,但虽然“捆绑包”可能有点矫枉过正,但它仍然可以解决问题。

        我在很多系统上工作过,而在一些系统上你只是没有完全访问权限。在某些系统上安装 gems 不是一种选择。因此,除非您将它们打包,否则通常您会被搞砸。不同的主机和系统有不同的解决方法,但有些没有。

        【讨论】:

          【解决方案9】:

          Pod - 如果您需要修改 gem,最好的做法是分叉项目,进行更改,然后在 bundler 中使用 'git' 标志:

          git 'some_gem', :git => 'git://github.com/me/my_forked_some_gem.git'

          这样你会在 gem 更新时收到通知。

          【讨论】:

            【解决方案10】:

            您想要的命令是bundle package,它只是解压缩vendor/cache 文件夹中的gem 和依赖项。

            但请注意,:git => .... 类型的宝石不会被打包。您必须为:git => ... 相关的宝石找到一条出路才能打包。

            【讨论】:

              【解决方案11】:

              gem unpack:path => 选项的更简洁说明:

              【讨论】:

                【解决方案12】:

                很多cmets都有点说用bundle install --path vendor/gems没用,但是用Dreamhost的人要注意,在Dreamhost中不能使用bundle install。

                解决方案是将所有 gem 放入 vendor 文件夹并将整个内容上传到 Dreamhost 目录。

                还有其他解决方案可以解决这个问题,但操作起来要复杂得多。

                【讨论】:

                  【解决方案13】:

                  好吧,我必须稍微修改一下我需要的宝石之一。所以我需要把它保存在我的回购中。所以 NFM 提到的就是我可能需要的。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2019-09-14
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-07-15
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多