有没有办法在 Rake 中获取有关当前 Rack 环境的信息?例如,我如何判断 Rack 是在运行development
还是在production
模式下运行?
我知道 Rake 不支持 Rack。我试图避免在生产环境和开发环境之间几乎相同的 Rake 任务中复制代码。
问题很旧,但从未获得最佳实践答案或令人满意的答案。
真正的问题是:如何确定在 Rake 任务中使用哪个环境以加载正确的配置/命中正确的 if 条件。
注意:由于 Rake 没有提供太多关于 Rack 的信息(Rake 不使用 HTTP),因此依赖 RACK_ENV 基本上是错误的,但如果 Rake 任务加载您的主 Sinatra 应用程序(需要 RACK_ENV 来让 Sinatras 开发?/测试?/生产?设置正确)。
答案:在每个 Rake 任务调用中设置环境。
命令行调用:
/usr/bin/rake namespace:task_name RACK_ENV=production
Cronjob 调用(在 crontab 中):
cd /into/your/app/root && /usr/bin/rake namespace:task_name RACK_ENV=production --silent
注意:如果您在全局系统变量中指定了 Rake bin 的路径,则无需指定它。您的路径可能与示例中使用的路径不同,请使用以下命令检查 Unix 系统: whereis rake
您可以RACK_ENV
通过以下方式检查您的任务:
puts ENV["RACK_ENV"]
作为其他环境变量,您可以使用以下方法检索它:
ENV['RACK_ENV']
考虑到它是一个 Sinatra 应用程序,并且您已将环境设置为config/environment.rb
,您可以将以下内容添加到您的Rakefile
:
task :environment do
require File.expand_path('config/environment', File.dirname(__FILE__))
end
task :your_task => :environment do
# task
end
然后,您可以使用或检索环境(取决于您在 中如何设置environment.rb
)。ENV['RACK_ENV']
Sinatra::Application.environment
考虑到没有config/environment.rb
配置文件,只有应用程序文件,例如hello_world.rb
,以下工作:
hello_world.rb:
require 'sinatra'
set :environment, :production
get '/' do
'Hello World'
end
耙文件:
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
这样做时,rake your_task
您应该获得:
> rake your_task
production
2.5 年后,我想分享我发现的最佳解决方案。
在应用程序的根文件夹中创建一个.env
文件,并添加一个指定应用程序环境的标志:
ENVIRONMENT=development
然后使用 Brandon Keepers 的dotenv
gem 从这个文件中加载所有的环境变量。.env
现在您可以使用在 Rake 任务中指定的任何环境变量。
Rake 将依赖于 中设置的显式值.env
,因此您必须.env
为您计划使用的每个环境(例如dev、test、staging、production等)创建单独的文件。
样品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
如果您想在您的 Rack 或 Sinatra 应用程序中使用环境变量(您可能会这样做),请将以下内容添加到应用程序的配置或引导程序块中:
require 'dotenv'
Dotenv.load