我应该如何构建一个Rakefile,其中包含一些需要在部署期间运行的任务,以及在部署期间甚至无法定义的其他任务?

时间:2013-05-29 11:44:58

标签: rspec rake capistrano bundler sprockets

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

  • 用于管理依赖项的Bundler
  • 构建任务的Rake
  • 资产预编译的链接
  • RSpec 2 for tests
  • Capistrano用于部署

Gemfile在rspec组中包含test

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

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

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

这是有道理的:当我们安装捆绑包时,服务器上没有安装RSpec,并且规范任务永远不会在那里运行。发生错误只是因为尝试定义任务。

我可以想出一些处理这个的选项,但是对我来说似乎没有一个选择:

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

这里的最佳做法是什么?

3 个答案:

答案 0 :(得分:4)

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

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

我不确定为什么使用Rails我从来没有参与其中。

答案 1 :(得分:1)

我会通过

来解决这个问题
require 'rspec/core/rake_task' if defined?(RSpec)

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

答案 2 :(得分:0)

我有几乎相同的问题。

不确定这是否是“最佳做法”,但我最终在Rakefile中执行此操作:

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

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