How should I structure a Rakefile with some tasks that must be performed during deployment and others that cannot even be defined during deployment?

I work with a simple (or so I thought) Sinatra application that uses several stones at different stages of the application development / deployment cycle:

  • Dependency management bundler
  • Rake for assembly tasks
  • Asterisks for precompiling assets
  • RSpec 2 for tests
  • Capistrano for deployment

Gemfile includes rspec in the test group.

The Rakefile defines the assets:compile task to translate Sass to CSS and CoffeeScript to JavaScript and concatenate the resulting files.

Capistrano runs bundle install --without development test so that only the gems needed for production (and compilation of assets) are installed on the production server. It also runs the Cap task, which ultimately runs bundle exec rake assets:compile on the server.

Everything is fine so far, but I would like to add the RSpec Rake task to my Rakefile and that where everything goes wrong. It works fine when I run locally, but when I run cap deploy , I get an error on the server: no such file to load -- rspec/core/rake_task .

This makes sense: RSpec is not installed on the server when we install the package, and the spec task will never work there. The error occurs only because of an attempt to determine the task.

I can come up with several options to handle this, but none of them seem to me completely correct:

  • Wrap require 'rspec/core/rake_task' in a begin...rescue block and ignore the errors
  • Take rspec from the test group or otherwise force it to install on the server
  • Use another rakefile during deployment, which includes only the assets:compile task
  • Define my own spec task, which only requires RSpec when called
  • Run the precompilation locally and not on the server (my favorite of these options)

What are the best practices here?

+4
source share
3 answers

Personally, seeing that Rake is not called on the server very often, I would save it simply and use rescue :

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

I'm not sure why with Rails I never came across this.

+4
source

I would solve this by doing

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

The rationale is simplicity. Other solutions are also likely to be sufficient, but I believe that they add more complexity than flexibility. If in the future there are more such cases, I would consider an alternative solution.

+1
source

I had an almost identical problem.

Not sure if this is “best practice”, but I ended this up on a Rakefile:

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

(I use a separate migration environment that points to the same database as the production, but has the higher database privileges needed to change the schema).

0
source

Source: https://habr.com/ru/post/1483348/


All Articles