How to get the current Rack environment in Rake?
Solution 1
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"]
Solution 2
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
Solution 3
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
Arman H
"In theory, theory and practice are the same. In practice, they’re not." - Yoggi Berra “Any code of your own that you haven't looked at for six or more months might as well have been written by someone else. ” - Eagleson's law “The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time. ” - Tom Cargill “To iterate is human, to recurse divine.” - L. Peter Deutsch "To err is human... to really foul up requires the root password." “Software sucks because users demand it to. ” - Nathan Myhrvold “If debugging is the process of removing software bugs, then programming must be the process of putting them in. ” - Edsger Dijkstra "Measuring programming progress by lines of code is like measuring aircraft building progress by weight." - Bill Gates “It's hard enough to find an error in your code when you're looking for it; it's even harder when you've assumed your code is error-free. ” - Steve McConnell “Walking on water and developing software from a specification are easy if both are frozen. ” - Edward V Berard “Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. ” - Brian Kernighan “Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter.” - Eric S. Raymond “Most of you are familiar with the virtues of a programmer. There are three, of course: laziness, impatience, and hubris.” - Larry Wall "Perl – The only language that looks the same before and after RSA encryption." - Keith Bostic "The last good thing written in C was Franz Schubert's Symphony No. 9." - Werner Trobin "XML is like violence - if it doesn’t solve your problems, you are not using enough of it." - Nokogiri "Brooks's Law: Adding manpower to a late software project makes it later." - Fred Brooks "Some people, when confronted with a problem, think 'I know, I'll use regular expressions." Now they have two problems.'" - Jamie Zawinski "It should be noted that no ethically-trained software engineer would ever consent to write a DestroyBaghdad procedure. Basic professional ethics would instead require him to write a DestroyCity procedure, to which Baghdad could be given as a parameter." - Nathaniel Borenstein "There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence." - Jeremy S. Anderson "... one of the main causes of the fall of the Roman Empire was that, lacking zero, they had no way to indicate successful termination of their C programs." - Robert Firth "Saying that Java is nice because it works on all OSs is like saying that anal sex is nice because it works on all genders." - Alanna
Updated on June 22, 2022Comments
-
Arman H almost 2 years
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
orproduction
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.
-
Arman H about 11 yearsDoesn't work. Here's a simple Rakefile to illustrate:
task :test_rack_env do puts ENV['RACK_ENV'] end
Prints a blank line. -
toch about 11 yearsWhere do you set the Rack environment to
production
ordevelopment
? -
Arman H about 11 yearsI'm using Sinatra, so it sets the environment.
-
toch about 11 years@ArmanH I've updated my answer. Hope it will help you this time.
-
Arman H about 11 yearsThanks for the expanded answer; however, there is no config file in a Sinatra app, and the environment is not being set through it. Instead, Sinatra uses
set :environment, :production
. -
toch about 11 years@ArmanH I've updated my answer considering you just have one Sinatra app where you have set up the environment.
-
wgp over 8 yearsI usually have an
:environment
task that all other tasks depend on. Within that I always set default values any other task would need. So I'd go further and suggest definingENV['RACK_ENV'] ||= 'development'
either at the top of the Makefile or inside of an:environment
task. -
EricC over 8 yearsThanks! Exactly what I'm looking for! Just to clarify, to use different
.env
files for different environments, do you use avdi's approach or some other mechanism for rake to pick up env vars in different.env
files? -
Arman H over 8 yearsTo test production settings locally, I have a file called
.env.production
, which I switch out with.env
while running tests (renaming the local env file to.env.local
while testing).