1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
# Since rubygems doesn't support optional dependencies, we have to manually check
unless Gem::Requirement.new(">= 6.1").satisfied_by?(Gem::Version.new(Rails.version))
warn "dotenv 3.0 only supports Rails 6.1 or later. Use dotenv ~> 2.0."
return
end
require "dotenv/replay_logger"
require "dotenv/log_subscriber"
Dotenv.instrumenter = ActiveSupport::Notifications
# Watch all loaded env files with Spring
ActiveSupport::Notifications.subscribe("load.dotenv") do |*args|
if defined?(Spring) && Spring.respond_to?(:watch)
event = ActiveSupport::Notifications::Event.new(*args)
Spring.watch event.payload[:env].filename if Rails.application
end
end
module Dotenv
# Rails integration for using Dotenv to load ENV variables from a file
class Rails < ::Rails::Railtie
delegate :files, :files=, :overwrite, :overwrite=, :autorestore, :autorestore=, :logger, to: "config.dotenv"
def initialize
super
config.dotenv = ActiveSupport::OrderedOptions.new.update(
# Rails.logger is not available yet, so we'll save log messages and replay them when it is
logger: Dotenv::ReplayLogger.new,
overwrite: false,
files: [
".env.#{env}.local",
(".env.local" unless env.test?),
".env.#{env}",
".env"
].compact,
autorestore: env.test? && !defined?(ClimateControl) && !defined?(IceAge)
)
end
# Public: Load dotenv
#
# This will get called during the `before_configuration` callback, but you
# can manually call `Dotenv::Rails.load` if you needed it sooner.
def load
Dotenv.load(*files.map { |file| root.join(file).to_s }, overwrite: overwrite)
end
def overload
deprecator.warn("Dotenv::Rails.overload is deprecated. Set `Dotenv::Rails.overwrite = true` and call Dotenv::Rails.load instead.")
Dotenv.load(*files.map { |file| root.join(file).to_s }, overwrite: true)
end
# Internal: `Rails.root` is nil in Rails 4.1 before the application is
# initialized, so this falls back to the `RAILS_ROOT` environment variable,
# or the current working directory.
def root
::Rails.root || Pathname.new(ENV["RAILS_ROOT"] || Dir.pwd)
end
# Set a new logger and replay logs
def logger=(new_logger)
logger.replay new_logger if logger.is_a?(ReplayLogger)
config.dotenv.logger = new_logger
end
# The current environment that the app is running in.
#
# When running `rake`, the Rails application is initialized in development, so we have to
# check which rake tasks are being run to determine the environment.
#
# See https://github.com/bkeepers/dotenv/issues/219
def env
@env ||= if defined?(Rake.application) && Rake.application.top_level_tasks.grep(TEST_RAKE_TASKS).any?
env = Rake.application.options.show_tasks ? "development" : "test"
ActiveSupport::EnvironmentInquirer.new(env)
else
::Rails.env
end
end
TEST_RAKE_TASKS = /^(default$|test(:|$)|parallel:spec|spec(:|$))/
def deprecator # :nodoc:
@deprecator ||= ActiveSupport::Deprecation.new
end
# Rails uses `#method_missing` to delegate all class methods to the
# instance, which means `Kernel#load` gets called here. We don't want that.
def self.load
instance.load
end
initializer "dotenv", after: :initialize_logger do |app|
if logger.is_a?(ReplayLogger)
self.logger = ActiveSupport::TaggedLogging.new(::Rails.logger).tagged("dotenv")
end
end
initializer "dotenv.deprecator" do |app|
app.deprecators[:dotenv] = deprecator if app.respond_to?(:deprecators)
end
initializer "dotenv.autorestore" do |app|
require "dotenv/autorestore" if autorestore
end
config.before_configuration { load }
end
Railtie = ActiveSupport::Deprecation::DeprecatedConstantProxy.new("Dotenv::Railtie", "Dotenv::Rails", Dotenv::Rails.deprecator)
end
|