Is there a way to get information about the current Rack environment in Rake? For example, how can I tell whether Rack is running in development
or production
mode?
I understand that Rake is not Rack-aware. I'm trying to avoid replicating code in nearly-identical Rake tasks between production and dev environments.
Including => :environment will tell Rake to load full the application environment, giving the relevant task access to things like classes, helpers, etc. Without the :environment , you won't have access to any of those extras.
Rake is a Domain Specific Language (DSL), which means you can only use it for things related to Ruby. Rake allows one to write tasks in the Ruby language and execute them on the command line.
Question is old but never fetched the best practice answer or a satisfying answer at all.
The real question is: How to go sure which environment is used in a Rake task in order to load the correct configuration / hitting into correct if-conditions.
Note: As Rake doesn't give much about Rack (Rake is not using HTTP) to rely on the RACK_ENV is basically wrong but common and handy if a Rake task loads your main Sinatra application (the RACK_ENV is required to let Sinatras development? / test? / production? being set correctly).
The answer: Set the environment with each Rake task call.
Command line call:
/usr/bin/rake namespace:task_name RACK_ENV=production
Cronjob call (in crontab):
cd /into/your/app/root && /usr/bin/rake namespace:task_name RACK_ENV=production --silent
Note: To specify the path of the Rake bin is not necessary if you have it in your global system variables. Your path might differs from mine used in the examples, check on Unix systems with: whereis rake
You can check the RACK_ENV
in your tasks via:
puts ENV["RACK_ENV"]
As other environment variable, you can retrieve it using:
ENV['RACK_ENV']
Considering it's a Sinatra application, and that you've set the environment into config/environment.rb
, you can add the following to your Rakefile
:
task :environment do
require File.expand_path('config/environment', File.dirname(__FILE__))
end
task :your_task => :environment do
# task
end
Then, you can retrieve the environment (depending how you set it up in your environment.rb
) with ENV['RACK_ENV']
or Sinatra::Application.environment
.
Considering there isn't a config/environment.rb
config file, only the application file, for instance hello_world.rb
, the following works:
hello_world.rb:
require 'sinatra'
set :environment, :production
get '/' do
'Hello World'
end
Rakefile:
task :environment do
require File.expand_path('hello_world', File.dirname(__FILE__)) # your Sinatra app
end
task :your_task => :environment do
puts Sinatra::Application.environment
end
When doing rake your_task
you should obtain:
> rake your_task
production
After 2.5 years, I want to share what I've found to be the best solution.
Create a .env
file in the root folder of the application, and add a flag specifying the application environment:
ENVIRONMENT=development
Then use Brandon Keepers' dotenv
gem to load all environment variables from this file. Now you can use any environment variables specified in .env
within Rake tasks.
Rake will rely on the explicit value set in .env
, so you must create separate .env
files for each environment you plan on using (e.g. dev, test, staging, production, etc).
Sample Rakefile
:
require 'dotenv/tasks'
task :default => :help
desc 'Show this help menu'
task :help do
puts "Available rake tasks:"
system('rake --tasks')
end
# Will run in any environment
desc 'Demo task'
task :demo_task => :dotenv do
puts "Running demo task in '#{ENV['ENVIRONMENT']}' mode"
end
# Will only run if ENVIRONMENT value in .env file is set to 'production'
desc 'Production-only task'
task :production_task => :dotenv do
if ENV['ENVIRONMENT'] == 'production'
puts "Running 'Production-only' task"
else
puts "Won't run, because the environment is not set to PRODUCTION!"
end
end
# Will only run if ENVIRONMENT value in .env file is set to 'development'
desc 'Development-only task'
task :dev_task => :dotenv do
if ENV['ENVIRONMENT'] == 'development'
puts "Running 'Development-only' task"
else
puts "Won't run, because the environment is not set to DEVELOPMENT!"
end
end
If you want to use the environment variables within your Rack or Sinatra app (which you probably do), add the following to the application's config or bootstrap block:
require 'dotenv'
Dotenv.load
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With