4

我正在使用一个简单的(或者我认为是这样的)Sinatra 应用程序,它在应用程序开发/部署周期的不同阶段使用了一些 gem:

  • 用于管理依赖项的 Bundler
  • 用于构建任务的耙子
  • 资产预编译的链轮
  • 用于测试的 RSpec 2
  • 用于部署的 Capistrano

Gemfile 包含rspec在一个test组中。

Rakefile 定义了一项assets:compile任务,用于将 Sass 转换为 CSS 并将 CoffeeScript 转换为 JavaScript,并连接生成的文件。

Capistrano 运行bundle install --without development test,因此只有生产(和资产编译)所需的 gem 安装在生产服务器上。它还运行最终bundle exec rake assets:compile在服务器上运行的 Cap 任务。

到目前为止一切都很好,但是我想将 RSpec Rake 任务添加到我的 Rakefile 中,这就是问题所在。当我在本地运行时它工作正常,但是当我运行时我cap deploy在服务器上得到一个错误:no such file to load -- rspec/core/rake_task.

这是有道理的:当我们安装 bundle 时,RSpec 并没有安装在服务器上,并且 spec 任务实际上永远不会在那里运行。错误只是因为试图定义任务而发生。

我可以想到很多选项来处理这个问题,但对我来说,它们似乎都不对:

  • 包裹require 'rspec/core/rake_task'在一个begin...rescue块中并忽略错误
  • rspec从组中取出或test以其他方式强制将其安装在服务器上
  • 在部署期间使用仅包含assets:compile任务的不同 rakefile
  • 定义我自己的spec任务,调用时只需要 RSpec
  • 在本地而不是在服务器上运行预编译(我最喜欢这些选项)

这里有哪些最佳实践?

4

3 回答 3

4

就个人而言,鉴于 Rake 不会经常在服务器上被调用,我会保持简单并使用rescue

begin
  require 'rspec/core/rake_take'
rescue LoadError
end

我不知道为什么我从来没有遇到过 Rails。

于 2013-05-31T09:05:02.450 回答
1

我会通过这样做来解决这个问题

require 'rspec/core/rake_task' if defined?(RSpec)

理由很简单。其他解决方案可能也足够了,但我认为它们增加的复杂性多于灵活性。如果将来出现更多这样的案例,我会考虑寻找替代解决方案。

于 2013-05-31T09:03:03.810 回答
0

我有几乎相同的问题。

不确定这是否是“最佳实践”,但我最终在 Rakefile 中这样做了:

if (Rails.env.migration? || Rails.env.production?)
  # define rake tasks that depend on gems installed only in dev/test envs
end

(我使用单独的环境进行迁移,它指向与生产相同的数据库,但具有执行架构更改所需的更高数据库权限。)

于 2014-11-20T19:20:58.280 回答